Android 调用手势服务设置:两次打开相机,五次打开紧急拨号

frameworks/base/services/core/java/com/android/server/GestureLauncherService.java

@VisibleForTesting

static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;

@VisibleForTesting

static final long POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS = 500;

/**

* Number of taps required to launch emergency gesture ui.

*/

private static final int EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD = 5;

/**

* Number of taps required to launch camera shortcut.

*/
private static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;
public boolean interceptPowerKeyDown (KeyEvent event, boolean interactive,

MutableBoolean outLaunched) {

if (event.isLongPress()) {

// Long presses are sent as a second key down. If the long press threshold is set lower

// than the double tap of sequence interval thresholds, this could cause false double

// taps or consecutive taps, so we want to ignore the long press event.

return false;

}

boolean launchCamera = false;
boolean launchEmergencyGesture = false;
boolean intercept = false;
long powerTapInterval;

synchronized (this) {

powerTapInterval = event.getEventTime() - mLastPowerDown;

mLastPowerDown = event.getEventTime();

if (powerTapInterval >= POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {//500ms

// Tap too slow, reset consecutive tap counts.

mPowerButtonConsecutiveTaps = 1;

mPowerButtonSlowConsecutiveTaps = 1;

} else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {//300ms

// Tap too slow for shortcuts

mPowerButtonConsecutiveTaps = 1;

mPowerButtonSlowConsecutiveTaps++;

} else {

// Fast consecutive tap

mPowerButtonConsecutiveTaps++;

mPowerButtonSlowConsecutiveTaps++;

}

// Check if we need to launch camera or emergency gesture flows

if (mEmergencyGestureEnabled) {

// Commit to intercepting the powerkey event after the second "quick" tap to avoid

// lockscreen changes between launching camera and the emergency gesture flow.

if (mPowerButtonConsecutiveTaps > 1) {

intercept = interactive;

}

if (mPowerButtonConsecutiveTaps == EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD) {//5 times
launchEmergencyGesture = true;
}

}

if (mCameraDoubleTapPowerEnabled
&& powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS
&& mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD) {//2 times
launchCamera = true;
intercept = interactive;
}

}

if (mPowerButtonConsecutiveTaps > 1 || mPowerButtonSlowConsecutiveTaps > 1) {

Slog.i(TAG, Long.valueOf(mPowerButtonConsecutiveTaps)

  • " consecutive power button taps detected, "

  • Long.valueOf(mPowerButtonSlowConsecutiveTaps)

  • " consecutive slow power button taps detected");

}

if (launchCamera ) {//打开相机

launchCamera = handleCameraGesture(false /* useWakelock */,
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);

} else if (launchEmergencyGesture ) {//打开紧急拨号

launchEmergencyGesture = handleEmergencyGesture();

}

outLaunched.value = launchCamera || launchEmergencyGesture;
return intercept && isUserSetupComplete();
}

/**

* @return true if camera was launched, false otherwise.处理相机

*/

@VisibleForTesting

boolean handleCameraGesture (boolean useWakelock, int source) {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handleCameraGesture");

try {

boolean userSetupComplete = isUserSetupComplete ();

if (!userSetupComplete) {

if (DBG) {

Slog.d(TAG, String.format(

"userSetupComplete = %s, ignoring camera gesture.",

userSetupComplete));

}

return false;

}

if (DBG) {

Slog.d(TAG, String.format(

"userSetupComplete = %s, performing camera gesture.",

userSetupComplete));

}

if (useWakelock) {

// Make sure we don't sleep too early

mWakeLock.acquire(500L);

}

StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onCameraLaunchGestureDetected(source);

return true;

} finally {

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

}

}

/**

* @return true if emergency gesture UI was launched, false otherwise.处理紧急拨号

*/

@VisibleForTesting

boolean handleEmergencyGesture () {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,

"GestureLauncher:handleEmergencyGesture");

try {

boolean userSetupComplete = isUserSetupComplete ();

if (!userSetupComplete) {

if (DBG) {

Slog.d(TAG, String.format(

"userSetupComplete = %s, ignoring emergency gesture.",

userSetupComplete));

}

return false;

}

if (DBG) {

Slog.d(TAG, String.format(

"userSetupComplete = %s, performing emergency gesture.",

userSetupComplete));

}

StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onEmergencyActionLaunchGestureDetected();

return true;

} finally {

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

}

}

