探索xpose如何通过修改手机数据来实现刷某积分墙某团购的

最近看到网上的基于xpose的android修改器可以通过修改手机信息来实现刷单刷广告刷积分墙,于是乎,照着做了一个,已经可以完美支持刷大部分积分墙广告,然后在此发布一些主要的实现方法。

关于xpose简单使用可以看上一篇,网上的xposeapp实在太多了,例如绿色守护这里写图片描述这里写图片描述

某些赚钱平台是没有用户登陆体系的,判断用户的依据无非是一些imei,mac,androidid码,我只要分析这个软件是使用什么id来判断用户的,然后在使用xpose修改他们,就可以很好的装成很多个用户的样子。

那么接下来就是修改手机数据了,查看下面代码

    public class XposeHook implements IXposedHookLoadPackage{


    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

        if(android.os.Process.myUid() <= 10000){
            L.debug("系统应用"+loadPackageParam.packageName+android.os.Process.myUid());
            return ;
        }else{
            L.debug("普通应用"+loadPackageParam.packageName+android.os.Process.myUid());
        }

        //xpose生效之后,每次启动一个app都会执行handleLoadPackage方法。当你将imei 从123改为321的时候,将他保存到本地文件,但是static JsonObject没有更新,initConfigMap是为了更新static JsonObject,要执行到改方法必须要重启app,或者在addHookMethod方法更新的话可以更快,但是addHookMethod调用太频繁了,强迫症不喜欢
        XposeUtil.initConfigMap();

        if(RecordFileUtil.ExternalStorage.length() == 0){
            RecordFileUtil.ExternalStorage = Environment.getExternalStorageDirectory().getAbsolutePath();
        }
        //劫持字段值
        setSystemData();

        //劫持指定的方法
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getDeviceId", new Object[]{});
        addHookMethod(loadPackageParam.packageName, Settings.Secure.class.getName(), loadPackageParam.classLoader, "getString", new Object[]{ContentResolver.class.getName(), String.class.getName()});
        addHookMethod(loadPackageParam.packageName, Settings.System.class.getName(), loadPackageParam.classLoader, "getString", new Object[]{ContentResolver.class.getName(), String.class.getName()});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getLine1Number", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSimSerialNumber", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSubscriberId", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSimOperator", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getNetworkOperatorName", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getNetworkType", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getPhoneType", new Object[]{});
        addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSimState", new Object[]{});

        addHookMethod(loadPackageParam.packageName, WifiInfo.class.getName(), loadPackageParam.classLoader, "getMacAddress", new Object[]{});
        addHookMethod(loadPackageParam.packageName, WifiInfo.class.getName(), loadPackageParam.classLoader, "getSSID", new Object[]{});
        addHookMethod(loadPackageParam.packageName, WifiInfo.class.getName(), loadPackageParam.classLoader, "getBSSID", new Object[]{});

        addHookMethod(loadPackageParam.packageName, Build.class.getName(), loadPackageParam.classLoader, "getRadioVersion", new Object[]{});
        addHookMethod(loadPackageParam.packageName, BluetoothAdapter.class.getName(), loadPackageParam.classLoader, "getAddress", new Object[]{});

        addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getTypeName", new Object[]{});
        addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getType", new Object[]{});
        addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getSubtype", new Object[]{});
        addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getSubtypeName", new Object[]{});
        addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getExtraInfo", new Object[]{});
        addHookMethod(loadPackageParam.packageName, ConnectivityManager.class.getName(), loadPackageParam.classLoader, "getNetworkInfo", new Object[]{Integer.TYPE.getName()});

        addHookMethod(loadPackageParam.packageName, ActivityManager.class.getName(), loadPackageParam.classLoader, "getRunningAppProcesses", new Object[]{});
        addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledPackages", new Object[]{Integer.TYPE.getName()});
        addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getPackageInfo", new Object[]{String.class.getName(), Integer.TYPE.getName()});
        addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getApplicationInfo", new Object[]{String.class.getName(), Integer.TYPE.getName()});
        addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledApplications", new Object[]{Integer.TYPE.getName()});

        addHookMethod(loadPackageParam.packageName, "android.os.SystemProperties", loadPackageParam.classLoader, "get", new Object[]{String.class.getName()});
        addHookMethod(loadPackageParam.packageName, "android.content.ContextWrapper", loadPackageParam.classLoader, "getExternalCacheDir", new Object[]{});




        //劫持构造方法
        addHookConstructor(loadPackageParam.packageName, File.class.getName(), loadPackageParam.classLoader, new Object[]{String.class.getName()});
        addHookConstructor(loadPackageParam.packageName, File.class.getName(), loadPackageParam.classLoader, new Object[]{String.class.getName(), String.class.getName()});
        addHookConstructor(loadPackageParam.packageName, FileReader.class.getName(), loadPackageParam.classLoader, new Object[]{String.class.getName()});
        addHookConstructor(loadPackageParam.packageName, FileReader.class.getName(), loadPackageParam.classLoader, new Object[]{File.class.getName()});
    }

    //修改字段值,上面的XposeUtil.initConfigMap();方法已经将本地数据保存到map中,我这里用jsonobject保存要修改的数据
    private void setSystemData() {

        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_RELEASE))){
            XposedHelpers.setStaticObjectField(Build.VERSION.class,"RELEASE",XposeUtil.configMap.optString(XposeUtil.m_RELEASE));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_SDK))){
            XposedHelpers.setStaticObjectField(Build.VERSION.class, "SDK", XposeUtil.configMap.optString(XposeUtil.m_SDK));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_framework))){
            String[] split = XposeUtil.configMap.optString(XposeUtil.m_framework).split("_");
            if(split.length == 2){
                XposedHelpers.setStaticObjectField(Build.class,"CPU_ABI",split[0]);
                XposedHelpers.setStaticObjectField(Build.class,"CPU_ABI2",split[1]);
            }
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_brand))){
            XposedHelpers.setStaticObjectField(Build.class, "BRAND", XposeUtil.configMap.optString(XposeUtil.m_brand));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_model))){
            XposedHelpers.setStaticObjectField(Build.class, "MODEL", XposeUtil.configMap.optString(XposeUtil.m_model));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_product))){
            XposedHelpers.setStaticObjectField(Build.class, "PRODUCT", XposeUtil.configMap.optString(XposeUtil.m_product));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_manufacture))){
            XposedHelpers.setStaticObjectField(Build.class, "MANUFACTURER", XposeUtil.configMap.optString(XposeUtil.m_manufacture));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_hardware))){
            XposedHelpers.setStaticObjectField(Build.class, "HARDWARE", XposeUtil.configMap.optString(XposeUtil.m_hardware));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_fingerprint))){
            XposedHelpers.setStaticObjectField(Build.class, "FINGERPRINT", XposeUtil.configMap.optString(XposeUtil.m_fingerprint));
        }
        if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_serial))){
            XposedHelpers.setStaticObjectField(Build.class, "SERIAL", XposeUtil.configMap.optString(XposeUtil.m_serial));
        }

    }

    //劫持指定方法
    public void addHookMethod(final String packageName, final String className, ClassLoader classLoader, final String methodName, Object[] parameterTypesAndCallback){

        XC_MethodHook xc_methodHook = new XC_MethodHook() {
            //方法调用前劫持,将参数替换成指定参数,实现屏蔽指定的包名
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                if("getPackageInfo".equals(methodName) ){
                    if(param.args[0].equals(XposeUtil.pkg1) || param.args[0].equals(XposeUtil.pkg2) || param.args[0].equals(XposeUtil.pkg3)){
                        param.args[0] = "yyyy.mmmm.aaaa.xxxx";
                    }
                }else
                if("getApplicationInfo".equals(methodName) ){
                    if(param.args[0].equals(XposeUtil.pkg1) || param.args[0].equals(XposeUtil.pkg2) || param.args[0].equals(XposeUtil.pkg3)){
                        param.args[0] = "yyyy.mmmm.aaaa.xxxx";
                    }
                }
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {


//                        L.log("android.os.SystemProperties获取序列号");
                if("get".equals(methodName) && className.equals("android.os.SystemProperties")){
                    if(param.args[0].equals("ro.serialno")){
                        String serial = XposeUtil.configMap.optString(XposeUtil.m_serial);
                        if(!TextUtils.isEmpty(serial)){
                            param.setResult(serial);
                        }
                    }
                }else
                //屏蔽自己的包名
                if("getInstalledApplications".equals(methodName) ){
                    List<ApplicationInfo> installedApplications = (List<ApplicationInfo>) param.getResult();
                    for (int i = installedApplications.size() - 1; i >= 0 ; i--) {
                        ApplicationInfo applicationInfo = installedApplications.get(i);
                        if(applicationInfo.equals(XposeUtil.pkg1) || applicationInfo.equals(XposeUtil.pkg2) || applicationInfo.equals(XposeUtil.pkg3)){
                            installedApplications.remove(i);
                        }
                    }
                    param.setResult(installedApplications);
                }else
                屏蔽自己
                if("getRunningAppProcesses".equals(methodName) ){
                    List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = (List<ActivityManager.RunningAppProcessInfo>) param.getResult();
                    for (int i = runningAppProcesses.size() - 1; i >= 0; i--) {
                        ActivityManager.RunningAppProcessInfo runningAppProcessInfo = runningAppProcesses.get(i);
                        if(runningAppProcessInfo.processName.equals(XposeUtil.pkg1) || runningAppProcessInfo.processName.equals(XposeUtil.pkg2) || runningAppProcessInfo.processName.equals(XposeUtil.pkg3)){

                            runningAppProcesses.remove(i);
                        }
                    }
                    param.setResult(runningAppProcesses);
                }else
                //屏蔽自己
                if("getInstalledPackages".equals(methodName) ){
                    List<PackageInfo> installedPackages = (List<PackageInfo>) param.getResult();
                    for (int i = installedPackages.size() - 1; i >= 0; i--) {
                        String s = installedPackages.get(i).packageName;
                        if(s.equals(XposeUtil.pkg1) || s.equals(XposeUtil.pkg2) || s.equals(XposeUtil.pkg3)){
                            L.debug("getInstalledPackages+移除"+s);
                            installedPackages.remove(i);
                        }
                    }
                    param.setResult(installedPackages);
                }else
                //蓝牙地址
                if("getAddress".equals(methodName)){
                    String m_bluetoothaddress = XposeUtil.configMap.optString(XposeUtil.m_bluetoothaddress);
                    if(!TextUtils.isEmpty(m_bluetoothaddress)){
                        param.setResult(m_bluetoothaddress);
                    }else{
                    }
                }else
                //固件版本
                if("getRadioVersion".equals(methodName)){
                    String m_firmwareversion = XposeUtil.configMap.optString(XposeUtil.m_firmwareversion);
                    if(!TextUtils.isEmpty(m_firmwareversion)){
                        L.debug("修改m_firmwareversion");
                        param.setResult(m_firmwareversion);
                    }else{
                        L.debug("获取m_firmwareversion为空");
                    }
                }else
                //无线路由地址
                if("getBSSID".equals(methodName)){
                    String m_BSSID = XposeUtil.configMap.optString(XposeUtil.m_BSSID);
                    if(!TextUtils.isEmpty(m_BSSID)){
                        L.debug("修改m_BSSID");
                        param.setResult(m_BSSID);
                    }else{
                        L.debug("获取m_BSSID为空");
                    }
                }else
                //无线路由名
                if("getSSID".equals(methodName)){
                    String m_SSID = XposeUtil.configMap.optString(XposeUtil.m_SSID);
                    if(!TextUtils.isEmpty(m_SSID)){
                        L.debug("修改m_SSID");
                        param.setResult(m_SSID);
                    }else{
                        L.debug("获取m_SSID为空");
                    }
                }else
                //mac地址
                if("getMacAddress".equals(methodName)){
                    String m_macAddress = XposeUtil.configMap.optString(XposeUtil.m_macAddress);
                    if(!TextUtils.isEmpty(m_macAddress)){
                        L.debug("修改m_macAddress");
                        param.setResult(m_macAddress);
                    }else{
                        L.debug("获取m_macAddress为空");
                    }
                }else
                //手机卡状态
                if("getSimState".equals(methodName)){
                    int m_simState = XposeUtil.configMap.optInt(XposeUtil.m_simState, -1);
                    if(m_simState != -1)
                        param.setResult(5);

                }else
                //手机类型
                if("getPhoneType".equals(methodName)){
                    int m_phoneType = XposeUtil.configMap.optInt(XposeUtil.m_phoneType,-1);
                        if(m_phoneType != -1)
                        param.setResult(m_phoneType);

                }else
                //网络类型
                if("getNetworkType".equals(methodName)){
                    int m_networkType = XposeUtil.configMap.optInt(XposeUtil.m_networkType, -1);
                    if(m_networkType != -1)
                        param.setResult(m_networkType);

                }else
                //网络类型名
                if("getNetworkOperatorName".equals(methodName)){
                    String networkOperatorName = XposeUtil.configMap.optString(XposeUtil.m_networkOperatorName);
                    if(!TextUtils.isEmpty(networkOperatorName)){
                        L.debug("修改networkOperatorName");
                        param.setResult(networkOperatorName);
                    }else{
                        L.debug("获取networkOperatorName为空");
                    }
                }else
                //运营商
                if("getSimOperator".equals(methodName)){
                    String simOperator = XposeUtil.configMap.optString(XposeUtil.m_simOperator);
                    if(!TextUtils.isEmpty(simOperator)){
                        L.debug("修改simOperatord");
                        param.setResult(simOperator);
                    }else{
                        L.debug("获取simOperator为空");
                    }
                }else
                //IMSI
                if("getSubscriberId".equals(methodName)){
                    String subscriberId = XposeUtil.configMap.optString(XposeUtil.m_subscriberId);
                    if(!TextUtils.isEmpty(subscriberId)){
                        L.debug("修改subscriberId");
                        param.setResult(subscriberId);
                    }else{
                        L.debug("获取subscriberId为空");
                    }
                }else
                //手机卡序列号
                if("getSimSerialNumber".equals(methodName)){
                    String simSerialNumber = XposeUtil.configMap.optString(XposeUtil.m_simSerialNumber);
                    if(!TextUtils.isEmpty(simSerialNumber)){
                        L.debug("修改simSerialNumber");
                        param.setResult(simSerialNumber);
                    }else{
                        L.debug("获取simSerialNumber为空");
                    }
                }else
                //电话号码
                if("getLine1Number".equals(methodName)){
                    String phoneNum = XposeUtil.configMap.optString(XposeUtil.m_phoneNum);
                    if(!TextUtils.isEmpty(phoneNum)){
                        L.debug("修改phoneNum");
                        param.setResult(phoneNum);
                    }else{
                        L.debug("获取phoneNum为空");
                    }
                }else
                //android_id
                if("getString".equals(methodName) && param.args[1].equals("android_id")){
                    String androidId = XposeUtil.configMap.optString(XposeUtil.m_androidId);
                    if(!TextUtils.isEmpty(androidId)){
                        L.debug("修改androidId");
                        param.setResult(androidId);
                    }else{
                        L.debug("获取androidId为空");
                    }
                }else
                //device_id
                if("getDeviceId".equals(methodName)){
                    L.debug("packageName" + packageName + "configMap" + XposeUtil.configMap.toString());
                    XposeUtil.initConfigMap();
                    String deviceid = XposeUtil.configMap.optString(XposeUtil.m_deviceId);
                    if(!TextUtils.isEmpty(deviceid)){
                        L.debug("修改deviceid");
                        param.setResult(deviceid);
                    }else{
                        L.debug("获取deviceid为空");

                    }
                }else
                if("testXpose".equals(methodName)){
                    param.setResult(1);
                }

            }
        };
        //执行hook方法findAndHookMethod的param值为参数+回调的可变参数,故要将回调加入进去
        Object [] param = new Object[parameterTypesAndCallback.length + 1];
        for (int i = 0; i < param.length; i++) {
            if(i == param.length-1){
                param[param.length - 1] = xc_methodHook;
                XposedHelpers.findAndHookMethod(className, classLoader, methodName, param);
                return ;
            }
            param[i] = parameterTypesAndCallback[i];
        }
    }

    //劫持构造方法
    public void addHookConstructor(final String packageName,String className,ClassLoader classLoader,Object[] parameterTypesAndCallback){

        XC_MethodHook xc_methodHook = new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);

                //监听File实例构建,实现监听文件的操作
                if (XposeUtil.configMap.optBoolean(XposeUtil.FileRecordPackageNameSwitch) && XposeUtil.configMap.optString(XposeUtil.FileRecordPackageName).contains(packageName)) {
                    String attr = "";
                    if(param.args[0]instanceof File){
                        attr = ((File) param.args[0]).getAbsolutePath();
                    }else if(param.args.length > 1 && param.args[1] != null ){
                        String separator = "";
                        if(!param.args[0].toString().endsWith("/"))
                            separator = "/";
                        attr =  param.args[0].toString() + separator + param.args[1].toString();
                    }else{
                        attr = (String) param.args[0];
                    }
                    if (attr.contains(RecordFileUtil.ExternalStorage) && !attr.contains("xpose")
                            && !(attr.startsWith(RecordFileUtil.ExternalStorage+RecordFileUtil.FILE_PATH_RECORD))
                                    && RecordFileUtil.addFileRecord(packageName, attr)) ;
                }
            }
        };

        //执行hook方法findAndHookConstructor的param值为参数+回调的可变参数,故要将回调加入进去
        Object [] param = new Object[parameterTypesAndCallback.length + 1];
        for (int i = 0; i < param.length; i++) {
            if(i == param.length-1){
                param[param.length - 1] = xc_methodHook;
                XposedHelpers.findAndHookConstructor(className,classLoader,param);
                return ;
            }
            param[i] = parameterTypesAndCallback[i];
        }
    }   
}

