Android 屏蔽USB权限弹框 您所在的位置:网站首页 安卓信息不弹出来 Android 屏蔽USB权限弹框

Android 屏蔽USB权限弹框

#Android 屏蔽USB权限弹框| 来源: 网络整理| 查看: 265

最近在看Android USB主从设备通讯(下载Demo)相关的东西,调试时每次运行都弹下面的框,即使勾选“默认情况下用于该USB设备”,还是会弹出,在调试阶段频繁弹框影响开发效率。

下面分享下怎么屏蔽USB权限框:

1. 做过相关开发的都见过下面代码

// Check whether we have permission to access the device. if (!mUsbManager.hasPermission(device)) { Intent intent = new Intent(ACTION_USB_DEVICE_PERMISSION); intent.setPackage(getPackageName()); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); mUsbManager.requestPermission(device, pendingIntent); return; } 意思在没有权限的情况下,请求权限才弹的框。

2. 分析弹框流程

mUsbManager.requestPermission(UsbDevice device...);//以UsbDevice为例,UsbAccessory同理

                a. frameworks/base/core/java/android/hardware/usb/UsbManager.java=>requestPermission

public void requestPermission(UsbDevice device, PendingIntent pi) { try { mService.requestDevicePermission(device, mContext.getPackageName(), pi); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }

               b. frameworks/base/core/java/android/hardware/usb/UsbDevice.java=>requestDevicePermission

@Override public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) { final int userId = UserHandle.getCallingUserId(); getSettingsForUser(userId).requestPermission(device, packageName, pi); } getSettingsForUser是 UsbDevice成员函数

private UsbSettingsManager getSettingsForUser(int userId) { synchronized (mLock) { UsbSettingsManager settings = mSettingsByUser.get(userId); if (settings == null) { settings = new UsbSettingsManager(mContext, new UserHandle(userId)); mSettingsByUser.put(userId, settings); } return settings; } }                c. frameworks/base/services/java/com/android/server/usb/UsbSettingsManager.java=> requestPermission

    public void requestPermission(UsbDevice device, String packageName, PendingIntent pi) {       Intent intent = new Intent();         // respond immediately if permission has already been granted       if (hasPermission(device)) {             intent.putExtra(UsbManager.EXTRA_DEVICE, device);             intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);             try {                 pi.send(mUserContext, 0, intent);             } catch (PendingIntent.CanceledException e) {                 if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");             }             return;         }         // start UsbPermissionActivity so user can choose an activity         intent.putExtra(UsbManager.EXTRA_DEVICE, device);         requestPermissionDialog(intent, packageName, pi);     } 接着调成员函数requestPermissionDialog

private void requestPermissionDialog(Intent intent, String packageName, PendingIntent pi) { final int uid = Binder.getCallingUid(); // compare uid with packageName to foil apps pretending to be someone else try { ApplicationInfo aInfo = mPackageManager.getApplicationInfo(packageName, 0); if (aInfo.uid != uid) { throw new IllegalArgumentException("package " + packageName + " does not match caller's uid " + uid); } } catch (PackageManager.NameNotFoundException e) { throw new IllegalArgumentException("package " + packageName + " not found"); } long identity = Binder.clearCallingIdentity(); intent.setClassName("com.android.systemui", "com.android.systemui.usb.UsbPermissionActivity"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(Intent.EXTRA_INTENT, pi); intent.putExtra("package", packageName); intent.putExtra(Intent.EXTRA_UID, uid); try { mUserContext.startActivityAsUser(intent, mUser); } catch (ActivityNotFoundException e) { Slog.e(TAG, "unable to start UsbPermissionActivity"); } finally { Binder.restoreCallingIdentity(identity); } } 由此看最终显示框的地方在SystemUI的UsbPermissionActivity。

3. 屏蔽弹框

a. 看到有博客说在UsbPermissionActivity的onCreate显示Dialog(setupAlert)时替换点击确定的代码

相当于自动点击确定

@Override public void onCreate(Bundle icicle) { ... //setupAlert(); mPermissionGranted = true; finish(); } 或

    @Override     public void onCreate(Bundle icicle) {         ...         mAlwaysUse.setOnCheckedChangeListener(this);         mAlwaysUse.setChecked(true);         ...         setupAlert();         onClick(this, AlertDialog.BUTTON_POSITIVE);     } 上述两种方法虽然能达到自动授权,个人觉得这种屏蔽方法不理想,下面介绍更好方法。

b. 直接让mUsbManager.hasPermission返回true(自动授权),不更彻底?!

下面列下函数调用关系

①. frameworks/base/core/java/android/hardware/usb/UsbManager.java=>hasPermission

public boolean hasPermission(UsbDevice device) { try { return mService.hasDevicePermission(device); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } ②. frameworks/base/core/java/android/hardware/usb/UsbDevice.java =>hasDevicePermission public boolean hasDevicePermission(UsbDevice device) { final int userId = UserHandle.getCallingUserId(); return getSettingsForUser(userId).hasPermission(device); } ③. frameworks/base/services/java/com/android/server/usb/UsbSettingsManager.java=>hasPermission

    // Android L(5.x)及之后的版本     public boolean hasPermission(UsbDevice device) {         synchronized (mLock) {             int uid = Binder.getCallingUid();             if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {                 return true;             }             SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());             if (uidList == null) {                 return false;             }             return uidList.get(uid);         }     }

让条件(uid == Process.SYSTEM_UID || mDisablePermissionDialogs)为真即可

第一种方式:在AndroidManifest.xml里加上android:sharedUserId="android.uid.system",但是apk需打系统签名

第二种方式:让mDisablePermissionDialogs为真

mDisablePermissionDialogs = context.getResources().getBoolean( com.android.internal.R.bool.config_disableUsbPermissionDialogs); frameworks/base/core/res/res/values/config.xml

true 哈哈,看看上面注释,这么改会引起CTS fail,这就看你的项目是否要过CTS了

// Android KK(4.4)及之前的版本 public boolean hasPermission(UsbDevice device) { synchronized (mLock) { int uid = Binder.getCallingUid(); if (uid == Process.SYSTEM_UID) { return true; } SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName()); if (uidList == null) { return false; } return uidList.get(uid); } } 这里就用上述第一种方式即可。

感觉自己好啰嗦哦(贴了不少代码),对你有帮助就好。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有