恢复出厂设置会发出android.intent.action.MASTER_CLEAR广播,发现最终在
\frameworks\base\services\core\java\com\android\server\MasterClearReceiver.java中实现。直接上代码。
1.添加private static final String MASTERCLEAR_TIMES_FILE = "/data/nvram/APCFG/APRDEB/MASTERCLEAR_TIMES";
2.在onReceive()中,如下位置添加:
// The reboot call is blocking, so we need to do it on another thread.
Thread thr = new Thread("Reboot") {
@Override
public void run() {
try {
int masterClearTimes = readNVRam(MASTERCLEAR_TIMES_FILE); //add line
masterClearTimes++; //add line
writeToNVRam(MASTERCLEAR_TIMES_FILE, masterClearTimes); //add line
Slog.d(TAG, "Call mtehod: rebootWipeUserData");
RecoverySystem.rebootWipeUserData(context, shutdown, reason);
Slog.e(TAG, "Still running after master clear?!");
} catch (IOException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
} catch (SecurityException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
}
}
};
以上方法实现:
//向nvram中写数据
private boolean writeToNVRam(String file, int data) {
IBinder binder = ServiceManager.getService("NvRAMAgent");
NvRAMAgent agent = NvRAMAgent.Stub.asInterface(binder);
byte[] buff = new byte[512];// { 0x00, 0x00, 0x00, 0x00 };
byte[] by = getBytes(data);
for (int i = 0; i < 4; i++) {
buff[i] = by[i];
}
try {
int flag = agent.writeFileByName(file, buff);
if (flag > 0) {
Log.d(TAG, "write to nvram success!");
return true;
} else {
Log.d(TAG, "write to nvram failed!");
return false;
}
} catch (RemoteException e) {
Log.d(TAG, "write to nvram failed! RemoteException!");
e.printStackTrace();
}
return false;
}
//从nvram中读取数据
private int readNVRam(String file) {
IBinder binder = ServiceManager.getService("NvRAMAgent");
NvRAMAgent agent = NvRAMAgent.Stub.asInterface(binder);
byte[] buff = null;
try {
// read buffer from nvram
// buff = agent.readFile(file_lid);
buff = agent.readFileByName(file);
} catch (RemoteException e) {
e.printStackTrace();
}
//for (int i = 0; i < buff.length; i++) {
// Log.d(TAG, "buff["+ i +"]:" + buff[i]);
//}
int result = byte2int(buff);
Log.d(TAG, "readNVRam result:" + result);
return result;
}
//将int型转化成byte数组
private byte[] getBytes(int data){
byte[] bytes = new byte[4];
bytes[0] = (byte)(data&0xff);
bytes[1] = (byte)((data&0xff00)>>8);
bytes[2] = (byte)((data&0xff0000)>>16);
bytes[3] = (byte)((data&0xff000000)>>24);
return bytes;
}
//将byte数组转换成整型
private int byte2int(byte[] res) {
int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00) | ((res[2] << 24) >>> 8) | (res[3] << 24);
return targets;
}
3.添加需要的NvRAMAgent.java
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: NvRAMAgent.aidl
*/
package com.android.server;
import java.lang.String;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Binder;
import android.os.Parcel;
public interface NvRAMAgent extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements NvRAMAgent
{
private static final java.lang.String DESCRIPTOR = "NvRAMAgent";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an NvRAMAgent interface,
* generating a proxy if needed.
*/
public static NvRAMAgent asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof NvRAMAgent))) {
return ((NvRAMAgent)iin);
}
return new NvRAMAgent.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_readFile:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
byte[] _result = this.readFile(_arg0);
reply.writeNoException();
reply.writeByteArray(_result);
return true;
}
case TRANSACTION_writeFile:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
byte[] _arg1;
_arg1 = data.createByteArray();
int _result = this.writeFile(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_readFileByName:
{
data.enforceInterface(DESCRIPTOR);
System.out.println("NVRAM TRANSACTION_readFile="+data.readString());
String _arg0;
_arg0 = data.readString();
byte[] _result = this.readFileByName(_arg0);
reply.writeNoException();
reply.writeByteArray(_result);
return true;
}
case TRANSACTION_writeFileByName:
{
data.enforceInterface(DESCRIPTOR);
String _arg0;
_arg0 = data.readString();
System.out.println("NVRAM TRANSACTION_writeFile="+data.readString());
byte[] _arg1;
_arg1 = data.createByteArray();
int _result = this.writeFileByName(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements NvRAMAgent
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public byte[] readFile(int file_lid) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
byte[] _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(file_lid);
mRemote.transact(Stub.TRANSACTION_readFile, _data, _reply, 0);
_reply.readException();
_result = _reply.createByteArray();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public int writeFile(int file_lid, byte[] buff) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(file_lid);
_data.writeByteArray(buff);
mRemote.transact(Stub.TRANSACTION_writeFile, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public byte[] readFileByName(String filename) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
byte[] _result;
try
{
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(filename);
mRemote.transact(Stub.TRANSACTION_readFileByName, _data, _reply, 0);
_reply.readException();
_result = _reply.createByteArray();
}
finally
{
_reply.recycle();
_data.recycle();
}
return _result;
}
public int writeFileByName(String filename, byte[] buff) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
System.out.println("writeFile"+filename);
try
{
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(filename);
_data.writeByteArray(buff);
mRemote.transact(Stub.TRANSACTION_writeFileByName, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally
{
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_readFile = (IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_writeFile = (IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_readFileByName = (IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_writeFileByName = (IBinder.FIRST_CALL_TRANSACTION + 3);
}
public byte[] readFile(int file_lid) throws android.os.RemoteException;
public int writeFile(int file_lid, byte[] buff) throws android.os.RemoteException;
public byte[] readFileByName(String filename) throws android.os.RemoteException;
public int writeFileByName(String filename, byte[] buff) throws android.os.RemoteException;
}
至此,NvRam增加记录恢复出厂设置次数功能完成。如需在其他地方使用,同上述方法。