2017-06-14 17 views
0

Je dois demander la permission pour les contacts et quand l'application commence, je demande, dans la partie ViewModel, je dois appeler la méthode qui nécessite une autorisation. J'ai besoin de vérifier l'autorisation est accordée par l'utilisateur ou non, puis appeler, mais pour vérifier la permission, j'ai besoin d'avoir accès à l'activité. alors que dans mon ViewModel je n'ai pas de référence à l'activité et je ne veux pas avoir, comment je peux surmonter le problème?Comment vérifier l'autorisation est accordée dans ViewModel?

+1

"donc dans la partie ViewModel j'ai besoin d'appeler la méthode qui nécessite une permission" - IMHO, c'est un bug d'architecture. Si un 'ViewModel' fonctionne avec quelque chose de beaucoup plus compliqué qu'un' Bitmap', alors votre 'ViewModel' a de mauvaises responsabilités. – CommonsWare

+0

@CommonsWare Dans ViewModel, j'appelle la méthode getContacts() ou toute autre méthode pour obtenir ce dont j'ai besoin. S'il y aura vérification que l'autorisation n'est pas accordée, la méthode ne sera pas appelée. Je ne sais pas où organiser la partie de vérification, comme dans ViewModel je ne veux pas avoir de référence à l'activité. –

+0

"Dans ViewModel, j'appelle la méthode getContacts() ou toute autre méthode pour ce dont j'ai besoin" - IMHO, quelque chose en dehors de 'ViewModel' devrait appeler' setContacts() 'sur' ViewModel'. Un 'ViewModel' devrait être un peu plus qu'un POJO. – CommonsWare

Répondre

0

Vous pouvez créer une classe PermissionRequester qui utilise le LocalBroadcastManager pour demander une autorisation avec une intention personnalisée. Votre activité de base résout cette demande d'autorisation et renvoie le résultat au PermissionRequester en utilisant également le LocalBroadcastManager. Votre ViewModel peut alors utiliser PermissionRequester.getInstance().requestPermission(permission) sans aucune connexion à votre activité. Voici un exemple de code pour PermissionRequester.java:

public class PermissionRequester { 

    private static PermissionRequester instance; 

    public static synchronized PermissionRequester getInstance() { 
     instance = instance == null ? new PermissionRequester() : instance; 
     return instance; 
    } 

    private final Map<String, WeakReference<OnResultListener>> pendingListeners = new HashMap<>(); 

    private PermissionRequester() { 
     LocalBroadcastManager.getInstance(MyApplication.getInstance()).registerReceiver(new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       String action = intent != null ? intent.getAction() : ""; 
       if ("ACTION_PERMISSION_REQUEST_RESPONSE".equals(action)) { 
        callbackListener(intent.getStringExtra("LISTENER"), intent.getIntExtra("RESULT", -1)); 
       } 
      } 
     }, new IntentFilter("ACTION_PERMISSION_REQUEST_RESPONSE")); 
    } 

    public void requestPermission(@NonNull OnResultListener listener, @NonNull String permission) { 
     pendingListeners.put(listener.getClass().getName() + listener.hashCode(), new WeakReference<>(listener)); 

     Intent requestPermissionIntent = new Intent("ACTION_REQUEST_PERMISSION"); 
     requestPermissionIntent.putExtra("PERMISSION", permission); 
     LocalBroadcastManager.getInstance(MyApplication.getInstance().getApplicationContext()).sendBroadcast(requestPermissionIntent); 
    } 

    private void callbackListener(String listener, int result) { 
     WeakReference<OnResultListener> listenerReference = pendingListeners.get(listener); 
     OnResultListener onResultListener = listenerReference != null ? listenerReference.get() : null; 
     if (onResultListener != null) { 
      pendingListeners.remove(listenerReference); 
      if (result == 1) { 
       onResultListener.onPermissionGranted(); 
      } else if (result == 0) { 
       onResultListener.onPermissionDenied(); 
      } 
     } 
    } 

    public interface OnResultListener { 
     void onPermissionGranted(); 
     void onPermissionDenied(); 
    } 
} 

Le code pour recevoir l'intention personnalisée dans votre activité de base est analogue à la réception du résultat dans le constructeur de PermissionRequester. Mais soyez conscient d'appeler registerReceiver dans onResume et unregisterReceiver dans .