web-dev-qa-db-ja.com

Android Marshmallowのサービスに許可をリクエストする方法

Android Marshmallowでは、アプリのインストール時に一度にではなく、必要に応じて実行時に権限を要求する必要があります。ただし、アクティビティから権限を要求するようにしか思えないことがあります。これは、アプリにサービスのみが含まれているため問題です。 (それはなぜでしょうか?アプリにはAndroid Wearウォッチフェイスがバンドルされており、携帯電話は時計に送信するために近くの写真を検索するだけです-アクティビティは不要です。場所の許可。)

だから、サービスから許可を要求する方法はありますか?または、過去のように、インストール時に何らかの方法で許可を強制しますか?

95
Tony Wickham

requestPermission()は、Activityからではなく、Serviceからのみ呼び出すことができます(PackageManagerのみを必要とするcheckPermission()とは異なります)。そのため、それを回避するには追加の作業が必要です。アプリでActivityを提供する必要があります。たとえば、Serviceは必要な許可を確認できます。まだ許可されていない場合、通知を作成し、理由を説明する短いメッセージでユーザーに通知できます。通知があり、通知をクリックしたときに何をする必要があるかなど。

40
Ali Naddaf

これはサービスにとって非常に面倒です。Android Developer Previewページで問題を報告する必要があると思います。

現時点では、最善の解決策はサービスの許可を確認し、許可がない場合に通知を表示することだと思います。さらに良いことに、ユーザーが通知を押したときに許可を要求するDialogActivityを作成します。

14
Derek Fung

PermissionEverywhere ライブラリをご覧ください。任意のコンテキストから許可をリクエストできます。

クリックして通知を作成し、それをクリックして許可を求めるアクティビティを開きます。

ライブラリのgithubページからのサンプルコード:-

@Override
  protected Boolean doInBackground(Void... params) {
      PermissionResponse response = PermissionEverywhere.getPermission(getApplicationContext(), 
      new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
              REQ_CODE,
              "Notification title", 
              "This app needs  a write permission", 
              R.mipmap.ic_launcher)
              .call();
      //waits..
      boolean isGranted = response.isGranted();

      if(isGranted){ //changed from isGrante to isGranted
      // Do stuff
      }
  }
7
Heisenberg

これを正確に行うことができる非常にシンプルなライブラリがあります。アプリがフォアグラウンドまたはバックグラウンドのどちらにあるかに基づいて、どこからでも(サービスからでも)アクセス許可を確認できます。通常のダイアログを表示するか、アクセス許可を求める通知を生成します。コードは非常に理解しやすく、非常に使いやすいです。

試してみてください: Android Permissions

2
Nishkarsh
@SuppressLint("NewApi")
public void checkPerm() 
{
   locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

   if ( checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
      return;
   }

   locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {....}
}
0