Sony LT25C电源键没有重启,只有关机,有时候用起来很不方便,于是做了这个Widget,点击之后弹出对话框,确认是否要重启,不过前提是手机必须要Root过才行。
一.在Eclipse中创建一个rebootwidget的工程,默认是一个Activity。在res/layout目录下创建一个widget属性的描述文件reboot_widget_layout.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="34dp"
android:minHeight="34dp"
android:updatePeriodMillis="0"
android:initialLayout="@layout/reboot_widget_activity">
</appwidget-provider>
android:minWidth和android:minHeight是Widget占据桌面的单元格数,(单元个数*74)-2。由于像素计算会造成一定的偏差,所以最后值减2。另,屏幕最大单元格数位4*4。
android:updatePeriodMillis表示每隔多少ms就调用onUpdate方法。
android:initialLayout表示在桌面显示的Widget的布局。
二.修改reboot_widget_activity.xml内容如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/reboot_btn"
style="@android:style/Widget.Holo.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reoot_str"
android:textColor="@android:color/holo_green_light"
/>
</RelativeLayout>
这样在桌面的Widget就只显示一个Button
三.创建一个Activity,当点击桌面Widget的Button时,就运行这个Activity,显示一个确认重启的对话框。Activity的xml代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".RebootActivity" >
</RelativeLayout>
四.修改工程的RebootWidget.java,让它继承自AppWidgetProvider,并重写onUpdate方法。
public class RebootWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
Intent intent_ = new Intent(context, RebootActivity.class);
PendingIntent pendingIntent_ = PendingIntent.getActivity(context, 0, intent_, 0);
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.reboot_widget_activity);
remoteView.setOnClickPendingIntent(R.id.reboot_btn, pendingIntent_);
AppWidgetManager awg = AppWidgetManager.getInstance(context);
awg.updateAppWidget(appWidgetIds, remoteView);
}
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
}
}
关于BroadcastReceiver说明如下:The AppWidgetProvider class extends BroadcastReceiver as a convenience class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts that are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled.所以Widget必须继承自它,触发它的就是广播消息。
PendingIntent主要用来在某个事件完成后执行特定的Action。PendingIntent包含了Intent及Context,所以就算Intent所属程序结束,PendingIntent依然有效,可以在其他程序中使用。RemoteViews是在其他的进程显示其他layout指定的view,这里是给button用PendingIntent添加点击事件。使用AppWidgetManager表示更新当前的Widget。
四.在重启的Activity中添加对话框和重启的代码就可以了
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reboot);
AlertDialog.Builder builder = new Builder(RebootActivity.this);
builder.setMessage("确认重启吗?");
builder.setTitle("鑫");
builder.setPositiveButton("确认", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
PowerManager pManager=(PowerManager) getSystemService(Context.POWER_SERVICE);
pManager.reboot("重启");
}
});
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
finish();
}
});
builder.create().show();
}
五.最后在AndroidManifest中添加权限和修改Widget相关信息:
Widget继承BroadcastReceiver,所以要修改为
<receiver
android:name="com.ericdm.rebootwidget.RebootWidget"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@layout/reboot_widget_layout" />
</receiver>
重启要添加权限
<uses-permission android:name="android.permission.REBOOT"/>
adb push SecureSetting.apk /sdcard/ // 上传要安装的文件,为安装做准备。
adb shell
su // 切换到 root 用户。如果没有获得 Root 权限,这一步不会成功。
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system // 让分区可写。
cat /sdcard/SecureSetting.apk > /system/app/SecureSetting.apk // 这一步可以用 cp 实现,但一般设备中没有包含该命令。如果使用 mv 会出现错误:failed on '/sdcard/NetWork.apk' - Cross-device link。
mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system // 还原分区属性,只读。
exit
exit
如果在手机上安装RE管理器,也可以通过RE管理器完成相应的操作。
所有工作到这里就完了,应该没什么问题。