只要将要修改的数据保存到static JsonObject中,每次只要程序执行到你hook的方法,就能执行你上面写的回调啦,注意每个app的static JsonObject不是共用的,你会发现每次启动一个app都会调用handleLoadPackage方法。

当你将imei 从123改为321的时候,将他保存到本地文件,但是static JsonObject没有更新,我这里是在handleLoadPackage更新,或者在hook方法里面更新数据,比如

    if("getDeviceId".equals(methodName)){
                    //每次执行这个方法就更新数据
                    XposeUtil.initConfigMap();
                    String deviceid = XposeUtil.configMap.optString(XposeUtil.m_deviceId);
                    if(!TextUtils.isEmpty(deviceid)){
                        L.debug("修改deviceid");
                        param.setResult(deviceid);
                    }else{
                        L.debug("获取deviceid为空");

                    }
                }

initConfigMap也就是将数据读取到 static JSONObject 而已

public class XposeUtil {
    public static String FILE_PATH_XPOSR = "/.xpose/";
    public static String FileRecordPackageName = "FileRecordPackageName";
    public static String FileRecordPackageNameSwitch = "FileRecordPackageNameSwitch";
    public static String m_deviceId = "deviceId";//设备id
    public static String m_androidId = "androidId";//android_id
    public static String m_phoneNum = "phoneNum";//电话号码
    public static String m_simSerialNumber = "simSerialNumber";//手机卡序列号
    public static String m_subscriberId = "subscriberId";//IMSI
    public static String m_simOperator = "simOperator";//运营商
    public static String m_networkOperatorName = "networkOperatorName";//网络类型名
    public static String m_networkType = "networkType";//网络类型
    public static String m_phoneType = "phoneType";//手机类型
    public static String m_simState = "simState";//手机卡状态
    public static String m_macAddress = "macAddress";//mac地址
    public static String m_SSID = "SSID";//无线路由名
    public static String m_BSSID = "BSSID";//无线路由地址
    public static String m_firmwareversion = "firmwareversion";//固件版本
    public static String m_bluetoothaddress = "bluetoothaddress";//蓝牙地址
    public static String m_screenSize = "screenSize";//蓝牙地址

