Android 6.0 下默认存储SD卡,使用原生FMRadio生成的文件保存到内部存储中
【预置条件】插入T卡
【操作步骤】设置>存储设备和USB>选择SD卡为默认存储>收音机录音
【实际结果】收音机的录音文件未保存到T卡
【预期结果】收音机的录音文件保存到T卡
【复现概率】10/10
此外,SoundRecorder默认存储SD卡,生成的文件却可以保存到SD卡中
1、收音机文件没有保存到指定的SD卡目录下,因此可能是文件的路径不对。
2、进入设置中,切换默认存储位置,内部存储或者SD卡,每次切换都会修改系统中某一属性值。
3、当收音机文件保存的时候,必须要读取当前系统的默认存储路径,然后生成自己的文件路径。
对比SoundRecorder,根据GIT库中,之前的同事的修改记录,找到可能的解决方案,修改如下:
1) 修改了packages/apps/FMRadio/AndroidManifest.xml文件添加
2) 修改packages/apps/FMRadio/src/com/android/fmradio/FmRecorder.java文件
添加import com.mediatek.storage.StorageManagerEx;语句
替换startRecording函数String recordingSdcard = FmUtils.getDefaultStoragePath();为String recordingSdcard = StorageManagerEx.getDefaultPath();
引入新的问题,此时,点击 Start Recording 会提示内部错误。
分析Log发现,由于权限拒绝,抛出IO异常
01-01 07:35:38.167 7467 7467 W System.err: java.io.IOException: open failed: EACCES (Permission denied)
分析由于权限问题后,结合Android M new design,开始查找文档,寻找解决Android M 下SD卡读写权限问题
Android6.0中的运行时请求权限
后来,试了好几种方法,但都没有用,以及报问题“EACCES (Permission denied)”
判断APP运行时权限如下:
- adb remount;//挂载
- adb shell;//进入shell
- ps | grep fmradio;//查找FMRadio的PID,前提是手机打开FMRadio,插入耳机
- cd proc/4830;//进入PID对应的信息文件中
- cat status;//查看进程信息
发现此时,FMRadio对于的组权限如下:
com.android.fmradio Groups: 1013 3002 3003 9997 50010
com.android.soundrecorder Groups: 1015 1023 3003 9997 50105
根据系统权限的定义,有兴趣的同学可以去看一下这个文件
system/core/include/private/android_filesystem_config.h
分析这些Gid发现:
1015 为sdcard_rw,1023 为media_rw权限
因此,得出结论如下
1、首先修改AndroidManifest.xml文件,新增权限,确保FMRadio应用级的权限;
2、原生FMRadio使用过程中,会进行运行时的权限检查,故FMRadio运行时应该拿到了WRITE_EXTERNAL_STORAGE,以及READ_EXTERNAL_STORAGE权限,
3、但是由于FMRadio本身不具备“1015,1023”组权限,这些权限无效,仍然无法对SD卡进行读写操作。
在STEP1的修改基础上,在框架层,权限对应组中给予FMRadio相应的组权限,新增修改如下:
frameworks/base/data/etc/platform.xml
<---add XXX begin -->
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
<group gid="sdcard_rw" />
<group gid="media_rw" />
permission>
<---add XXX end -->
重编framework.jar, 将修改后的jar文件push到手机,重启
此时,再检查FMRadio对于的组权限如下:
com.android.fmradio Groups: 1013 1015 1023 3002 3003 9997 50010
到此为止,
重启验证,可以保存到SD卡
1、修改了packages/apps/FMRadio/AndroidManifest.xml文件添加
2、修改packages/apps/FMRadio/src/com/android/fmradio/FmRecorder.java文件
添加import com.mediatek.storage.StorageManagerEx;语句
替换startRecording函数String recordingSdcard = FmUtils.getDefaultStoragePath();为String recordingSdcard = StorageManagerEx.getDefaultPath();
其实之前的方法是正确的,push修改后的FMRadio之后,重启一下手机即可。
当时没有生效的原因是,从L版本开始,apk直接push就不生效了,要push+重启才可以,因为PMS取消了各个路径下的observer,直接push不会生效,重启才会重新扫描。
这里向大家主要提到两个文件
1、电脑代码区文件:frameworks/base/data/etc/platform.xml
这个文件中定义了底层权限组GID和高层权限名字之间的对应关系
其实,在这个文件已经定义过了
<permission name="android.permission.WRITE_MEDIA_STORAGE" >
<group gid="media_rw" />
<group gid="sdcard_rw" />
permission>
故我们只需要在AndroidManifest.xml,添加即可grant FMRadio SD卡读写权限。
2、手机数据区文件:data/system/packages.xml
这个文件由PackageManagerService.Java生成,里面记录了系统当中安装的APK的所有属性,权限等信息。L之前,当系统中的APK安装、删除、升级时,文件就会被更新。L之后,重启才会重新扫描更新该文件。
push后,重启前
name="com.android.fmradio" codePath="/system/priv-app/FMRadio" nativeLibraryPath="/system/priv-app/FMRadio/lib" primaryCpuAbi="arm64-v8a" publicFlags="940097093" privateFlags="8" pkgFlagsEx="0" ft="151fd3402d8" it="158575d1d70" ut="151fd3402d8" version="2" userId="10010">
count="1">
"0" key=“……” />
<item name="android.permission.MODIFY_AUDIO_SETTINGS" granted="true" flags="0" />
<item name="android.permission.MODIFY_AUDIO_ROUTING" granted="true" flags="0" />
<item name="android.permission.ACCESS_MOCK_LOCATION" granted="true" flags="0" />
<item name="android.permission.ACCESS_FM_RADIO" granted="true" flags="0" />
<item name="android.permission.BLUETOOTH" granted="true" flags="0" />
<item name="android.permission.INTERNET" granted="true" flags="0" />
<item name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" granted="true" flags="0" />
<item name="android.permission.INTERACT_ACROSS_USERS" granted="true" flags="0" />
<item name="android.permission.WAKE_LOCK" granted="true" flags="0" />
"1" />
重启后
name="com.android.fmradio" codePath="/system/priv-app/FMRadio" nativeLibraryPath="/system/priv-app/FMRadio/lib" primaryCpuAbi="arm64-v8a" publicFlags="940097093" privateFlags="8" pkgFlagsEx="0" ft="151fda9d6e8" it="158575d1d70" ut="151fda9d6e8" version="2" userId="10010">
count="1">
"0" key="……" />
<item name="android.permission.MODIFY_AUDIO_SETTINGS" granted="true" flags="0" />
<item name="android.permission.MODIFY_AUDIO_ROUTING" granted="true" flags="0" />
<item name="android.permission.ACCESS_MOCK_LOCATION" granted="true" flags="0" />
<item name="android.permission.ACCESS_FM_RADIO" granted="true" flags="0" />
<item name="android.permission.BLUETOOTH" granted="true" flags="0" />
<item name="android.permission.WRITE_MEDIA_STORAGE" granted="true" flags="0" />**
<item name="android.permission.INTERNET" granted="true" flags="0" />
<item name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" granted="true" flags="0" />
<item name="android.permission.INTERACT_ACROSS_USERS" granted="true" flags="0" />
<item name="android.permission.WAKE_LOCK" granted="true" flags="0" />
"1" />
未完待续……