今天要说的是为Android设备添加重启、飞行模式、静音模式按钮,客户需求中需要添加这项功能,在长按电源键弹出的菜单中没有这些选项,谨以此文记录自己添加这个功能的过程。
首先找到长按电源键弹出的对话框,在frameworks\base\policy\src\com\android\internal\policy\impl\GlobalActions.java文件中,修改createDialog()方法。
/**
* Create the global actions dialog.
* @return A new dialog.
*/
private AlertDialog createDialog() {
// Simple toggle style if there's no vibrator, otherwise use a tri-state
if (!mHasVibrator) {
mSilentModeAction = new SilentModeToggleAction();
} else {
mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
}
mAirplaneModeOn = new ToggleAction(
R.drawable.ic_lock_airplane_mode,
R.drawable.ic_lock_airplane_mode_off,
R.string.global_actions_toggle_airplane_mode,
R.string.global_actions_airplane_mode_on_status,
R.string.global_actions_airplane_mode_off_status) { void onToggle(boolean on) {
if (mHasTelephony && Boolean.parseBoolean(
SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
mIsWaitingForEcmExit = true;
// Launch ECM exit dialog
Intent ecmDialogIntent =
new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);
ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(ecmDialogIntent);
} else {
changeAirplaneModeSystemSetting(on);
}
} @Override
protected void changeStateFromPress(boolean buttonOn) {
if (!mHasTelephony) return; // In ECM mode airplane state cannot be changed
if (!(Boolean.parseBoolean(
SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
mState = buttonOn ? State.TurningOn : State.TurningOff;
mAirplaneState = mState;
}
} public boolean showDuringKeyguard() {
return true;
} public boolean showBeforeProvisioning() {
return false;
}
};
onAirplaneModeChanged(); mItems = new ArrayList<Action>(); // first: power off
mItems.add(
new SinglePressAction(
com.android.internal.R.drawable.ic_lock_power_off,
R.string.global_action_power_off) { public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
mWindowManagerFuncs.shutdown();
} public boolean onLongPress() {
mWindowManagerFuncs.rebootSafeMode();
return true;
} public boolean showDuringKeyguard() {
return true;
} public boolean showBeforeProvisioning() {
return true;
}
}); //edited by ouyang started
// next: reboot
mItems.add(
new SinglePressAction(
com.android.internal.R.drawable.ic_lock_power_off,
R.string.global_action_reboot) { public void onPress() {
//reboot
mWindowManagerFuncs.reboot(true);
} public boolean onLongPress() {
mWindowManagerFuncs.rebootSafeMode();
return true;
} public boolean showDuringKeyguard() {
return true;
} public boolean showBeforeProvisioning() {
return true;
}
});
//edited by ouyang ended // next: airplane mode
mItems.add(mAirplaneModeOn); // last: silent mode
if (SHOW_SILENT_TOGGLE) {
mItems.add(mSilentModeAction);
} //edited by ouyang ended
List<UserInfo> users = mContext.getPackageManager().getUsers();
if (users.size() > 1) {
UserInfo currentUser;
try {
currentUser = ActivityManagerNative.getDefault().getCurrentUser();
} catch (RemoteException re) {
currentUser = null;
}
for (final UserInfo user : users) {
boolean isCurrentUser = currentUser == null
? user.id == 0 : (currentUser.id == user.id);
SinglePressAction switchToUser = new SinglePressAction(
com.android.internal.R.drawable.ic_menu_cc,
(user.name != null ? user.name : "Primary")
+ (isCurrentUser ? " \u2714" : "")) {
public void onPress() {
try {
ActivityManagerNative.getDefault().switchUser(user.id);
getWindowManager().lockNow();
} catch (RemoteException re) {
Log.e(TAG, "Couldn't switch user " + re);
}
} public boolean showDuringKeyguard() {
return true;
} public boolean showBeforeProvisioning() {
return false;
}
};
mItems.add(switchToUser);
}
} mAdapter = new MyAdapter(); final AlertDialog.Builder ab = new AlertDialog.Builder(mContext); ab.setAdapter(mAdapter, this)
.setInverseBackgroundForced(true); final AlertDialog dialog = ab.create();
dialog.getListView().setItemsCanFocus(true);
dialog.getListView().setLongClickable(true);
dialog.getListView().setOnItemLongClickListener(
new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
long id) {
return mAdapter.getItem(position).onLongPress();
}
});
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); dialog.setOnDismissListener(this); return dialog;
}
public interface WindowManagerFuncs {
public static final int LID_ABSENT = -1;
public static final int LID_CLOSED = 0;
public static final int LID_OPEN = 1; /**
* Ask the window manager to re-evaluate the system UI flags.
*/
public void reevaluateStatusBarVisibility(); /**
* Add a fake window to the window manager. This window sits
* at the top of the other windows and consumes events.
*/
public FakeWindow addFakeWindow(Looper looper,
InputEventReceiver.Factory inputEventReceiverFactory,
String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
boolean hasFocus, boolean touchFullscreen); /**
* Returns a code that describes the current state of the lid switch.
*/
public int getLidState(); /**
* Creates an input channel that will receive all input from the input dispatcher.
*/
public InputChannel monitorInput(String name); /**
* Switch the keyboard layout for the given device.
* Direction should be +1 or -1 to go to the next or previous keyboard layout.
*/
public void switchKeyboardLayout(int deviceId, int direction); public void shutdown();
public void rebootSafeMode();
//edited by ouyang
public void reboot(boolean confirm);
}
添加reboot方法。但这只是添加接口而已,它的具体实现在呢?找了许久在frameworks\base\services\java\com\android\server\wm\windowManagerService.java中找到了这个接口的实现。
// Called by window manager policy. Not exposed externally.
@Override
public void shutdown() {
ShutdownThread.shutdown(mContext, true);
}
//edited by ouyang start
public void reboot(boolean confirm){
ShutdownThread.reboot(mContext,null,confirm);
}
//edited by ouyang end
/**
* Request a clean shutdown, waiting for subsystems to clean up their
* state etc. Must be called from a Looper thread in which its UI
* is shown.
*
* @param context Context used to display the shutdown progress dialog.
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
* @param confirm true if user confirmation is needed before shutting down.
*/
public static void reboot(final Context context, String reason, boolean confirm) {
mReboot = true;
mRebootSafeMode = false;
mRebootReason = reason;
shutdownInner(context, confirm);
}
修改shutdownInner方法
static void shutdownInner(final Context context, boolean confirm) {
// ensure that only one thread is trying to power down.
// any additional calls are just returned
synchronized (sIsStartedGuard) {
if (sIsStarted) {
Log.d(TAG, "Request to shutdown already running, returning.");
return;
}
} final int longPressBehavior = context.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnPowerBehavior);
//edited by ouyang started
final int resourceId =mReboot
?com.android.internal.R.string.reboot_confirm
:(mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_confirm
: (longPressBehavior == 2
? com.android.internal.R.string.shutdown_confirm_question
: com.android.internal.R.string.shutdown_confirm));
//edited by ouyang ended /**
//resource code
final int resourceId = mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_confirm
: (longPressBehavior == 2
? com.android.internal.R.string.shutdown_confirm_question
: com.android.internal.R.string.shutdown_confirm);
*/
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior); if (confirm) {
final CloseDialogReceiver closer = new CloseDialogReceiver(context);
final AlertDialog dialog = new AlertDialog.Builder(context)
/*
//source code
.setTitle(mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_title
: com.android.internal.R.string.power_off)
.setMessage(resourceId)
*/
//edited by ouyang started
.setTitle(mReboot
?com.android.internal.R.string.global_action_reboot
:(mRebootSafeMode
? com.android.internal.R.string.reboot_safemode_title
: com.android.internal.R.string.power_off))
.setMessage(resourceId)
//edited by ouyang ended .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
beginShutdownSequence(context);
}
})
.setNegativeButton(com.android.internal.R.string.no, null)
.create();
closer.dialog = dialog;
dialog.setOnDismissListener(closer);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
dialog.show();
} else {
beginShutdownSequence(context);
}
}
<!--edited by ouyang started-->
<string name="global_action_reboot">Reboot</string>
<string name="reboot_confirm">Do you want to reboot your device?</string>
<!--edited by ouyang started-->
frameworks\base\core\res\res\values-zh-rCN\strings.xml
<!--edited by ouyang started-->
<string name="global_action_reboot">重启</string>
<string name="reboot_confirm">您要重新启动您的设备吗?</string>
<!--edited by ouyang started-->
现在已经添加了好这些资源,但是现在还不能使用,此时编译会出现找不到该资源的错误,还需要在frameworks\base\core\res\res\values\public.xml文件中进行资源声明:
<java-symbol type="string" name="global_action_reboot" />
<java-symbol type="string" name="reboot_confirm" />
最后重新编译即可
==================================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================
Android系统移植与调试之------->如何修改Android设备添加重启、飞行模式、静音模式等功能(二)的更多相关文章
-
Android系统移植与调试之------->如何修改Android系统默认显示【开发者选项】并默认打开【USB调试】和【未知来源】开关
今天有个用户对[设置]有个特殊的要求,即: 1.开机的时候默认显示[开发者选项]并打开[USB调试]开关 ([Developer options]-->[USB debugging]) 2 ...
-
Android系统移植与调试之------->如何修改Android手机显示的4G信号强度的格子数
在修改显示的信号强度之前,先了解一下什么是dB,什么是dBm? 1.dB dB是一个表征相对值的值,纯粹的比值,只表示两个量的相对大小关系,没有单位,当考虑甲的功率相比于乙功率大或小多少个dB时, 按 ...
-
Android系统移植与调试之------->如何修改Android自带的apk出现一圈圈类似鸡蛋的花纹
最近被一个问题烦恼到了,就是android4.1系统自带的Email.文件管理器.信息等apk都出现同一个问题,就是现实在平板上的时候会出现一圈圈类似鸡蛋的花纹. 我想了两种方法来解决,第一种方法没有 ...
-
Android系统移植与调试之------->如何修改Android手机NFC模块,使黑屏时候能够使用NFC
我们都知道在不修改源代码的情况下,只能是解锁之后才能使用NFC功能.而在锁屏和黑屏2个状态下是没办法用NFC的,但是最近有个客户要求手机在黑屏状态下能够使用NFC,因此我们需要去修改Android源代 ...
-
Android系统移植与调试之------->如何修改Android设备存储盘符名称与Android设备的型号
一.修改Android设备存储盘符名称 (注:TBDG1073为我的项目名称) 1.修改device/other/TBDG1073/system.prop 文件 2.修改ro.media.patiti ...
-
[置顶] Android系统移植与调试之------->;如何修改Android设备状态条上音量加减键在横竖屏的时候的切换与显示
这两天由于一个客户的要求,将MID竖屏时候的状态条上的音量键去掉.所以尝试修改了一下,成功了,分享一下经验. 先看一下修改后的效果图,如下所示 . 横屏的时候:有音量加减键 竖屏的时候:音量加减键被去 ...
-
Android系统移植与调试之------->如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
这两天由于一个客户的要求,将MID竖屏时候的状态条上的音量键去掉.所以尝试修改了一下,成功了,分享一下经验. 先看一下修改后的效果图,如下所示 . 横屏的时候:有音量加减键 竖屏的时候:音量加减键被去 ...
-
Android系统移植与调试之------->如何修改Android默认字体大小和设置里面字体大小比例
因为我修改 ro.sf.lcd_density的值,将它从160修改 为120,所以导致整个系统的字体都变得很小.因此需要将整个字体变大,并且在设置-->显示-->字体大小的4个选项的值都 ...
-
[置顶] Android系统移植与调试之------->;如何修改Android设备添加3G上网功能
1.首先先来看一下修改前后的效果对比图 step1.插上3G设备前 step2.插上3G设备后,获取信号中.... step3.插上3G设备后,获取到信号 step4.使用3G信号浏览网页 2.下面讲 ...
随机推荐
-
PHP操作Mongodb之增删改查篇
之前,我讲解过PHP中mongodb扩展的安装,及启动,链接操作[忘记了?去看看吧!PHP操作Mongodb之一].本文主要就是讲在PHP中Mongodb的增加,查询,修改及删除数据的操作. 1.增加 ...
-
HDU 5228
#include<stdio.h> #include<string.h> *]; int main(){ int t; scanf("%d",&t) ...
-
Xcode中使用GitHub详解
为了熟悉git命令及将写的小Demo能够管理起来方便日后查询,所以选择使用GitHub. 现在我们来说说Xcode中如何使用GitHub--- 一.当然是要先有GitHub帐号并登录了(没有的注册一个 ...
-
getopt(分析命令行参数)
ref:http://vopit.blog.51cto.com/2400931/440453 相关函数表头文件 #include<unistd.h>定义函数 ...
-
深入理解ES6之—数据解构
一 对象解构 对象解构语法在赋值语句的左侧使用了对象字面量 let node = { type: true, name: false } //既声明又赋值 let { type, name } = n ...
-
Python基础练习题100例(Python 3.x)
1:题目:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 程序源 ...
-
linux下tomcat启动很慢的解决办法
1.用vim编辑器打开tomcat的bin目录下的catalina.sh [root@iz09a32x1sghz3z bin]# vi /usr/local/src/java/tomcats/tomc ...
-
YARN简述
YARN(Yet Another Resource Negotiator)是Hadoop的集群资源管理系统.YARN提供请求和使用集群资源的API,但这些API很少直接用于用户代码.相反,用户代码中用 ...
-
Java 字符串拼接四种方式的性能比较分析
一.简单介绍 编写代码过程中,使用"+"和"contact"比较普遍,但是它们都不能满足大数据量的处理,一般情况下有一下四种方法处理字符串拼接,如下: 1. 加 ...
-
TerraGate软件安装后,不能启动的解决办法
在服务端安装Skyline的TerraGate软件的时候,大家可能会遇到过这样的问题,“TerraGate软件安装后,不能启动”,很多时候,这个问题是因为TerraGate设 置的端口号已经被占用造成 ...