如何在Android 9上绕过USB主机权限确认对话框

4
在Android 9之前,我可以通过root,系统化我的应用程序并使用下一个USB类来绕过Android USB主机权限确认对话框 https://dev59.com/7WYr5IYBdhLWcg3wYZKD#15378118 https://dev59.com/7WYr5IYBdhLWcg3wYZKD#19681849。但是对于最新的Android版本-9,它不起作用。它会抛出java.lang.NoSuchMethodError: No interface method grantDevicePermission(Landroid/hardware/usb/UsbDevice;I)V in class Landroid/hardware/usb/IUsbManager; or its super classes (declaration of 'android.hardware.usb.IUsbManager' appears in /system/framework/framework.jar)异常。
fun setUsbPermissionRoot(device: UsbDevice) : Boolean {
    if (BuildConfig.DEBUG) Log.i(TAG, "trying set permission")
    try {
        val pm = App.context.packageManager
        val ai = pm.getApplicationInfo(App.context.packageName, 0)
        ai?.let {
            val b = ServiceManager.getService(Context.USB_SERVICE)
            val service = IUsbManager.Stub.asInterface(b)
            service.grantDevicePermission(device, it.uid)
            try {
                service.setDevicePackage(device, App.context.packageName, it.uid)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            if (BuildConfig.DEBUG) Log.i(TAG, "permission was set usb device")
            return true
        }
    } catch (e: PackageManager.NameNotFoundException) {
        if (BuildConfig.DEBUG) e.printStackTrace()
    } catch (e: RemoteException) {
        if (BuildConfig.DEBUG) e.printStackTrace()
    }
    return false
}

有没有办法让它在Android 9上运行?

似乎您的“IUsbManager”无法在Android 9上使用。也许“grantDevicePermission()”方法已被删除,或者在较新的Android版本中具有不同的签名。 - emandt
1个回答

5
我们可以通过输入以下内容来解决它:
adb shell
su
settings put global hidden_api_policy_pre_p_apps  1
settings put global hidden_api_policy_p_apps 1

非SDK接口限制(Android 9):https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces

在Android 9上,grantDevicePermission方法将再次通过反射可用:

public static boolean grantAutomaticUsbPermissionRoot(Context context, UsbDevice usbDevice) {
    try {
        PackageManager pkgManager = context.getPackageManager();
        ApplicationInfo appInfo = pkgManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);

        Class serviceManagerClass = Class.forName("android.os.ServiceManager");
        Method getServiceMethod = serviceManagerClass.getDeclaredMethod("getService", String.class);
        getServiceMethod.setAccessible(true);
        android.os.IBinder binder = (android.os.IBinder)getServiceMethod.invoke(null, Context.USB_SERVICE);

        Class iUsbManagerClass = Class.forName("android.hardware.usb.IUsbManager");
        Class stubClass = Class.forName("android.hardware.usb.IUsbManager$Stub");
        Method asInterfaceMethod = stubClass.getDeclaredMethod("asInterface", android.os.IBinder.class);
        asInterfaceMethod.setAccessible(true);
        Object iUsbManager=asInterfaceMethod.invoke(null, binder);

        final Method grantDevicePermissionMethod = iUsbManagerClass.getDeclaredMethod("grantDevicePermission", UsbDevice.class, int.class);
        grantDevicePermissionMethod.setAccessible(true);
        grantDevicePermissionMethod.invoke(iUsbManager, usbDevice,appInfo.uid);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

顺便提一句,你需要具备root权限并将应用系统化(移动到/system/priv-app/目录下)。


1
@HoseinHaqiqian 是的,应该是这样的。 - user924
抱歉,是root或签名系统应用程序?还是只有root而没有签名的系统应用程序?这适用于Android 10吗? - Fortran
@Yeung,是什么让你感到困惑?... - user924
@Yeung 是的,答案中已经写了... - user924
是的,我已经检查了那部分。我正在处理生成此错误的Android 11上。@user924有人在Android 11或更高版本中检查过吗? - Nikhil
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接