2015-09-14 9 views
7

Używam Android Storage Access Framework, aby uzyskać dostęp do niektórych plików na karcie SD. Ważne jest, aby zachować te uprawnienia, aby móc edytować pliki po ponownym uruchomieniu urządzenia.Storage Access Framework persist permissions nie działa

Tak więc zgodnie z Storage Access Framework documentation używam uprawnień Persist, które dają użytkownikowi stały dostęp do plików za pośrednictwem aplikacji, nawet jeśli urządzenie zostało ponownie uruchomione.

Jednak po pewnym czasie zauważyłem, że dla niektórych użytkowników uprawnienia zostały w jakiś sposób unieważnione. Ponieważ gdy próbuję użyć SAF do pisania, uzyskuję po tym wyjątku android.system.ErrnoException: open failed: EACCES (Permission denied) , sprawdzam, jakie uprawnienia mam do dyspozycji, korzystając z mContext.getContentResolver().getPersistedUriPermissions(), ale zwracam pustą listę. Jestem pewien, że użytkownik dostarczył mi odpowiednie uprawnienia i że uprawnienia są dla aktualnie zainstalowanej karty SD, ponieważ śledzę te akcje w bazie danych.

Obecnie w tym przypadku wyświetlany jest selektor dokumentów, więc użytkownik może podać mi jeszcze raz nowe uprawnienia, ale poproszenie użytkownika o wykonanie tej samej akcji często nie jest przyjazne dla użytkownika.

Co może spowodować cofnięcie uprawnień? I jak mogę temu zapobiec?

Przetestowałem na wszystkich moich urządzeniach wiele restartów telefonu, zmieniając czas, usuwając wkładanie karty SD, ale nie mogłem stracić żadnego z bezpiecznych uprawnień.

mam następny kod dla uzyskania uprawnień:

private void openDocumentTree() { 
     Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 
     intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
     startActivityForResult(intent, REQUEST_CODE); 
    } 

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) { 
      Uri treeUri = data.getData(); 
      final int takeFlags = data.getFlags() & ( 
        Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
      mContext.getContentResolver().takePersistableUriPermission(treeUri, 
        takeFlags); 

        //this is my internal class for saving and restoring tree uri permissions. 
        final Permission permission = Permission.from(treeUri); 
        mPermissionDao.save(permission); 
     } 
    } 
+1

"Używam Android Framework bagażu dostęp do korzystania z niektórych plików na kartę SD" - nie, używasz do współpracy z SAF dokumenty. To, czy te dokumenty są przechowywane, zależy od użytkownika, a nie od ciebie. Mogą być zarządzane przez dowolnego dostawcę (Dysk Google, Dropbox itp.). "Jestem pewien, że użytkownik dostarczył mi odpowiednie uprawnienia i że uprawnienia są dla aktualnie zainstalowanej karty SD, ponieważ śledzę te akcje w bazie danych" - dokumenty, które wybiera użytkownik, nie muszą znajdować się na karcie SD. "Co może spowodować cofnięcie uprawnień?" - być może użytkownik usunął plik od dostawcy. – CommonsWare

+0

Używam Saf tylko do pracy z plikami na kartach SD, ze względu na specyfikę aplikacji, istnieje tylko powód do współpracy z zewnętrznym dostawcą pamięci. Sprawdzam, czy drzewo uri ma format pamięci zewnętrznej. –

+0

Być może użytkownik usunął plik od dostawcy - nie jest to możliwe, ponieważ otrzymałem URI drzewa, które reprezentuje ścieżkę główną zewnętrznej pamięci. Nie ma sposobu, aby go usunąć. Ponadto, jak już wspomniałem, nie byłem w stanie tworzyć nowych plików (to było wyrzucanie 'android.system.ErrnoException') i' getContentResolver(). GetPersistedUriPermissions() 'zwrócił pustą listę. Więc użytkownik w jakiś sposób odwołał uprawnienia. –

Odpowiedz

1

potrzebne są dodatkowe flagi przy żądaniu ACTION_OPEN_DOCUMENT_TREE.

openDocumentTree powinien wyglądać

private void openDocumentTree() { 
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 
    intent.addFlags(
     Intent.FLAG_GRANT_READ_URI_PERMISSION 
     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 
     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 
     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 
    startActivityForResult(intent, REQUEST_CODE); 
} 

docs recenzję dla FLAG_GRANT_PERSISTABLE_URI_PERMISSION i FLAG_GRANT_PREFIX_URI_PERMISSION