Android 7.1 增加屏幕边缘滑动事件(手势滑动)两种方式(Back,Home,Menu功能键) 免开启无障碍功能

30 篇文章 0 订阅

目前公司在做新项目开发,项目目前是不让有Back,Home,Menu实体按键,这就导致了一个问题,点开其它应用无法返回到桌面,

当然些问题对于做开发的我们肯定是难不到的,如果我们开发碰到这问题肯定是adb链接 终端输入对应的key值 命令就搞定了

例如

$adb shell input keyevent 4

或者我们使用投屏神器 scrcpy 也能搞定.

问题是产品要面向客户展示,总不能抱个电脑链接产品机器让客户看吧...这样也太丢人了,使用的是Android 7.1 原生系统,又不支持边缘滑动,问题总是要解决的,经过前期的调研发现了两种方式可以完成.

第一种是系统层面增加

好处:系统自己维护,定制化强

缺点:需要有自己的ROM包

 

第二种是写一个手势APP

好处:不需要修改系统.

缺点:受系统限制比较大

 

第一种方式

经过查询代码发现其实Google 在7.1 上面已经写好对应的借口,只是空着没实现.

那具体的实现方式就是 我在系统中属性里面增加属性值来决定每个滑动事件对应的动作,这样以来只需要改动配置文件就行,不需要每次修改framework代码.

我开发的版本的系统属性路径如下,添加系统属性,默认是配置是空(关闭状态)想要使用该功能的时候直接打开即可.

device/qcom/msmXXX/system.prop

#Edge Gesture Function
persist.gesturekey.bottom= #HOME
persist.gesturekey.right= #MENU
persist.gesturekey.left= #BACK

然后在 PhoneWindowManager.java中添加滑动事件

frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

   // monitor for system gestures
        mSystemGestures = new SystemGesturesPointerEventListener(context,
                new SystemGesturesPointerEventListener.Callbacks() {
                    @Override
                    public void onSwipeFromTop() {
                        if (mStatusBar != null) {
                            // 下拉框 系统已经实现的 如 systemUI 通知栏等
                            requestTransientBars(mStatusBar);
                        }
                    }
                    @Override
                    public void onSwipeFromBottom() {
                 
                        // 添加底部往上滑动事件
                               doPersitKey(SystemProperties.get("persist.gesturekey.bottom"));

                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onSwipeFromRight() {
                       
                        // 添加右滑动

                        doPersitKey(SystemProperties.get("persist.gesturekey.right"));

                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
                    @Override
                    public void onSwipeFromLeft() {
                    // 添加左滑动
                     
                    doPersitKey(SystemProperties.get("persist.gesturekey.left"));

                        if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
                            requestTransientBars(mNavigationBar);
                        }
                    }
      ...........省略代码.........
                });

可以看到我没有在具体的事件中进行处理,这样是为了后期方便,我处理时间的时候去读取配置文件对应的值,通过对应的值来决定做左滑动,上滑动以及右滑动的值

具体的处理滑动事件逻辑逻辑

    private void doPersitKey(String persistkey) {
        if ("BACK".equals(persistkey)) {

            long now = SystemClock.uptimeMillis();
            KeyEvent down = new KeyEvent(
                    now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0);
            InputManager.getInstance().injectInputEvent(
                    down, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
            KeyEvent up = new KeyEvent(
                    now, now, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, 0);
            InputManager.getInstance().injectInputEvent(
                    up, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);

        } else if ("HOME".equals(persistkey)) {
            launchHomeFromHotKey();
        } else if ("MENU".equals(persistkey)) {
            toggleRecentApps();
        }
    }

 

第二种APP方式无障碍功能

边缘手势代码

代码已经写好,直接用AndroidStudio打开运行即可

运行之后需要打开无障碍模式模式才能进行使用

如果不想每次使用都开启无障碍服务就需要系统签名 系统签名详解

1.AndroidManifest.xml 增加 

添加 sharedUserId
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:sharedUserId="com.xxx.gesture"
    package="com.xxx.gesture">
添加开机启动权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

添加开机启动广播
<action android:name="android.intent.action.BOOT_COMPLETED" />

2.在静态开机广播中增加如下代码,这样的话开机就会启动此服务,越过用户手动开启,就可以使用边缘手势滑动功能

public class SystemReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {

            Settings.Secure.putString(context.getContentResolver(),
                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "com.xxx.gesture/com.xxx.gesture.AccessibilityServiceGesture");
            Settings.Secure.putString(context.getContentResolver(),
                    Settings.Secure.ACCESSIBILITY_ENABLED, "1");
        }
    }
}

 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android 7.1 AOSP中添加屏幕密度选项并实现功能选项的功能,可以按照以下步骤进行操作: 1. 在AOSP源代码中找到Settings应用程序的代码目录,路径为packages/apps/Settings。 2. 在该目录下找到res/values/arrays.xml文件,并打开该文件。 3. 在该文件中添加一个新的数组,用于表示屏幕密度选项的值。例如: ``` <string-array name="screen_density_values"> <item>120</item> <item>160</item> <item>240</item> <item>320</item> <item>480</item> <item>640</item> </string-array> ``` 4. 在该文件中添加一个新的数组,用于表示屏幕密度选项的标签。例如: ``` <string-array name="screen_density_labels"> <item>@string/screen_density_120</item> <item>@string/screen_density_160</item> <item>@string/screen_density_240</item> <item>@string/screen_density_320</item> <item>@string/screen_density_480</item> <item>@string/screen_density_640</item> </string-array> ``` 5. 在该文件中添加对应的字符串资源,例如: ``` <string name="screen_density_120">Low Density (120)</string> <string name="screen_density_160">Medium Density (160)</string> <string name="screen_density_240">High Density (240)</string> <string name="screen_density_320">Extra High Density (320)</string> <string name="screen_density_480">Extra Extra High Density (480)</string> <string name="screen_density_640">Extra Extra Extra High Density (640)</string> ``` 6. 在Settings应用程序的代码中,找到DisplaySettings.java文件,并打开该文件。 7. 在该文件中找到屏幕密度选项的相关代码,在onCreate方法中添加以下代码: ``` mScreenDensityPreference = (ListPreference) findPreference(KEY_SCREEN_DENSITY); mScreenDensityPreference.setEntries(R.array.screen_density_labels); mScreenDensityPreference.setEntryValues(R.array.screen_density_values); mScreenDensityPreference.setValue(String.valueOf(currentDensity)); mScreenDensityPreference.setOnPreferenceChangeListener(this); ``` 其中,KEY_SCREEN_DENSITY是一个常量,表示屏幕密度选项对应的键值。currentDensity是当前屏幕密度的值。 8. 在该文件中实现功能选项的功能,在onPreferenceChange方法中添加以下代码: ``` if (preference == mScreenDensityPreference) { int density = Integer.parseInt((String) newValue); DisplayMetrics metrics = getResources().getDisplayMetrics(); metrics.densityDpi = density; getBaseContext().getResources().updateConfiguration(getResources().getConfiguration(), metrics); try { IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); if (wm != null) { wm.updateSettings(); } } catch (RemoteException e) { Log.e(TAG, "Unable to update window manager settings", e); } return true; } ``` 其中,newValue是用户选择的屏幕密度的值。该代码将用户选择的屏幕密度值更新到系统的DisplayMetrics中,并更新配置信息。然后,它调用IWindowManager接口更新窗口管理器的设置。 9. 构建AOSP源代码并运行生成的系统镜像。 10. 在系统设置中,找到显示选项,即可看到屏幕密度选项,并且可以根据用户选择的屏幕密度值来改变屏幕的显示效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值