Android usb設備權限查詢及自動獲取詳解流程
看到當上面的對話框彈出時,可以使用命令查看頂層的活動窗口
adb shell dumpsys window | findstr mCurrentFocus mCurrentFocus=Window{41ab0ee0 u0 com.android.systemui/com.android.systemui.usb.UsbPermissionActivity}
這就是應用的位置,當然我們也可以是用grep命令來查找這個對話框的.xml文件,進入android源碼然後輸入命令:
grep '默認情況下用於' ./ -Rn ./SystemUI/res/values-zh-rCN/strings.xml:51: <string name="always_use_device" msgid="1450287437017315906">"默認情況下用於該 USB 設備"</string> ./SystemUI/res/values-zh-rCN/strings.xml:52: <string name="always_use_accessory" msgid="1210954576979621596">"默認情況下用於該 USB 配件"</string>
那麼這個對話框的路徑在
/android/frameworks/base/packages/SystemUI/res/values-zh-rCN/strings.xml
其相關的內容如下:
<string name="always_use_device" msgid="1450287437017315906">"默認情況下用於該 USB 設備"</string> <string name="usb_device_permission_prompt" msgid="834698001271562057">"允許應用“<xliff:g id="APPLICATION">%1$s</xliff:g>”訪問該 USB 設備嗎?"
相關應用路徑找到.java文件來修改,其位置在:
/android/frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
這就是那個討厭的對話框對應的java程序,那麼來看看這個程序如下:
/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.usb; import android.app.AlertDialog; import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.hardware.usb.IUsbManager; import android.hardware.usb.UsbAccessory; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.TextView; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.systemui.R; public class UsbPermissionActivity extends AlertActivity implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener { private static final String TAG = "UsbPermissionActivity"; private CheckBox mAlwaysUse; private TextView mClearDefaultHint; private UsbDevice mDevice; private UsbAccessory mAccessory; private PendingIntent mPendingIntent; private String mPackageName; private int mUid; private boolean mPermissionGranted; private UsbDisconnectedReceiver mDisconnectedReceiver; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); Intent intent = getIntent(); mDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); mAccessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); mPendingIntent = (PendingIntent)intent.getParcelableExtra(Intent.EXTRA_INTENT); mUid = intent.getIntExtra(Intent.EXTRA_UID, -1); mPackageName = intent.getStringExtra("package"); Log.e(TAG, "mPackageName "+ mPackageName); Log.e(TAG, "mUid "+ mUid); PackageManager packageManager = getPackageManager(); ApplicationInfo aInfo; try { aInfo = packageManager.getApplicationInfo(mPackageName, 0); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "unable to look up package name", e); finish(); return; } String appName = aInfo.loadLabel(packageManager).toString(); Log.e(TAG, "appName "+ appName); final AlertController.AlertParams ap = mAlertParams; ap.mIcon = aInfo.loadIcon(packageManager); ap.mTitle = appName; if (mDevice == null) { ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName); mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory); } else { ap.mMessage = getString(R.string.usb_device_permission_prompt, appName); mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice); } ap.mPositiveButtonText = getString(android.R.string.ok); ap.mNegativeButtonText = getString(android.R.string.cancel); ap.mPositiveButtonListener = this; ap.mNegativeButtonListener = this; // add "always use" checkbox LayoutInflater inflater = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null); mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse); if (mDevice == null) { mAlwaysUse.setText(R.string.always_use_accessory); } else { mAlwaysUse.setText(R.string.always_use_device); } mAlwaysUse.setOnCheckedChangeListener(this); mClearDefaultHint = (TextView)ap.mView.findViewById( com.android.internal.R.id.clearDefaultHint); mClearDefaultHint.setVisibility(View.GONE); if(!mPackageName.equals("com.zqc.usbcamera")) setupAlert(); else { mPermissionGranted = true; finish(); } } @Override public void onDestroy() { IBinder b = ServiceManager.getService(USB_SERVICE); IUsbManager service = IUsbManager.Stub.asInterface(b); // send response via pending intent Intent intent = new Intent(); try { if (mDevice != null) { intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice); if (mPermissionGranted) { service.grantDevicePermission(mDevice, mUid); if (mAlwaysUse.isChecked()) { final int userId = UserHandle.getUserId(mUid); service.setDevicePackage(mDevice, mPackageName, userId); } } } if (mAccessory != null) { intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory); if (mPermissionGranted) { service.grantAccessoryPermission(mAccessory, mUid); if (mAlwaysUse.isChecked()) { final int userId = UserHandle.getUserId(mUid); service.setAccessoryPackage(mAccessory, mPackageName, userId); } } } intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, mPermissionGranted); mPendingIntent.send(this, 0, intent); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "PendingIntent was cancelled"); } catch (RemoteException e) { Log.e(TAG, "IUsbService connection failed", e); } if (mDisconnectedReceiver != null) { unregisterReceiver(mDisconnectedReceiver); } super.onDestroy(); } public void onClick(DialogInterface dialog, int which) { if (which == AlertDialog.BUTTON_POSITIVE) { mPermissionGranted = true; } finish(); } public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (mClearDefaultHint == null) return; if(isChecked) { mClearDefaultHint.setVisibility(View.VISIBLE); } else { mClearDefaultHint.setVisibility(View.GONE); } } }
這段代碼是獲取應用的包名,我們可以通過包名對比來決定是否彈出對話框。
final AlertController.AlertParams ap = mAlertParams; ap.mIcon = aInfo.loadIcon(packageManager); ap.mTitle = appName; if (mDevice == null) { ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName); mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory); } else { ap.mMessage = getString(R.string.usb_device_permission_prompt, appName); mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice); } ap.mPositiveButtonText = getString(android.R.string.ok); ap.mNegativeButtonText = getString(android.R.string.cancel); ap.mPositiveButtonListener = this; ap.mNegativeButtonListener = this; // add "always use" checkbox LayoutInflater inflater = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null); mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse); if (mDevice == null) { mAlwaysUse.setText(R.string.always_use_accessory); } else { mAlwaysUse.setText(R.string.always_use_device); } mAlwaysUse.setOnCheckedChangeListener(this); mClearDefaultHint = (TextView)ap.mView.findViewById( com.android.internal.R.id.clearDefaultHint); mClearDefaultHint.setVisibility(View.GONE);
在上面的代碼就是對話框瞭,接下來就是要修該的東西瞭
setupAlert();
如果不需要顯示對話框就可以這樣修改,根據包名來判斷該應用是否彈出
if(!mPackageName.equals("包名")) setupAlert(); else { mPermissionGranted = true; finish(); }
最終給該應用授權USB設備權限的代碼,是通過調用grantDevicePermission()和grantAccessoryPermission()方法給該應用授權USB設備權限
@Override public void onDestroy() { IBinder b = ServiceManager.getService(USB_SERVICE); IUsbManager service = IUsbManager.Stub.asInterface(b); // send response via pending intent Intent intent = new Intent(); try { if (mDevice != null) { intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice); if (mPermissionGranted) { service.grantDevicePermission(mDevice, mUid); if (mAlwaysUse.isChecked()) { final int userId = UserHandle.getUserId(mUid); service.setDevicePackage(mDevice, mPackageName, userId); } } } if (mAccessory != null) { intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory); if (mPermissionGranted) { service.grantAccessoryPermission(mAccessory, mUid); if (mAlwaysUse.isChecked()) { final int userId = UserHandle.getUserId(mUid); service.setAccessoryPackage(mAccessory, mPackageName, userId); } } } intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, mPermissionGranted); mPendingIntent.send(this, 0, intent); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "PendingIntent was cancelled"); } catch (RemoteException e) { Log.e(TAG, "IUsbService connection failed", e); } if (mDisconnectedReceiver != null) { unregisterReceiver(mDisconnectedReceiver); } super.onDestroy(); }
日志打印
C:\Users\Android1>adb shell logcat -s UsbPermissionActivity
——— beginning of /dev/log/system
——— beginning of /dev/log/main
E/UsbPermissionActivity( 708): mPackageName com.test.usbcamera
E/UsbPermissionActivity( 708): mUid 10018
E/UsbPermissionActivity( 708): appName USBCamera
E/UsbPermissionActivity( 708): onDestroy() grantDevicePermission false
E/UsbPermissionActivity( 708): mPackageName com.zqc.usbcamera
E/UsbPermissionActivity( 708): mUid 10019
E/UsbPermissionActivity( 708): appName USBCamera
E/UsbPermissionActivity( 708): onDestroy() grantDevicePermission false
到此這篇關於Android usb設備權限查詢及自動獲取詳解流程的文章就介紹到這瞭,更多相關Android usb設備權限 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Android實現一鍵鎖屏功能
- 詳解Android的四大應用程序組件
- android10 隱藏SystemUI鎖屏下的多用戶圖標的示例代碼
- Android中Intent組件的入門學習心得
- Android BindService使用案例講解