Android设置里面默认存储器选项(default write disk)的实现
原生的Android设置里面没有默认存储器的选项,可是MTK偏偏加上了这个功能,可能MTK认为这个比較实用吧,所以,他们在原生的基础上面做了改动。加上了这个功能。可是高通平台没有这个功能。相对MTK来说。高通比較严谨一点,不会随随便便加上一些功能。可是MTK平台优化了非常多东西(有有点也有缺点),开发人员这可能是非常多山寨手机选择MTK平台的原因吧。
我给“默认存储器”做了一个简单的定义:一些内置应用的数据存放位置。当然。假设其它应用知道这个接口(不是标准接口。所以仅仅有开发人员本人知道,或者MTK的人),也能够使用该功能。
之前接到一个在高通平台上的手机里面加上默认存储器的选项,即假设选择本地内存,一些内置应用的数据将存储到本地内存里面,假设选择SD卡存储。则这些应用的数据将会存储到SD卡里面。借鉴MTK平台的实现方法。整理其思路是:通过SystemProperties接口往系统内存里面写入存储路径(set),然后在一些指定应用里面存储数据的时候推断当前默认存储器,使用get方法读取这个属性。为什么使用SystemProperties,由于其设置的值全局都能够使用,即不同应用都能够通过共享内存取出其值,攻克了进程间通信的问题。
1:我们先在framework层加上一些自己定义的接口文件。我加的位置是 ....../frameworks/base/core/java/android/os/storage/。加入的文件名称StorageManagerEx.java,内容例如以下:
package android.os.storage;
import android.util.Log;
import com.android.internal.R;
import android.os.SystemProperties;
import java.io.File;
import android.os.Environment; public class StorageManagerEx {
» private static final String TAG ="StorageManagerEx";
» private static final String PROP_SD_DEFAULT_PATH = "persist.sys.sd.defaultpath";
»
» private static final String STORAGE_PATH_SD1 ="/storage/sdcard0";
» private static final String STORAGE_PATH_SD2 ="/storage/sdcard1";
» private static final String STORAGE_PATH_SD1_ICS = "/mnt/sdcard";
» private static final String STORAGE_PATH_SD2_ICS = "/mnt/sdcard2";
»
» private static final String STORAGE_PATH_SHARE_SD = "/storage/emulated/0";
»
» /**
» * Return default path for writing.
» * @return default path.
» * @hide
» * @internal
» */
public static String getDefaultPath(){
» String path = STORAGE_PATH_SD1;
» try {
» » path = SystemProperties.get(PROP_SD_DEFAULT_PATH);
» » Log.i(TAG,"default path = "+path);
» } catch (IllegalArgumentException e) {
» » Log.e(TAG,"IllegalArgumentException when get default path:"+e);
» }
» //Property will be empty when first boot should set to default
» if(path.equals("")){
» » Log.i(TAG,"getDefaultPath empty! set to default");
» » //Here may be some problems.refer to MTK:only share sd and no swap,internal path
is
» » //"/storage/emulated/0",i don't know "share" and "no swap",so i skip.
» » // if (FeatureOption.MTK_SHARED_SDCARD && !FeatureOption.MTK_2SDCARD_SW
AP) {» »
» » // setDefaultPath(STORAGE_PATH_SHARE_SD);
» » // path = STORAGE_PATH_SHARE_SD;
» » // } else {
» » // setDefaultPath(STORAGE_PATH_SD1);
» » // path = STORAGE_PATH_SD1;
» » // }
» » setDefaultPath(STORAGE_PATH_SD1);
» » path = STORAGE_PATH_SD1;
» }
»
» //Here we don't care multi user which will be used by google,ignore and go on.
»
» //MOTA upgrade from ICS to JB,update defaultPath to JB.
» if(path.equals(STORAGE_PATH_SD1_ICS)){
» » path = STORAGE_PATH_SD1;
» » setDefaultPath(path);
» }else if(path.equals(STORAGE_PATH_SD2_ICS)){
» » path = STORAGE_PATH_SD2;
» » setDefaultPath(path);
» }
»
» Log.i(TAG,"getDefaultPath path="+path);
» return path;
} /**
* set default path for Appto storage data
* this only can used by settings.
*
* @param path
* @hide
* @internal
*/
public static void setDefaultPath(String path){
» Log.i(TAG,"setDefaultPath path = " + path);
» if (path == null) {
» » Log.e(TAG,"setDefaultPath error! path = null");
» » return;
» }
»
» try {
» » SystemProperties.set(PROP_SD_DEFAULT_PATH,path);
» } catch (IllegalArgumentException e) {
» » Log.e(TAG,"IllegalArgumentException when setDefaultPath:" + e);
» }
} /**
* Returns external SD card path.» /sdcard2
* @hide
* @internal
*/
// public static String getExternalStoragePath(){» //method 1:
//» String sdCardDir = null;
// android.os.storage.StorageManager storageManager =
// (android.os.storage.StorageManager) context
// .getSystemService(Context.STORAGE_SERVICE);
// StorageVolume[] volumes = storageManager.getVolumeList();
// for (int i = 0; i < volumes.length; i++) {
// if (volumes[i].isRemovable() && volumes[i].allowMassStorage()) {
// sdCardDir = volumes[i].getPath();
// break;
// }
// }
// return sdCardDir;
// } public static String getExternalStoragePath(){» //method 2:
String sdCardDir = null;
String state = Environment.getStorageState(new File(STORAGE_PATH_SD2)); if(state.equals(Environment.MEDIA_MOUNTED)){
» sdCardDir = STORAGE_PATH_SD2;
}else if(state.equals(Environment.MEDIA_UNMOUNTED)){
» sdCardDir = Environment.MEDIA_UNMOUNTED;
}else{
» sdCardDir = STORAGE_PATH_SD2;
}
return sdCardDir;
} /**
* Returns internal storage path.
* @return
* @hide
* @internal
*/
public static String getInternalStoragePath(){
» String sdCardDir = null;
» String state = Environment.getStorageState(new File(STORAGE_PATH_SHARE_SD));
»
» if(state.equals(Environment.MEDIA_MOUNTED)){
» » sdCardDir = STORAGE_PATH_SD1;
» }else if(state.equals(Environment.MEDIA_UNMOUNTED)){
» » sdCardDir = Environment.MEDIA_UNMOUNTED;
» }else{
» » sdCardDir = STORAGE_PATH_SD1;
» }
» return sdCardDir;
} 1 }
定义的主要作用是往系统内存的属性里面加入属性presist.sys.sd.default.我们能够进入adb里面查看和改动一些属性1:adb shell 2:getprop + 键(或不加) tip:我们也能够setprop + 键 +值
2:在设置里面加入默认存储器的选项:
在Settings的project里面的.....res/xml/device_info_memory.xml的文件中面加入
......<span style="white-space:pre"> </span><PreferenceCategory
android:key="memory_select"
android:title="@string/select_memory" /> ......
然后在PreferenceCategory里面加入RadioButtonPreference (此处省略)
在Memroy.java文件中面加入
private void initDefaultWriteDisk(){
» mDefaultWriteCategory = (PreferenceCategory)findPreference(DEFAULT_WRITE_CATEGORY_KEY);
List<RadioButtonPreference> defaultWritePreference = new ArrayList<RadioButtonPreference>();
StorageVolume[] volumes = mStorageManager.getVolumeList();
List<StorageVolume> storageVolumesEx = initVolumeList(volumes);
for (int i = 0; i < storageVolumesEx.size(); i++) {
» StorageVolume volumn = storageVolumesEx.get(i);
» RadioButtonPreference avalibileDisk = new RadioButtonPreference(getActivity());
» String path = volumn.getPath();» //volumn path
» android.util.Log.i("haiyong.liu","volumn.path="+path);
» String state = Environment.getStorageState(new File(path));
»
» avalibileDisk.setKey(path);
» avalibileDisk.setTitle(volumn.getDescription(getActivity()));
» avalibileDisk.setPath(path);
» avalibileDisk.setOnPreferenceChangeListener(this);
» defaultWritePreference.add(avalibileDisk);
» android.util.Log.e("haiyong.liu","Environment="+state);
» if(state.equals(Environment.MEDIA_UNMOUNTED)||state.equals(Environment.MEDIA_REMOVED
)){
» »
» }else {
» » mDefaultWriteCategory.addPreference(avalibileDisk);
» » if(path.equals(StorageManagerEx.getDefaultPath())){
» » » avalibileDisk.setChecked(true);
» » » mDeafultWritePathPref = avalibileDisk;
» » }else{
» » » avalibileDisk.setChecked(false);
» » }
» }
» » }
} private List<StorageVolume> initVolumeList(StorageVolume[] volumes){
» List<StorageVolume> storageVolumes = new ArrayList<StorageVolume>();
» /*if(UserManager.supportsMultipleUsers()){» //return the current user's volumn lis
t if supported,otherwise ignore.
» » StorageVolume[] sv = mStorageManager.getVolumeListAsUser();
» » for (int i = 0; i < sv.length; i++) {
if (!"not_present".equals(mStorageManager.getVolumeState(volumes[i].getPath()))) {
storageVolumes.add(volumes[i]);
}
}
» » return storageVolumes;
» }*/
»
for (int i = 0; i < volumes.length; i++) {
if (!"not_present".equals(mStorageManager.getVolumeState(volumes[i].getPath()))) {
storageVolumes.add(volumes[i]);
}
} return storageVolumes;
} @Override
public boolean onPreferenceChange(Preference preference, Object newValue) { if (preference != null && preference instanceof RadioButtonPreference) {
if (mDeafultWritePathPref != null) {
mDeafultWritePathPref.setChecked(false);
}
StorageManagerEx.setDefaultPath(preference.getKey());
mDeafultWritePathPref = (RadioButtonPreference) preference;
return true;
}
return false;
}
然后在oncreate方法里面调用
initDefaultWriteDisk()
这种方法,这种方法放在Memory.java的onCreate(...)方法里面,另外,StorageManagerEx.setDefaultPath(),这种方法仅仅能够在settings这个apk里面使用,即仅仅有settings这个apk能够写入。
3:找到相应须要加入该功能的project,我们须要加入的是Camrea2。蓝牙,下载器,录音这几个Apk。找到这几个源代码存储数据的地方,将存储位置改为StorageManagerEx.getDefaultPath()
tip:SystemProperties写入数据时候须要权限。在Manifests.xml文件加上android:sharedUserId="android.uid.system",在Android.mk中。將LOCAL_CERTIFICATE := XXX改动成LOCAL_CERTIFICATE :=platform。
Android设置里面默认存储器选项(default write disk)的实现的更多相关文章
- android设置系统默认开机时间
1.设置RTC时间,该时间是如果RCT时钟断电以后使用的默认时间 Android L之前: \alps\mediatek\custom\[project]\preloader\ inc\cust_rt ...
- Android 设置界面的圆角选项
请先看一个图: 像这种界面的设计,其实是这样的:整体为一个LinearLayout,一个一个排下去,每一个点击项都是一个RelativeLayout(要为其设置clickable为true),分为左右 ...
- 【SecureCRT配置】修改默认卷屏行数当做一个操作,屏幕输出有上百行,当需要将屏幕回翻时,这个设置会有很大帮助,默认为500行,可以改为10000行,不用担心找不到了。 选项 => 全局选项 => Default Session => Edit Default Settings => Terminal => Emulation => Scrollback 修改为32000。
SecureCRT配置屏幕内容输出到log文件 SecureCRT看不到前几分钟操作的内容,或者想把通过vi命令查看的日志输出到log文件(在懒得下载日志文件的情况下),所以接下来就这样操作: 文件保 ...
- MTK Android 设置-选择日期格式 [管理和组织首选项,ListPreference,CheckBoxPreference,EditTextPreference,RingtonePreference]
###android.preference.ListPreference的一些特性 android:key 选项的名称或键 android:title 选项的标题 android:summary ...
- I.MX6 android 设置 默认 动态桌面
/************************************************************************ * I.MX6 android 设置 默认 动态桌面 ...
- Mysql 数据库date, datetime类型设置0000-00-00默认值(default)报错问题
Mysql 数据库date, datetime类型设置0000-00-00默认值报错问题 现象:MySQL5.7版本之后,date, datetime类型设置默认值"0000-00-00&q ...
- Android 9.0 默认输入法的设置流程分析
Android 输入法设置文章 Android 9.0 默认输入法的设置流程分析 Android 9.0 添加预置第三方输入法/设置默认输入法(软键盘) 前言 在上一篇文章 Android 9.0 ...
- Android eclipse 运行项目设置程序默认安装到SD卡
Android eclipse 运行项目设置程序默认安装到SD卡 1.在Android手机启用USB调试功能 2.在Windows系统中打开命令提示符(开始菜单,选择运行,输入cmd回车即可),使用 ...
- SQL Server 默认跟踪(Default Trace)
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) 查看默认跟踪信息(Default Tr ...
随机推荐
- (转)js获取url参数值
明天有空编辑下 今天做项目遇到js取得url地址问号后面的参数,找了下面的,用着非常好,项目是选项卡样式的,也就是一点击二级分类,底下的同样名字的背景变红(选项卡倍选中) http://www.cnb ...
- php中函数不确定参数个数时获取所有参数
func_get_arg(),func_get_args()和func_num_args()的用法 这三个函数呢,都是以func_打头的,顾名思义,是跟php的函数有关的.我们在写类的时候也经常用到这 ...
- error: expected constructor, destructor, or type conversion before '.' token
今天写代码是遇到这样一个问题error: expected constructor, destructor, or type conversion before '.' token:立马网上查,原来是 ...
- C++重载操作符
重载的函数操作符,对对象使用起来就像对象是一个函数一样 class A{public:A(int n);int operator()(int n); //需要一个参数,返回int类型void out ...
- wm_char
用于接收键盘输入的消息 int CXuexi2View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateS ...
- git clone 远程分支
先初始化一个git 仓库 命令:git init git clone 相应的地址 这样就会形成一个.git 隐藏文件夹 一定要注意的,要进入到子文件夹去git checkout feature/0. ...
- 2016年9月3日 文成小盆友python-num18 - django进阶一
一.深入django的路由系统 下面为django的请求生命周期 下面来看下整个生命周期中的路由系统: 在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规则如下: " ...
- twisted(2)--聊天系统
我们今天要做一个聊天系统,这样可以和我们之前flask api那系列文章结合起来:其次,聊天系统最能代表tcpserver,以后可以套用各种模型,比如我们公司做的物联网,其实就是把聊天系统简化一下. ...
- C++是怎么实现多态性的
C++是怎么实现多态性的,C++中多态实现的原理, 当一个类中有虚函数时,系统会为该类构造一个虚函数表vtable,他是一个指针数组,存放每个虚函数的入口地址,编译器还会在此类中隐含插入一个指针vpt ...
- UVA 1600 Patrol Robot
带状态的bfs 用一个数(ks)来表示状态-当前连续穿越的障碍数: step表示当前走过的步数: visit数组也加一个状态: #include <iostream> #include & ...