    public static String m_RELEASE = "RELEASE";//系统版本
    public static String m_SDK = "SDK";//系统版本值
    public static String m_framework = "framework";//系统架构
    public static String m_brand = "brand";//手机品牌
    public static String m_model = "model";//手机型号
    public static String m_product = "product";//产品名
    public static String m_manufacture = "manufacture";//制造商
    public static String m_hardware = "hardware";//硬件
    public static String m_fingerprint = "fingerprint";//指纹
    public static String m_serial = "serial";//序列号

    public static String pkg1 = "de.robv.android.xpose.installer";
    public static String pkg2 = "pro.burgerz.wsm.manager";

    public static JSONObject configMap = new JSONObject();

    /**
     * 将map信息写入供xpose调用
     */
    public static void saveConfigMap(){

        new Thread(){
            @Override
            public void run() {
                saveFileData("xposeDevice.txt",configMap.toString());
            }
        }.start();
    }
    /**
     * 读取文本数据到configMap
     */
    public static void initConfigMap(){
        try {
            configMap = new JSONObject(getFileData("xposeDevice.txt"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private static void saveFileData(String fileName,String value){
        File localFile = new File(Environment.getExternalStorageDirectory()+FILE_PATH_XPOSR);
        if(!localFile.exists()){
            localFile.mkdir();
        }
        localFile = new File(localFile,fileName);
        if(!localFile.exists()){
            try {
                localFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        L.debug("写入文本"+value);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(localFile);
            fos.write(value.getBytes("UTF-8"));
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    private static String getFileData(String fileName){

        File localFile = new File(Environment.getExternalStorageDirectory()+FILE_PATH_XPOSR,fileName);
        if(!localFile.exists()){
            try {
                localFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        BufferedReader reader = null;
        String result = "";
        try {
            reader = new BufferedReader(new FileReader(localFile));
            result = reader.readLine();
            if(result == null)
                return "";
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(reader != null)
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

        return result;
    }
}

上面的功能就能实现某些该数据神器的功能,只要摸清大致的思路,想要修改什么数据都能依瓢画葫芦出来,数据来源什么的大家就自己想办法了,希望能起到帮助!!!

这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值