Nella mia applicazione, che è un amministratore del dispositivo, ho bisogno di cancellare l'intero dispositivo quando l'utente tenta di disattivare la funzione di amministrazione dell'applicazione. Quando l'utente accede a Impostazioni/Sicurezza/Amministratori e disattiva l'app di amministrazione, prima viene visualizzata una finestra di dialogo "Disattivare". Se l'utente dice "sì", viene presentata un'altra piccola finestra di dialogo, con il testo fornito da AdminReceiver dell'applicazione in onDisableRequested(). Se l'utente dice "sì", voglio cancellare l'intero dispositivo. Come realizzare questo?Come cancellare il dispositivo Android quando l'amministratore del dispositivo è disattivato?
Ho provato di tutto, ho cercato a lungo le risposte, non ho trovato soluzioni reali.
Quello che ho cercato:
- AdminReceiver ha una funzione onDisable(). Ho provato a cancellare il dispositivo in quella funzione. Tuttavia, sembra che onDisable() sia chiamato dopo l'amministratore è stato disabilitato. Pertanto l'app non può utilizzare la funzione wipeData() (viene generata un'eccezione di sicurezza). Ho anche verificato che isAdminActive() restituisce false in quel momento.
La documentazione ufficiale non lo dice chiaramente, ma sembra che l'amministratore sia già disabilitato quando viene chiamato onDisable(). Quindi dobbiamo pulire il dispositivo prima di quel momento.
AdminReceiver ha una funzione suDisableRequested(), che restituisce CharSequence. Ho provato a mettere un'altra casella di avviso in quella funzione. Questo si blocca perché una casella di avviso non può essere chiamata da un contesto di non attività, che sembra essere quello che abbiamo quando siamo in onDisableRequested().
AdminReceiver ha una funzione onReceive(), che viene richiamata su qualsiasi evento. In questa funzione, ancora una volta, non ci troviamo in un contesto di attività e non possiamo presentare le nostre finestre di dialogo.
Ho provato a creare un'altra attività da onReceive(). Questo funziona; durante onReceive() quando otteniamo ACTION_DISABLE_ADMIN_REQUESTED, l'amministratore è ancora attivo e possiamo cancellare il dispositivo. Tuttavia, il sistema presenta ancora una propria finestra di dialogo che chiede all'utente se disattivare l'amministratore. Se l'utente dice no alla nostra finestra di dialogo, ma sì alla finestra di dialogo del sistema, l'amministratore verrà disattivato e avremo fallito nel cancellare il dispositivo.
Ho provato quanto segue, nel mio sottoclasse di DeviceAdminReceiver:
@Override
public void onReceive(Context context, Intent intent) {
// detect whether disabling is requested?
if (intent.getAction().equals(ACTION_DEVICE_ADMIN_DISABLE_REQUESTED)) {
confirmWipeDevice(context);
} else {
super.onReceive(context, intent);
}
}
In altre parole, non mi chiamo super.onReceive() se l'azione è quello di disabilitare l'amministratore. La funzione confirmWipeDevice() mostra un'attività diversa con una finestra di dialogo. Questo non mostra la finestra di dialogo del sistema per confermare la disabilitazione della mia app di amministrazione. Tuttavia, questo non impedisce l'effettiva disabilitazione dell'app!
Sembra che il sistema Android esegue le seguenti operazioni:
Invia ACTION_DEVICE_ADMIN_DISABLE_REQUESTED al AdminReceiver
Procedere con disabilitando l'amministratore indipendentemente da ciò che l'applicazione di amministrazione vuole fare
Se l'utente annulla la disabilitazione, bene; in caso contrario, l'app è disabilitata. L'app non consente in alcun modo di rifiutare di essere disattivata o di eseguire la cancellazione del dispositivo dopo la disattivazione.
L'unica soluzione è quella di cancellare immediatamente senza conferma quando l'utente desidera disabilitare l'app di amministrazione. In altre parole, posso chiamare getManager(). WipeData() immediatamente in onDisableRequested(). A quel tempo, l'amministratore è ancora attivo e funziona.
È corretto? Come pulire il dispositivo quando l'utente sceglie di disabilitare l'app di amministrazione?
Sto trovando che provare a eseguire una chiamata wipeData() su OnDisableRequested() o suDisable() mette le cose in uno stato traballante, e la cancellazione dei dati ha esito negativo se lo schermo si spegne. Hai avuto ulteriore fortuna con questo? –
La cancellazione dei dati può avere esito positivo se lo schermo si spegne? Non abbiamo provato questo. (Abbiamo cambiato il dispositivo in Android 3.2 dove possiamo fare cose su onDisabled.) – winitzki
Sono riuscito a farlo funzionare se ho avviato un AsyncTask da onDisableRequested(). Penso che qualunque thread sia in esecuzione quando viene chiamato onDisableRequested(), una chiamata wipeData() non può essere fatta in modo affidabile qui. Quando l'ho licenziato da un AsyncTask, vedo la finestra di PowerOff in arrivo quasi immediatamente. –