有很多朋友咨询过我如果修改Android的系统参数 比如 ro.build.id ro.product.name ro.product.device ro.product.model等参数。对应在APP端的java代码就是Build.ID Build.PRODUCT Build.MODEL等参数。
不同于Xposed VirtualApp 双开助手
DualSpace
Go双开
双开精灵 这些软件是通过hook方式,让app 运行在一个虚拟的环境中。世面上有很多成熟的技术可以检测到app 是真实运行在Android中还是虚拟空间中。如果彻底的修改只能通过修改Android源码的方式。一劳永逸的解决
Android 的参数信息主要保存在build.prop中,

# begin build properties# autogenerated by buildinfo.shro.build.id=KOT49Hro.build.display.id=V1.01ro.build.version.incremental=eng.dyna.1477556289ro.custom.build.version=1477556289ro.build.version.sdk=19ro.build.version.codename=RELro.build.version.release=4.4.2ro.build.date=Thu Oct 27 16:21:53 CST 2016ro.build.date.utc=1477556513ro.build.type=userro.build.user=dynaro.build.host=dyna-PowerEdge-R720ro.build.tags=test-keysro.product.model=P92ro.product.brand=alpsro.product.name=sanstar82_cwet_kkro.product.device=sanstar82_cwet_kkro.product.board=sanstar82_cwet_kkro.product.cpu.abi=armeabi-v7aro.product.cpu.abi2=armeabiro.product.manufacturer=alpsro.product.locale.language=zhro.product.locale.region=CN

一个标准的build.prop文件如上图所示,Android系统在启动的阶段,会在解析init的时候加载这些属性文件
\system\core\init\Init.c

int main(int argc, char **argv){        //加入到action queue队列    queue_builtin_action(property_service_init_action, "property_service_init");    for(;;)        //执行action queue队列        //接收通过socket向property service 发送的数据;        nr = poll(ufds, fd_count, timeout);        ……        handle_property_set_fd();}

property_service_init_action是初始化属性的入口

static int property_service_init_action(int nargs, char **args){    start_property_service();}

\system\core\init\property_service.c:

void start_property_service(void){    //加载属性配置文件    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);    load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);    load_persistent_properties();        //创建socket资源 并绑定    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);    //监听    listen(fd, 8);}Property Service 是运行在init守护进程中。

这里会加载 /system/build.prop /default.prop 这两个属性文件
之后保存这些属性到共享内存空间。供所有进程访问
这里有三种方式访问系统属性。
第一种是adb shell 方式

PS C:\Users\xxx> adb shell getprop  ro.product.cpu.abilist32armeabi-v7a,armeabiPS C:\Users\xxx>

第二种 通过SystemProperties 类访问,这个需要导入Android 源码的framework.jar ,否则编译通过不了

String test = SystemProperties.get("o.build.id");

没有framework.jar ,也可以通过反射的方式

     public String getProperty(String key, String defaultValue) {        String value = defaultValue;        try {            Class<?> c = Class.forName("android.os.SystemProperties");            Method get = c.getMethod("get", String.class, String.class);            value = (String)(get.invoke(c, key, "unknown" ));        } catch (Exception e) {            e.printStackTrace();        }         return value;    }

第三种是

android.os.Build.PRODUCTandroid.os.Build.ID

通过源码可以明显看到这种方法只是第二种做了一层封装

 public static  final String PRODUCT = getString("ro.product.name");    /** The name of the industrial design. */    public static  final String DEVICE = getString("ro.product.device");
private static String getString(String property) {        return SystemProperties.get(property, UNKNOWN);    }

最后还是调用 SystemProperties.get 获取系统参数
现在如果想修改Android系统参数,可以通过上面三种方式。但是在实际测试中。大家在获取参数的时候只会用到第二种和第三种。
有人首先想到修改\frameworks\base\core\java\android\build.java文件。

public class Build {    private static final String TAG = "Build";    /** Value used for when a build property is unknown. */    public static final String UNKNOWN = "unknown";    /** Either a changelist number, or a label like "M4-rc20". */    public static final String ID = "PPTVID";    /** A build ID string meant for displaying to the user */    public static final String DISPLAY = "PPTVDISPLAY";    /** The name of the overall product. */    public static final String PRODUCT = "PPTVTV";    /** The name of the industrial design. */    public static final String DEVICE = "PPTV_OS";

这种方式完全可以,但是没法做到动态。
后面我又想到一种方法。加入B 是检测改机的APP,我让B 在调用时候 执行下面的语句

public static final String PRODUCT = SystemProperties.get(ro.product.name, UNKNOWN);

然后我专门做一个A app 用于修改

 SystemProperties.set(ro.product.name,"PPTV") .......

每次B 启动前,我先让A执行 SystemProperties.set 修改系统参数。
测试后发现A的修改只对 A这个app 起作用。后来查看源码得知
1、首先public static final String PRODUCT 是final 类型
只会在初始化执行一次。
2、build.java 是static类型。每个进程单独有一份。不是共享的。
所以修改A只会对A进程起作用
我又想到动态修改 SystemProperties 里面的属性。在系统启动的时候加载我自己预置/sdcard/build.prop

private  String FindProp(String key) {        String fileName = "build.prop";        String retValue = null;        try {            String sdPath = Environment.getExternalStorageDirectory().getPath();            File file = new File(sdPath,fileName);            if (file.isFile() && file.exists()) {                InputStreamReader isr = new InputStreamReader(new FileInputStream(file));                BufferedReader br = new BufferedReader(isr);                String lineTxt = null;                while ((lineTxt = br.readLine()) != null) {                    if (!"".equals(lineTxt)) {                        if(lineTxt.contains("#")){                            continue;                        }                        String props[] = lineTxt.split("\\=");                        if(props.length == 2){                            String propKey = lineTxt.split("\\=")[0];                            String propValue = lineTxt.split("\\=")[1];                            if(propKey.equals(key)){                                retValue = propValue;                                break;                            }else{                                continue;                            }                        }                    }                }                isr.close();                br.close();            }else {                //  Toast.makeText(getApplicationContext(),"can not find file",0).show();            }        } catch (Exception e) {            e.printStackTrace();        }        return  retValue;    }

测试之后跟上面一样,无法正常修改。
最后经过多次测试终于找到一个合适的方法,原理是

原理是开发一个app 用于检测管理
1、读取要修改的系统参数文件,可以是/sdcard/build.prop 或者
从网络获取
2、设置当前的属性到SystemProperties 和build中。
3、开启标志,开启后改机检测工具就读我们设置的属性
经过测试完全满足要求。有希望交流的朋友可以加我qq:875646589

更多相关文章

  1. Android(安卓)使用Vitamio实现播放视频(一)
  2. Android(安卓)ImageView的scaleType属性与adjustViewBounds属性
  3. Android自定义属性,format详解
  4. Android获取版本号
  5. 有关Android中EditText的一些属性
  6. Android(安卓)ApiDemos示例解析(15):App->Activity->SetWallpaper
  7. android jni介绍
  8. mybatisplus的坑 insert标签insert into select无参数问题的解决
  9. Python技巧匿名函数、回调函数和高阶函数

随机推荐

  1. SlidingMenu和ActionBarSherlock结合做出
  2. Android如何获得系统版本
  3. 创建android逐帧动画的两种方式
  4. Android——开发环境
  5. android 中文api (62) —— ViewSwitcher
  6. 总目录
  7. Android 之 AsyncTask 异步任务
  8. [Android] ACTION_GET_CONTENT与ACTION_P
  9. android之BitMap
  10. android通过ksoap2对webservice的解析