2017-06-14 9 views
0

私は連絡先の許可を求める必要があります。アプリケーションが起動すると、ViewModelの部分では許可が必要なメソッドを呼び出す必要があります。私は許可されているかどうかをチェックする必要がありますか?私のViewModelではActivityへの参照がなく、問題を解決する方法はありません。権限を確認する方法はViewModelで許可されていますか?

+1

"ViewModelの部分では、私は許可が必要なメソッドを呼び出す必要があります" - IMHO、これはアーキテクチャのバグです。 'ViewModel'が' Bitmap'よりも複雑なもので動作している場合、あなたの 'ViewModel'は間違った責任を持ちます。 – CommonsWare

+0

@CommonsWare ViewModelでは、メソッドgetContacts()やその他の権限メソッドが必要です。パーミッションが与えられていないというチェックがある場合、メソッドは呼び出されません。 ViewModelのように、チェック部分を整理する場所がわかりません。私はActivityへの参照をしたくありません。 –

+0

"ViewModelでは、メソッドgetContacts()やその他の権限が必要なメソッドを呼び出す" - IMHO、 'ViewModel'以外のものは、' ViewModel'で 'setContacts()'を呼び出す必要があります。 'ViewModel'はPOJOのようなものではありません。 – CommonsWare

答えて

0

LocalBroadcastManagerを使用してカスタムインテントでアクセス権を要求するPermissionRequesterクラスを作成できます。あなたのベースアクティビティがこの許可要求を解決し、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のコンストラクタに結果の受信に類似しています。ただし、onResumeunregisterReceiverregisterReceiverをに記載してください。

関連する問題