2017-06-14 110 views
0

我需要問聯繫人的權限和應用程序啓動時我問,在ViewModel部分我需要調用需要權限的方法。我需要檢查權限是否由用戶授權然後調用,但爲了檢查權限,我需要訪問活動。而在我的ViewModel中,我沒有對Activity的引用,也不想擁有,我該如何克服這個問題?在ViewModel中如何檢查權限?

+1

「所以在ViewModel部分我需要調用需要權限的方法」 - 恕我直言,這是一個架構錯誤。如果一個'ViewModel'處理比'Bitmap'更復雜的任何事情,那麼你的'ViewModel'就有錯誤的職責。 – CommonsWare

+0

@CommonsWare在ViewModel中,我調用方法getContacts()或任何其他方法來獲得我需要的權限。如果將檢查權限未被授予,該方法將不會被調用。我不知道在哪裏組織檢查部分,因爲在ViewModel中我不想引用Activity。 –

+0

「在ViewModel中,我調用方法getContacts()或任何其他方法來獲取我需要的權限」 - 恕我直言,ViewModel之外的某些東西應該調用'ViewModel'上的'setContacts()'。一個'ViewModel'應該只是一個POJO。 – CommonsWare

回答

0

您可以創建PermissionRequester類,該類使用LocalBroadcastManager來請求具有自定義意圖的權限。您的基本活動將解析此權限請求,並使用LocalBroadcastManager將結果發送回PermissionRequester。您的ViewModel然後可以使用PermissionRequester.getInstance().requestPermission(permission),而無需連接到您的活動。爲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(); 
    } 
} 

的代碼,即可獲得在你的基地活動自定義意圖是類似於結果在PermissionRequester的構造函數接收。但請注意撥打registerReceiver,onResumeunregisterReceiver的。