首先自己恭喜自己找到新的工作,這段時間也把自己的寫過的一些功能做個總結。
手勢快捷操作現在很多手機廠商都有做,三指截屏隻是一個例子,可以通過這個例子去實作某個操作<->某個動作。本文隻是寫個簡單的需求,後期可能自己擴充,例如像OPPO系統的上三指分屏,下三指截圖。
一:修改的檔案如下
M alps/frameworks/base/api/current.txt
M alps/frameworks/base/api/system-current.txt
M alps/frameworks/base/api/test-current.txt
M alps/frameworks/base/core/java/android/provider/Settings.java
M alps/frameworks/base/core/java/android/view/ViewGroup.java
M alps/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
M alps/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
M alps/frameworks/base/packages/SystemUI/AndroidManifest.xml
M alps/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
M alps/packages/apps/Settings/AndroidManifest.xml
A alps/packages/apps/Settings/res/drawable-xhdpi/ic_settings_three_screenshot.png
M alps/packages/apps/Settings/res/values-zh-rCN/strings.xml
M alps/packages/apps/Settings/res/values/strings.xml
M alps/packages/apps/Settings/src/com/android/settings/Settings.java
M alps/packages/apps/Settings/src/com/android/settings/SettingsActivity.java
A alps/packages/apps/Settings/src/com/android/settings/fuzhu/ThreeScreenShot.java
修改檔案分類
1)frameworks/base/
2)packages/apps/Settings/
這個部落客要記錄frameworks/base/相關的修改與實作 Settings子產品的修改可以參考我從前的部落格
Android N Settings實戰開發(1)一,二級界面增加
https://blog.csdn.net/qq_24716151/article/details/78619044
Android N Settings實戰開發(2)一級界面狀态更新
https://blog.csdn.net/qq_24716151/article/details/78675743
二:實作原理
實作原理:
1)Settings中開關控制狀态,
Settings.System.putInt(getActivity().getContentResolver(), Settings.System.SCREENSHOTPOINTER, 1);
0代表關,1代表開。
2)ViewGroup.java中的事件分發中增加parse3PointerScreenShot(ev)手勢判斷邏輯
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, );
}
parse3PointerScreenShot(ev);
Log.i("WHB11111","parse3PointerScreenShot-----PWM=");
........
}
3)parse3PointerScreenShot(ev)手勢邏輯判斷,如果符合邏輯發送截屏廣播
private void parse3PointerScreenShot(MotionEvent ev) {
int actionMasked = ev.getActionMasked();
int pointerCount = ev.getPointerCount();
//擷取Settings中是否允許三指截屏,1為允許,非1為不允許
//最好是在framework中加入
int value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SCREENSHOTPOINTER, );
Log.i("WHB11111","SCREENSHOTPOINTER="+value);
if (value != ) {
return ;
}
if (pointerCount == ) {
switch (actionMasked) {
case MotionEvent.ACTION_POINTER_DOWN:
for (int i = ; i < pointerCount; i++) {
int pointerId = ev.getPointerId(i);
downY[pointerId] = ev.getY(i);
}
is3Pointer = true;
break;
case MotionEvent.ACTION_POINTER_UP:
if (is3Pointer) {
//如果是三個手指,就擷取每個手指的滑動間距,否則就清空資料
for (int i = ; i < pointerCount; i++) {
int pointerId = ev.getPointerId(i);
upY[pointerId] = ev.getY(i);
matchY[pointerId] = Math.abs(upY[pointerId] - downY[pointerId]);
}
} else {
clearArrayData(downY);
clearArrayData(upY);
clearArrayData(matchY);
}
break;
default:
break;
}
boolean[] flag = new boolean[] {
false, false, false,
};
for (int i = ; i < pointerCount; i++) {
int pointerId = ev.getPointerId(i);
//三個手指劃過的距離是否大于最大預定值
if (matchY[pointerId] > Y_OFFSET) {
flag[i] = true;
matchY[pointerId] = ;
}
}
//如果三個指頭都劃過了最大預定值,就開始截屏
if (flag[] && flag[] && flag[]) {
Intent intent = new Intent("com.whb.screenshot");
//Send broadcast to PhoneWindowManager to cature screen
getContext().sendBroadcast(intent);
Log.d(TAG, "Intercept the key Three finger to capture screen");
}
} else {
is3Pointer = false;
}
}
4)PhoneWindowManager接收廣播實作截屏操作
注冊廣播
filter = new IntentFilter("com.whb.screenshot");
context.registerReceiver(mScreenShotReceiver, filter);
接收廣播通過調用SystemUI的截圖方法實作截圖操作
BroadcastReceiver mScreenShotReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if ("com.qucii.screenshot".equals(intent.getAction())) {
Log.i("WHB11111","begin-----SCREENSHOTPOINTER=");
mHandler.post(mScreenshotRunnable); // 調用系統代碼,執行截屏邏輯
}
}
};
如果想調用SystemUI的截圖方法,要做如下修改
--- a/alps/frameworks/base/packages/SystemUI/AndroidManifest.xml
+++ b/alps/frameworks/base/packages/SystemUI/AndroidManifest.xml
<service android:name=".screenshot.TakeScreenshotService"
android:process=":screenshot"
- android:exported="false" />
+ android:exported="true" />
<!-- Called from PhoneWindowManager -->
<receiver android:name=".screenshot.ScreenshotServiceErrorReceiver"
三:解決ListView事件沖突
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
&& ev.getAction() == MotionEvent.ACTION_DOWN
&& ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
&& isOnScrollbarThumb(ev.getX(), ev.getY())) {
return true;
}
+ if (ev.getPointerCount()==
+ &&Settings.System.getInt(mContext.getContentResolver(), +Settings.System.SCREENSHOTPOINTER, )==) {
+ return true;
+ }
return false;
}
四:預設狀态控制
1.frameworks/base/packages/SettingsProvider/res/values/defaults.xml設定預設指控制三指截屏操作是預設開還是關。
M alps/frameworks/base/core/java/android/provider/Settings.java
M alps/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
M alps/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
Settings.java
+ public static final String SCREENSHOTPOINTER = "screenshot_pointer";
DatabaseHelper.java
+ loadIntegerSetting(stmt, Settings.System.SCREENSHOTPOINTER,
+ R.integer.screenshot_pointer);
defaults.xml
+ <integer name="screenshot_pointer"></integer>
2.編譯遇到不過的時候
******************************
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
) You can add "@hide" javadoc comments to the methods, etc. listed in the
errors above.
) You can update current.txt by executing the following command:
make update-api
To submit the revised current.txt to the main Android repository,
you will need approval.
******************************
執行make update-api,并把相關的current.txt送出上