【Unity3D】用 Unity3D / C# 如何获取 Android 外置 SD 卡的路径

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wenxuhonghe/article/details/95214181

上次在文章《打包的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 文件,添加两行代码,申请读写存储权限。

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然后创建脚本,脚本中添加一个 getSdPath() 函数。

    private string getSdPath()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.vivedu.sdcardget.GetSdcardNameUtil");
        AndroidJavaObject context = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
        string path = jc.CallStatic<string>("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<AndroidJavaObject>("currentActivity");
string path = jc.CallStatic<string>("getStoragePath", context, true);

 第一行代码中的 “com.vivedu.sdcardget.GetSdcardNameUtil” ,是 “包名.类名”,如果 Jar 包是自己打包的话,这个参数根据自己的实际情况进行修改。

第三行代码中的 "getStoragePath" 是函数名,后面的 context 和 true 分别是函数的两个参数。

public static String getStoragePath(Context mContext, boolean is_removale) 

3. Unity 打包得到 Android 应用并安装后,别忘记给应用授权相应的读写本地存储的权限哦。

猜你喜欢

转载自blog.csdn.net/wenxuhonghe/article/details/95214181