androidandroid-permissionsandroid-9.0-pieruntime-permissionsusb-otg

How get runtime permission to communicate with a USB Flash Drive in an Android Application with LockTask Mode enable?


I'm developing an Application SDK 28 with LockTask Mode for a Single-Uses Device. The application transfer some files from Device to USB Flash Drive through USB OTG. For the comunication with the Flash Drive, the application requests a runtime permission but the LockTask Mode blocks the Dialog Message for accept the user permission. Due to this, the application can't get the permission and when it wants transfer the files fail. I want to know if exits a way for enable some permission in lock task mode or enable these dialogues?

Request the permission to communication with Flash Drive

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void check() {
    manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    /*
     * this block required if you need to communicate to USB devices it's
     * take permission to device
     * if you want than you can set this to which device you want to communicate
     */
    // ------------------------------------------------------------------
    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(mUsbReceiver, filter);
    // -------------------------------------------------------------------
    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
    Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    String i = "";
    while (deviceIterator.hasNext()) {
        device = deviceIterator.next();
        manager.requestPermission(device, mPermissionIntent);
        i +=  "USB Detectada!!";
    }
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        UsbDevice usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
        if (ACTION_USB_PERMISSION.equals(action)) {
            // Permission requested
            synchronized (this) {
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    //cueMsg.cueCorrect("Permiso otorgado");
                    // User has granted permission
                    // ... Setup your UsbDeviceConnection via mUsbManager.openDevice(usbDevice) ...
                } else {
                    cueMsg.cueError("Permiso denegado");
                    // User has denied permission
                }
            }
        }
        if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
            cueMsg.cueError("Usb desconectado");
            // Device removed
            synchronized (this) {
                // ... Check to see if usbDevice is yours and cleanup ...
            }
        }
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
            cueMsg.cueCorrect("Usb conectado");
            // Device attached
        }
    }
};

LockTask Mode Code

@TargetApi(Build.VERSION_CODES.M)
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onStart() {
    if (mDevicePolicyManager.isLockTaskPermitted(this.getPackageName())){
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        if (am.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_NONE){
            setDefaultCosuPolicies(true);
            startLockTask();
        }
    }
    super.onStart();
}

@RequiresApi(api = Build.VERSION_CODES.M)
private void unlockApp(){
    ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
    if (am.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED){
        stopLockTask();
    }
    setDefaultCosuPolicies(false);
}


@TargetApi(Build.VERSION_CODES.M)
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void setDefaultCosuPolicies(boolean active) {
    //Configuración de restricciones de usuario
    setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, active);
    setUserRestriction(UserManager.DISALLOW_FACTORY_RESET, active);
    setUserRestriction(UserManager.DISALLOW_ADD_USER, active);

    //setUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, active);
    setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, false);


    setUserRestriction(UsbManager.EXTRA_PERMISSION_GRANTED, true);
    setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, active);


    //Desabilitar lockscreen y barra de estado
    mDevicePolicyManager.setKeyguardDisabled(mAdminComponentName, active);
    mDevicePolicyManager.setStatusBarDisabled(mAdminComponentName, active);
    //Permisos para USB
    mDevicePolicyManager.setPermissionGrantState(mAdminComponentName,
            "com.example.devicepolicymanager2",
            UsbManager.EXTRA_PERMISSION_GRANTED,
            DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);

    //Habilitar Plugged in
    enableStayOnWhilePluggedIn(active);

    //Configurar politicas de actualización de sistema
    if (active){
        mDevicePolicyManager.setSystemUpdatePolicy(mAdminComponentName, SystemUpdatePolicy.createWindowedInstallPolicy(60, 120));
    } else {
        mDevicePolicyManager.setSystemUpdatePolicy(mAdminComponentName, null);
    }

    //Configurar la actividad como un paquete lock task
    //mDevicePolicyManager.setLockTaskPackages(mAdminComponentName,
    //      active ? new String[]{getPackageName()} : new String[]{});
    mDevicePolicyManager.setLockTaskPackages(mAdminComponentName, APP_PACKAGES);


    IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
    intentFilter.addCategory(Intent.CATEGORY_HOME);
    intentFilter.addCategory(Intent.CATEGORY_DEFAULT);

    if (active){
        //configura actividad cosu como home para que comience al reiniciarse
        mDevicePolicyManager.addPersistentPreferredActivity(mAdminComponentName,
                intentFilter,
                new ComponentName(getPackageName(),
                        LoginActivity.class.getName()));
    } else {
        mDevicePolicyManager.clearPackagePersistentPreferredActivities(mAdminComponentName, getPackageName());
    }
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void setUserRestriction(String restriction, boolean disallow){
    if (disallow){
        mDevicePolicyManager.addUserRestriction(mAdminComponentName, restriction);
    }else {
        mDevicePolicyManager.clearUserRestriction(mAdminComponentName, restriction);
    }
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void enableStayOnWhilePluggedIn(boolean enabled){
    if (enabled){
        mDevicePolicyManager.setGlobalSetting(mAdminComponentName,
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                Integer.toString(BatteryManager.BATTERY_PLUGGED_AC |
                        BatteryManager.BATTERY_PLUGGED_USB |
                        BatteryManager.BATTERY_PLUGGED_WIRELESS));
    }else {
        mDevicePolicyManager.setGlobalSetting(mAdminComponentName,
                Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
                "0");
    }
}

Solution

  • During Lock task mode any applications that are not white-listed are not permitted to open. You have to white list the USB dialog application.

        private static String USB_DIALOG_PACKAGE = "com.android.systemui";
    
        private static String[] APP_PACKAGES = {[YOUR OTHER WHITE LISTED PACKAGES HERE],USB_DIALOG_PACKAGE };