上次在文章《打包的Android应用如何播放本地视频及外置SD卡的视频》中整理了一下读取并播放外置 SD 卡中的视频的方法。
上篇文章侧重于解决读取并播放外置 SD 卡中的本地视频,而本文会详细讲解如何在 Unity 中自动获取 SD 卡的路径(因为不同的 SD 卡,它的路径不同,所以最好的方法是让程序自动获取 SD 路径而不是代码中写死)。
总体思路就是,在 Android 中将获取 SD 卡路径的方法打成 Jar 包,然后在 Unity 中调用。
1. 打 Jar 包
在 Android 中获取外置 SD 卡路径的代码,在之前的文章中已经说过。这里对其进行了削微的改动,然后将其打成 Jar 包。
public class GetSdcardNameUtil { private static final String TAG = GetSdcardNameUtil.class.getSimpleName(); /** * @param mContext context对象,传入activty对象即可 * @param is_removale 存储否可以移除,如果是外置sdcard,is_removale应该传入true * @return */ public static String getStoragePath(Context mContext, boolean is_removale) { StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); Class storageVolumeClazz = null; try { storageVolumeClazz = Class.forName("android.os.storage.StorageVolume"); Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList"); Method getPath = storageVolumeClazz.getMethod("getPath"); Method isRemovable = storageVolumeClazz.getMethod("isRemovable"); Object result = getVolumeList.invoke(mStorageManager); final int length = Array.getLength(result); for (int i = 0; i < length; i++) { Object storageVolumeElement = Array.get(result, i); String path = (String) getPath.invoke(storageVolumeElement); Log.d(TAG, "path = " + path); boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement); if (is_removale == removable) { return path; } } } catch (Exception e) { e.printStackTrace(); } return null; } }
Jar 包打包的具体过程就不讲了,毕竟我不是擅长这个的,打包过程中你们万一有啥问题我也回答不来,干脆不写了,你们自行找其他教程学吧。
下面这个是我已经打包好的一个 Jar 包,你们需要的话可以直接拿去用。
链接:https://pan.baidu.com/s/1ceo3up-v29EBkQ2l5x0nJw 提取码:n75g
2. 在 Unity 中调用 Jar 包中的方法
首先,将 Jar 包放入 Unity 的 Plugins 目录下。
然后,打开 Plugins / Android 文件夹下的 AndroidManifest.xml 文件,添加两行代码,申请读写存储权限。
然后创建脚本,脚本中添加一个 getSdPath() 函数。
private string getSdPath() { AndroidJavaClass jc = new AndroidJavaClass("com.vivedu.sdcardget.GetSdcardNameUtil"); AndroidJavaObject context = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity"); string path = jc.CallStatic("getStoragePath", context, true); return path; }
调用该函数后,返回的 SD 卡根目录路径,形如:
/storage/3686-3696
然后就可以使用啦。
3. 常见问题
1. 在 Unity 中直接运行时,会报错 Exception: JNI: Init'd AndroidJavaClass with null ptr! 。
这个是因为 Unity 中不是 Android 真机环境,这个错误可以不用理会,打包后在 Android 环境下运行就没问题了。
2. 还是有必要解释一下 getSdPath 函数中的代码。
AndroidJavaClass jc = new AndroidJavaClass("com.vivedu.sdcardget.GetSdcardNameUtil"); AndroidJavaObject context = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity"); string path = jc.CallStatic("getStoragePath", context, true);
第一行代码中的 “com.vivedu.sdcardget.GetSdcardNameUtil” ,是 “包名.类名”,如果 Jar 包是自己打包的话,这个参数根据自己的实际情况进行修改。
第三行代码中的 "getStoragePath" 是函数名,后面的 context 和 true 分别是函数的两个参数。
public static String getStoragePath(Context mContext, boolean is_removale)
3. Unity 打包得到 Android 应用并安装后,别忘记给应用授权相应的读写本地存储的权限哦。