1.第二步就是判断权限是否开放,因为在open 是会对权限检验所以必要的:
mUsbManager.hasPermission(mDevice));
mUsbManager.requestPermission(mDevice,
mPermissionIntent);
2.直接看UsbService 吧
public boolean hasDevicePermission(UsbDevice device) {
// 不同应用用有不同usbId,除非是系统应用
final int userId = UserHandle.getCallingUserId();
return getSettingsForUser(userId).hasPermission(device);
}
//UsbSettiongManager
public boolean hasPermission(UsbDevice device) {
synchronized (mLock) {
int uid = Binder.getCallingUid();
if (uid == Process.SYSTEM_UID) {
return true; //是系统应用直接返回true
}
SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName()); //在已经授权的集合中能查到返回true否则false;
if (uidList == null) {
return false;
}
return uidList.get(uid);
}
}
//申请权限
public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) {
final int userId = UserHandle.getCallingUserId();
getSettingsForUser(userId).requestPermission(device, packageName, pi);
}
//UsbSettingManager
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);
}
//就调起UsbPermissionActivity 没有什么别的
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);
}
}
//UsbPermissionActivity 关键部分
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) { //点击确定按钮就确认授权
mPermissionGranted = true;
}
finish();
}
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) {
//填充UsbSettingManager 授权集合 ,之前在做无权限弹窗时使用aidl(将IUsbManager.adil拷贝到自己工程目录下,能执行这个方法却报我应用没有manger_usb权限 也是需要系统应用才能分配这个权限.是系统应用要你干啥)
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();
}
3.无权限弹窗常见方法:1.root 可以用libusb库2.系统应用3.自己修改系统源码