private boolean isUserSetupComplete () {

return Settings.Secure.getIntForUser(mContext.getContentResolver(),

Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;

}

如果想要实现其他按键的紧急拨号?可以在此接受注册广播并处理

@Override

public void onBootPhase(int phase) {

if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {

Resources resources = mContext.getResources();

if (!isGestureLauncherEnabled(resources)) {

if (DBG) Slog.d(TAG, "Gesture launcher is disabled in system properties.");

return;

}

mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);

mPowerManager = (PowerManager) mContext.getSystemService(

Context.POWER_SERVICE);

mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,

"GestureLauncherService");

updateCameraRegistered();

updateCameraDoubleTapPowerEnabled();

updateEmergencyGestureEnabled();

mUserId = ActivityManager.getCurrentUser();

mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED));

//*/ add SOS for Emergency Number
mContext.registerReceiver(mUserReceiver, new IntentFilter("adnroid.intent.action.sos"));
//*/

registerContentObservers();

}

}

private final BroadcastReceiver mUserReceiver= new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {

mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);

mContext.getContentResolver().unregisterContentObserver(mSettingObserver);

registerContentObservers();

updateCameraRegistered();

updateCameraDoubleTapPowerEnabled();

updateEmergencyGestureEnabled();

}

//*/add sos onEmergencyActionLaunchGestureDetected
else if (intent.getAction().equals("adnroid.intent.action.sos")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"GestureLauncher:handleEmergencyGesture");
try {
boolean userSetupComplete = isUserSetupComplete();
if (!userSetupComplete) {
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, ignoring emergency gesture.",
userSetupComplete));
}
}
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, performing emergency gesture.",
userSetupComplete));
}
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onEmergencyActionLaunchGestureDetected();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
//*/

}

};

其他触发广播的地方,只需在PhoneWindowManager里面拦截方法下添加对应的按键添加短按或长按的广播发送即可!!!

private void sendBC(String action){

Intent intent = new Intent();
intent.setAction(action);
android.util.Log.d("PWM","===== sendBC ===== "+action);
mContext.sendBroadcast(intent);

}

sendBC("adnroid.intent.action.sos");

完结撒花!

相关推荐
Crossoads2 分钟前
【汇编语言】call 和 ret 指令(一) —— 探讨汇编中的ret和retf指令以及call指令及其多种转移方式
android·开发语言·javascript·汇编·人工智能·数据挖掘·c#
十五年专注C++开发2 分钟前
C++不完整类型(Incomplete Type)的检测与避免
开发语言·c++·算法·设计模式
风掣长空7 分钟前
C++11————线程库
开发语言·c++
eternal19959 分钟前
优化算法|基于Deep-Q-Network(DQN)的邻域搜索算法求解分布式柔性作业车间调度问题
分布式·算法
心死翼未伤12 分钟前
python从入门到精通:pyspark实战分析
开发语言·数据结构·python·spark·json
码农飞飞1 小时前
详解Rust结构体struct用法
开发语言·数据结构·后端·rust·成员函数·方法·结构体
《源码好优多》2 小时前
基于Java Springboot出租车管理网站
java·开发语言·spring boot
清流君2 小时前
【运动规划】移动机器人运动规划与轨迹优化全解析 | 经典算法总结
人工智能·笔记·算法·机器人·自动驾驶·运动规划
wang_changyue2 小时前
CSP-X2024解题报告(T3)
数据结构·算法·leetcode
因特麦克斯2 小时前
每日一题&移动语义
算法