原生的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)的实现的更多相关文章

  1. android设置系统默认开机时间

    1.设置RTC时间,该时间是如果RCT时钟断电以后使用的默认时间 Android L之前: \alps\mediatek\custom\[project]\preloader\ inc\cust_rt ...

  2. Android 设置界面的圆角选项

    请先看一个图: 像这种界面的设计,其实是这样的:整体为一个LinearLayout,一个一个排下去,每一个点击项都是一个RelativeLayout(要为其设置clickable为true),分为左右 ...

  3. 【SecureCRT配置】修改默认卷屏行数当做一个操作,屏幕输出有上百行,当需要将屏幕回翻时,这个设置会有很大帮助,默认为500行,可以改为10000行,不用担心找不到了。 选项 => 全局选项 => Default Session => Edit Default Settings => Terminal => Emulation => Scrollback 修改为32000。

    SecureCRT配置屏幕内容输出到log文件 SecureCRT看不到前几分钟操作的内容,或者想把通过vi命令查看的日志输出到log文件(在懒得下载日志文件的情况下),所以接下来就这样操作: 文件保 ...

  4. MTK Android 设置-选择日期格式 [管理和组织首选项,ListPreference,CheckBoxPreference,EditTextPreference,RingtonePreference]

    ###android.preference.ListPreference的一些特性 android:key  选项的名称或键 android:title  选项的标题 android:summary  ...

  5. I.MX6 android 设置 默认 动态桌面

    /************************************************************************ * I.MX6 android 设置 默认 动态桌面 ...

  6. Mysql 数据库date, datetime类型设置0000-00-00默认值(default)报错问题

    Mysql 数据库date, datetime类型设置0000-00-00默认值报错问题 现象:MySQL5.7版本之后,date, datetime类型设置默认值"0000-00-00&q ...

  7. Android 9.0 默认输入法的设置流程分析

    Android 输入法设置文章 Android 9.0 默认输入法的设置流程分析 Android 9.0 添加预置第三方输入法/设置默认输入法(软键盘) 前言 在上一篇文章  Android 9.0 ...

  8. Android eclipse 运行项目设置程序默认安装到SD卡

    Android eclipse 运行项目设置程序默认安装到SD卡  1.在Android手机启用USB调试功能 2.在Windows系统中打开命令提示符(开始菜单,选择运行,输入cmd回车即可),使用 ...

  9. SQL Server 默认跟踪(Default Trace)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) 查看默认跟踪信息(Default Tr ...

随机推荐

  1. Web Api学习一

    接触WebApi读的第一篇文章: ASP.NET Web API(一):使用初探,GET和POST数据 实践过程中,用的Fiddler模拟Post请求时收到的对象总是为空null 解决:将文章中的内容 ...

  2. iOS8中添加的extensions总结(四)——Action扩展

    Action扩展 注:此教程来源于http://www.raywenderlich.com的<iOS8 by Tutorials> 1.准备 本次教程利用网站bitly.com进行 bit ...

  3. Apache 2.x+jboss6.1反向代理session共享问题设置

    2016年8月4日,第一次开笔写博客园,今天在公司解决了一个问题. apache+jboss做负载均衡的问题一直困扰了很久.问题描述如下,使用apche做反向代理转发给3台jboss 的app,app ...

  4. GitHub——如何更新已经fork的代码

    github上有个很方便的功能叫fork,将别人的工程一键复制到自己账号下.这个功能很方便,但有点不足的是,当源项目更新后,你fork的分支并不会一起更新,需要自己手动去更新.下面记录下网上找到的更新 ...

  5. extjs中grid中行内文本或图片居中显示

    我是看了网上写的方法调试自己的代码来实现的,实现的方式是当加载store数据时改变grid的行样式,源码如下: html代码: <div id="weatherP_grid-body& ...

  6. [算法导论]贪心算法(greedy algorithm)

    转载请注明出处:http://www.cnblogs.com/StartoverX/p/4611544.html 贪心算法在每一步都做出当时看起来最佳的选择.也就是说,它总是做出局部最优的选择,寄希望 ...

  7. C#中out的一种用法

    1.当希望方法返回多个值时,声明out 方法很有用. 这样使方法可以有选择地返回值. using System; using System.Collections.Generic; using Sys ...

  8. IOS编程教程(八):在你的应用程序添加启动画面

    IOS编程教程(八):在你的应用程序添加启动画面   虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...

  9. (摘)Chart属性设置

    Chart ChartBorder 图表区域的边框设置 ChartFill 图表区域的背景填充 Legend 图表的注释标签显示设置项目,一组数据对应一种颜色的注释 IsHStack 当有多个显示项的 ...

  10. How systems researchers build systems

    Define the problem >>Identify the constraints and abstract problem propose solution:simple ide ...