原生的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. .NET中删除空白字符串的10大方法

    介绍 我们有无数方法可用于删除字符串中的所有空白.大部分都能够在绝大多数的用例中很好工作,但在某些对时间敏感的应用程序中,是否采用最快的方法可能就会造成天壤之别. 如果你问空白是什么,那说起来还真是有 ...

  2. 如何使用CSS Sprites技术进行图片合并

    http://jingyan.baidu.com/article/066074d6757654c3c21cb02d.html

  3. MySQL 表子查询

    MySQL 表子查询 表子查询是指子查询返回的结果集是 N 行 N 列的一个表数据. MySQL 表子查询实例 下面是用于例子的两张原始数据表: article 表: aid title conten ...

  4. MYSQL Model报错:指定的存储区提供程序在配置中找不到 的解决

    开了项目发现没装mysql及mysql connector/.net.下了个最新版本,结果打开vs,进入模型edmx页面就出了这个问题. 刚开始以为是ProviderManifestToken版本的问 ...

  5. libusb简介

    概述 libusb是一个C库,它提供了通用的访问USB设备. 它的目的是供开发人员使用方便的生产与USB通信硬件的应用程序. 可移植的: 使用一个跨平台API,它提供了访问USB设备在Linux上,O ...

  6. c++模板类被继承时他的成员不能被子类看到

    c++模板类被继承时他的成员不能被子类看到,必须用限定的符号 this->foo  或者 baseclass::foo,或者using bassclass::foo. msvc不提示错误,gcc ...

  7. jsp连接MySQL操作GIS地图数据,实现添加point的功能

    index_map.jsp中的代码: <%@ page language="java" pageEncoding="utf-8"%> <%@ ...

  8. 搭建splinter+python环境时遇到的错误

    因为不想用urllib2了,没有用过splinter,今天就想试试,毕竟后者支持的功能更人性化/自动化. 1,安装splinter 安装过程很简单,安装了pip的话,执行: $ [sudo] pip ...

  9. 如何升级nodejs版本

    直接下载最新版安装即可,例如我本地的nodejs版本为: y@y:untitled$ node -v v0.10.33 当前node官网最新版本为:Current Version: v0.12.2 下 ...

  10. Activity和Servlet的相似之处和区别

    相似之处:1.Activity.Servlet的职责都是向用户呈现界面.2.开发者开发Activity.Servlet都继承系统的基类.3.Activity.Servlet开发出来之后都需要进行配置. ...