了解Android的存储服务调用

时间:2019-09-16 02:18:59

标签: java android service internals mount-point

在我正在开发的应用中,可以使用以下两种方法之一来获取外部存储(即USB介质)的列表:

方法1

            Object[] storageVolumes;

            Method getService = Class.forName("android.os.ServiceManager")
                    .getDeclaredMethod("getService", String.class);

            if (!getService.isAccessible()) getService.setAccessible(true);
            IBinder service = (IBinder) getService.invoke(null, "mount");

            Method asInterface = Class.forName("android.os.storage.IMountService$Stub")
                    .getDeclaredMethod("asInterface", IBinder.class);

            if (!asInterface.isAccessible()) asInterface.setAccessible(true);
            Object mountService = asInterface.invoke(null, service);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                String packageName = context.getPackageName();
                int uid = context.getPackageManager().getPackageInfo(packageName, 0).applicationInfo.uid;
                Method getVolumeList = mountService.getClass().getDeclaredMethod(
                        "getVolumeList", int.class, String.class, int.class);
                if (!getVolumeList.isAccessible()) getVolumeList.setAccessible(true);
                storageVolumes = (Object[]) getVolumeList.invoke(mountService, uid, packageName, 0);
            } else {
                Method getVolumeList = mountService.getClass().getDeclaredMethod("getVolumeList");
                if (!getVolumeList.isAccessible()) getVolumeList.setAccessible(true);
                storageVolumes = (Object[]) getVolumeList.invoke(mountService, (Object[]) null);
            }

方法2

            StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

            Method getVolumeList = storageManager.getClass().getMethod("getVolumeList", null);
            if (!getVolumeList.isAccessible()) getVolumeList.setAccessible(true);

            storageVolumes = (Object[]) getVolumeList.invoke(storageManager, (Object[]) null); // android.os.Storage.StorageVolume

这两种方法似乎都以相同的方式用已安装媒体的列表正确填充storageVolumes数组。

但是,由于我不是Android和/或Java专家,所以我不确定这些方法如何工作,并且由于它们使用内部Android API,因此找不到任何可以解释什么的有用文档。这些都可以。

因此,如果您能在这里解释这些功能的作用,我将不胜感激。

此外,您会建议我坚持哪一个?我能以某种方式将它们组合成一个奇异函数吗?

0 个答案:

没有答案