最近在做行车记录仪的事情,由于车载设备上的锂电池容量比较小,所以在停车熄火,保存数据后需要自动关机,由于Shutdown的权限不对普通应用开放,所以需要在源码下编译代码。可以自己写个BroadcastReceiver放到Setting源码里,也可以是独立应用。
manifest节点需要声明系统级uid:
android:sharedUserId="android.uid.system"
以及关机权限:
<uses-permission android:name="android.permission.SHUTDOWN"/>
以上这两点在Setting的AndroidManifest里都有,所以就不用我们手动添加了。
然后我在Application里声明了两个全局变量,用来存储当前的电源状态和已经断开电源的秒数:
/**
* 电源是否连接
*/
public static boolean isPowerConnect = true;
/**
* 电源断开的秒数
*/
public static int OffSecond = 0;
接着就是PowerStateChangeReceiver:
package com.android.settings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;
public class PowerStateChangeReceiver extends BroadcastReceiver {
private Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
Screenshot.OffSecond = 0;
if ("android.intent.action.ACTION_POWER_CONNECTED".equals(intent
.getAction())) {
Screenshot.isPowerConnect = true;
} else if ("android.intent.action.ACTION_POWER_DISCONNECTED"
.equals(intent.getAction())) {
Screenshot.isPowerConnect = false;
new Thread(new shutdownThread()).start();
}
}
/**
* Shutdown
*
* @param context
*/
public void shutdown(Context context) {
try {
Intent intent = new Intent(
"android.intent.action.ACTION_REQUEST_SHUTDOWN");
intent.putExtra("android.intent.extra.KEY_CONFIRM", false);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Exception e) {
}
Toast.makeText(context, context.getResources().getString(R.string.shutdown_now), Toast.LENGTH_SHORT).show();
}
public class shutdownThread implements Runnable {
@Override
public void run() {
synchronized (shutdownHandler) {
while (!Screenshot.isPowerConnect) {
try {
Thread.sleep(1000);
Message message = new Message();
message.what = 1;
shutdownHandler.sendMessage(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
final Handler shutdownHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
if (!Screenshot.isPowerConnect) {
Screenshot.OffSecond++;
} else {
Screenshot.OffSecond = 0;
}
if (Screenshot.OffSecond == 10
&& !Screenshot.isPowerConnect) {
shutdown(context);
}
break;
default:
break;
}
}
};
}
另外是在setting的AndroidManifest.xml对reveiver的声明:
<receiver android:name=".PowerStateChangeReceiver" >
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
intent-filter>
receiver>
okay,大功告成。