admin管理员组

文章数量:1570743

背景:之前遇到有项目需要在恢复出厂设置之后,wifi能保持之前的状态,用户不需要重新输入密码,就可以连接上以前的热点。

对于recovery来说,有两种1、只清除data分区;2、清除data分区和cache分区。wifi状态,密码都是保存在data分区的,所以回复出厂后便会被清除掉。

要实现这个功能,修改及思路也比较简单,如下:

备份wifi状态->恢复出厂->还原wifi状态

恢复出厂是在recovery中控制的,这个我们就不修改了。

1、备份wifi状态

备份wifi状态选择在RecoverySystem类中去做,目录:frameworks/base/core/java/android/os/RecoverySystem.java

补丁如下:

private static void bootCommand(Context context, String arg, Boolean update) throws IOException {

+ if(SystemProperties.getBoolean("persist.wifi.restore_enable",false) && !update && WIFI_SUPPLICANT_FILE.exists()){

+ Log.d(TAG, "recovery: Wi-Fi backup!!!");

+ WIFI_DIR.mkdirs(); // In case we need it

+ WIFI_STATE_FILE.delete(); // In case it's not writable

+ WIFI_SUPPLICANT_BACKUP_FILE.delete(); // In case it's not writable

+ backupWifiSupplicantTemplate();

+ backupWifiState(context);

+ }

+ //

RECOVERY_DIR.mkdirs(); // In case we need it

COMMAND_FILE.delete(); // In case it's not writable

LOG_FILE.delete();

@@ -665,5 +682,42 @@

return log;

}

+ private static File WIFI_SUPPLICANT_FILE = new File("/data/misc/wifi/wpa_supplicant.conf");

+ private static File WIFI_DIR = new File("/backup/wifi");

+ private static File WIFI_STATE_FILE = new File(WIFI_DIR,"wifistate.conf");

+ private static File WIFI_SUPPLICANT_BACKUP_FILE = new File(WIFI_DIR,"wpa_supplicant.conf");

+

+ private static void backupWifiSupplicantTemplate() {

+ try {

+ BufferedReader br = new BufferedReader(new FileReader(WIFI_SUPPLICANT_FILE));

+ BufferedWriter bw = new BufferedWriter(new FileWriter(WIFI_SUPPLICANT_BACKUP_FILE));

+

+ char[] temp = new char[1024];

+ int size;

+ while ((size = br.read(temp)) > 0) {

+ bw.write(temp, 0, size);

+ }

+ br.close();

+ bw.close();

+ } catch (Exception e) {

+ Log.e(TAG, "backupWifiSupplicantTemplate error" );

+ }

+ }

+

+ private static void backupWifiState(Context context) {

+ try{

+ final ContentResolver cr = context.getContentResolver();

+ int wifistate = Settings.Global.getInt(cr, Settings.Global.WIFI_ON);

+

+ FileWriter file = new FileWriter(WIFI_STATE_FILE);

+ file.write(String.valueOf(wifistate));

+ file.close();

+ }

+ catch (Exception e) {

+ Log.e(TAG, "backupWifiState error" );

+ }

+ }

+ //

private void RecoverySystem() { } // Do not instantiate

}

基本的流程就是在RecoverySystem增加对wifi状态的备份,备份两个东西:

1)wifi的ssid密码等信息。存放在/data/misc/wifi/wpa_supplicant.conf文件中的,wpa_supplicant会根据文件中的信息去进行wifi的连接。如果恢复出厂后没有该文件的话,会将system/etc/wifi/下的文件拷贝过去。

private static void backupWifiSupplicantTemplate() 对此过程实现。

2)wifi状态的开关。存放在数据库中Settings.Global.WIFI_ON字段。该字段如果是开着的话,开机会自动去连接wifi,framework有一整套wifi状态机来控制。

private static void backupWifiState(Context context)对此过程实现。

2、还原wifi状态

还原wifi状态选择在SystemServer 中去处理,选择在wifiservice初始化之前。目录:frameworks/base/services/java/com/android/server/SystemServer.java

补丁如下:

+ private static File WIFI_SUPPLICANT_FILE = new File("/data/misc/wifi/wpa_supplicant.conf");

+ private static File WIFI_DIR = new File("/backup/wifi");

+ private static File WIFI_STATE_FILE = new File(WIFI_DIR,"wifistate.conf");

+ private static File WIFI_SUPPLICANT_BACKUP_FILE = new File(WIFI_DIR,"wpa_supplicant.conf");

+

+ private void restoreWifi(){

+ try {

+ //cp "/backup/wifi/wpa_supplicant.conf" to "/data/misc/wifi/wpa_supplicant.conf"

+ BufferedReader br = new BufferedReader(new FileReader(WIFI_SUPPLICANT_BACKUP_FILE));

+ BufferedWriter bw = new BufferedWriter(new FileWriter(WIFI_SUPPLICANT_FILE));

+

+ char[] temp = new char[1024];

+ int size;

+ while ((size = br.read(temp)) > 0) {

+ bw.write(temp, 0, size);

+ }

+ br.close();

+ bw.close();

+ if(WIFI_SUPPLICANT_FILE.exists()){

+ Process p = Runtime.getRuntime().exec("chmod 644 /data/misc/wifi/wpa_supplicant.conf");

+ p.waitFor();

+ }

+

+ //put wifi_on to setting.db

+ br = new BufferedReader(new FileReader(WIFI_STATE_FILE));

+ String str = br.readLine();

+ br.close();

+ if(mContentResolver != null){

+ Settings.Global.putInt(mContentResolver, Settings.Global.WIFI_ON, Integer.parseInt(str));

+ }

+

+ //"rm -rf backup/wifi/"

+ if(WIFI_DIR.exists()){

+ Process p = Runtime.getRuntime().exec("rm -rf backup/wifi/");

+ p.waitFor();

+ }

+ } catch (Exception e) {

+ Log.e(TAG, "restoreWifi error" );

+ }

+ }

+ //

void reportWtf(String msg, Throwable e) {

Slog.w(TAG, "***********************************************");

Log.wtf(TAG, "BOOT FAILURE " + msg, e);

@@ -605,6 +655,13 @@

}

try {

+ if(firstBoot && WIFI_SUPPLICANT_BACKUP_FILE.exists()){

+ Slog.i(TAG, "firstBoot: Wi-Fi restore!!!");

+ restoreWifi();

+ WIFI_DIR.delete();

+ }

+ //end

Slog.i(TAG, "Wi-Fi Service");

wifi = new WifiService(context);

ServiceManager.addService(Context.WIFI_SERVICE, wifi);

和备份的流程差不多,就是将备份的wpa_supplicant.conf文件拷贝到/data/misc/wifi/wpa_supplicant.conf,权限改为644。把Settings.Global.WIFI_ON的状态重新写回数据库即可,也没什么好说的。这样在初始化wifiservice的时候,就会根据之前保存的状态进行wifi的连接了。

本文标签: 备份状态androidwifi