web-dev-qa-db-ja.com

Android Marshmallow 6.0の実行時に権限をリクエストする

私はMarshmallow 6.0でアプリをテストしていますが、マニフェストですでに定義されている場合でも、Android.permission.READ_EXTERNAL_STORAGEは強制的にクローズされます。どこかで読んだことがあります。実行時に権限を要求しても、アプリケーションが強制的に閉じられることはありません。私は this Android document も読みました。これは、ランタイム権限をリクエストするためのものです。

したがって、Androidドキュメントに記載されている以下のような許可をリクエストできることがわかりました。

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

上記のコードには、結果を取得するコールバックメソッドonRequestPermissionsResultがあります。

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {

     }
}

私の質問は、ユーザーに許可を正確に要求する場所ですか?アプリの起動時にリクエスト権限を使用する必要がありますか、それとも権限が必要な場合と同じように使用する必要がありますか?

13
Pankaj

一般に、必要な権限を必要なときにすぐに要求します。このようにして、アクセス許可が必要な理由をユーザーに通知し、アクセス許可の拒否をはるかに簡単に処理できます。

アプリの実行中にユーザーが権限を取り消すシナリオを考えてみてください。起動時にリクエストし、後でチェックしない場合、予期しない動作や例外が発生する可能性があります。

3
Jörn Buitink

これは私のために働いています!!!アプリケーションのスプラッシュアクティビティで、次の操作を行います。

1)要求コードのint変数を宣言し、

private static final int REQUEST_CODE_PERMISSION = 2;

2)必要な権限の数で文字列配列を宣言し、

 String[] mPermission = {Manifest.permission.READ_CONTACTS, Manifest.permission.READ_SMS,
 Manifest.permission.ACCESS_FINE_LOCATION,
 Manifest.permission.WRITE_EXTERNAL_STORAGE};

3)次に、onCreateメソッドのランタイム権限の条件を確認します。

try {
            if (ActivityCompat.checkSelfPermission(this, mPermission[0])
                    != MockPackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.checkSelfPermission(this, mPermission[1])
                            != MockPackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.checkSelfPermission(this, mPermission[2])
                            != MockPackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.checkSelfPermission(this, mPermission[3])
                            != MockPackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(this,
                        mPermission, REQUEST_CODE_PERMISSION);

              // If any permission aboe not allowed by user, this condition will execute every tim, else your else part will work
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

4)次に、onRequestPermissionsResultメソッドを宣言してリクエストコードを確認します。

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.e("Req Code", "" + requestCode);
        if (requestCode == REQUEST_CODE_PERMISSION) {
            if (grantResults.length == 4 &&
                    grantResults[0] == MockPackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == MockPackageManager.PERMISSION_GRANTED &&
                    grantResults[2] == MockPackageManager.PERMISSION_GRANTED &&
                    grantResults[3] == MockPackageManager.PERMISSION_GRANTED) {

               // Success Stuff here

            }
        }

    }
7
Nanda Gopal

私の意見では、あなたの質問に対する正しい答えは1つではありません。この公式の 許可パターンページ をご覧になることを強くお勧めします。

Googleが提案するいくつかのこと:

「許可の戦略は、要求する許可のタイプの明確さと重要性によって異なります。これらのパターンは、ユーザーに許可を導入するさまざまな方法を提供します。」

「重要な権限は事前にリクエストする必要があります。セカンダリ権限はコンテキスト内でリクエストされる場合があります。」

「あまり明確でない許可は、事前に行われたか、コンテキストで行われたかに関係なく、許可に何が含まれるかについての教育を提供する必要があります。」

このイラスト は、理解を深める可能性があります。

ここで最も重要なことは、事前に許可を求める場合でも、コンテキストで許可を求める場合でも、ユーザーがいつでもこれらの許可を取り消すことができることを忘れないでください(たとえば、アプリがバックグラウンドで実行されている場合など)。

アプリの冒頭で許可を求め、ユーザーがその許可に関するユーザーの設定を変更していないと想定したからといって、アプリがクラッシュしないことを確認する必要があります。

3
Can Elmas

こうする

private static final int  REQUEST_ACCESS_FINE_LOCATION = 111;

あなたのonCreateで

boolean hasPermissionLocation = (ContextCompat.checkSelfPermission(getApplicationContext(),
            Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED);
    if (!hasPermissionLocation) {
        ActivityCompat.requestPermissions(ThisActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_ACCESS_FINE_LOCATION);
    }

次に結果を確認します

   @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {

        case REQUEST_ACCESS_FINE_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                Toast.makeText(ThisActivity.this, "Permission granted.", Toast.LENGTH_SHORT).show();

                //reload my activity with permission granted
                finish();
                startActivity(getIntent());

            } else
            {
                Toast.makeText(ThisActivity.this, "The app was not allowed to get your location. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
            }
        }

    }

}
2

ランタイム権限をリクエストするには、私は GitHub Library を使用します

Build.gradleファイルにライブラリを追加

dependencies {
     compile 'gun0912.ted:tedpermission:1.0.3'
}

アクティビティを作成してPermissionListenerを追加

public class MainActivity extends AppCompatActivity{

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);



    PermissionListener permissionlistener = new PermissionListener() {
        @Override
        public void onPermissionGranted() {
            Toast.makeText(RationaleDenyActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show();
            //Camera Intent and access Location logic here
        }

        @Override
        public void onPermissionDenied(ArrayList<String> deniedPermissions) {
            Toast.makeText(RationaleDenyActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
        }
    };


    new TedPermission(this)
            .setPermissionListener(permissionlistener)
            .setRationaleTitle(R.string.rationale_title)
            .setRationaleMessage(R.string.rationale_message) // "we need permission for access camera and find your location"
            .setDeniedTitle("Permission denied")
            .setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]")
            .setGotoSettingButtonText("Settings")
            .setPermissions(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            .check();
   }
}

string.xml

<resources>

    <string name="rationale_title">Permission required</string>
    <string name="rationale_message">we need permission for read <b>camera</b> and find your <b>location</b></string>

</resources>
1
Android Player
    Android Easy Runtime Permissions with Dexter:
    1. Dexter Permissions Library

    To get started with Dexter, add the dependency in your build.gradle

    dependencies {
        // Dexter runtime permissions
        implementation 'com.karumi:dexter:4.2.0'
    }

    1.1 Requesting Single Permission
    To request a single permission, you can use withPermission() method by passing the required permission. You also need a PermissionListener callback to receive the state of the permission.

    > onPermissionGranted() will be called once the permission is granted.

    > onPermissionDenied() will be called when the permission is denied. Here you can check whether the permission is permanently denied by using response.isPermanentlyDenied() condition.

    The below code requests CAMERA permission.

Dexter.withActivity(this)
                .withPermission(Manifest.permission.CAMERA)
                .withListener(new PermissionListener() {
                    @Override
                    public void onPermissionGranted(PermissionGrantedResponse response) {
                        // permission is granted, open the camera
                    }

                    @Override
                    public void onPermissionDenied(PermissionDeniedResponse response) {
                        // check for permanent denial of permission
                        if (response.isPermanentlyDenied()) {
                            // navigate user to app settings
                        }
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
                        token.continuePermissionRequest();
                    }
                }).check();

1.2 Requesting Multiple Permissions
To request multiple permissions at the same time, you can use withPermissions() method. Below code requests STORAGE and LOCATION permissions.

Dexter.withActivity(this)
                .withPermissions(
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                .withListener(new MultiplePermissionsListener() {
                    @Override
                    public void onPermissionsChecked(MultiplePermissionsReport report) {
                        // check if all permissions are granted
                        if (report.areAllPermissionsGranted()) {
                            // do you work now
                        }

                        // check for permanent denial of any permission
                        if (report.isAnyPermissionPermanentlyDenied()) {
                            // permission is denied permenantly, navigate user to app settings
                        }
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                        token.continuePermissionRequest();
                    }
                })
                .onSameThread()
                .check();
1
Akshaymahajan28

この関数を呼び出すと、カメラの許可とオーディオの録音の許可を求めるダイアログを開くことができます。

    if ( ActivityCompat.shouldShowRequestPermissionRationale (this, Manifest.permission.CAMERA) ||
            ActivityCompat.shouldShowRequestPermissionRationale (this,
                    Manifest.permission.RECORD_AUDIO) ) {
        Toast.makeText (this,
                R.string.permissions_needed,
                Toast.LENGTH_LONG).show ();
    } else {
        ActivityCompat.requestPermissions (
                this,
                new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO},
                CAMERA_MIC_PERMISSION_REQUEST_CODE);
    }
0
Deepika kapila

良い説明とハウツーはここにあります:

https://inthecheesefactory.com/blog/things-you-need-to-know-about-Android-m-permission-developer-edition/en

私が実行時に他のすべてのActivity.classの親であるBaseActivity.classで実行時に権限をチェックおよびリクエストするために、このコードを書きました:

public static final int PERMISSION_REQUEST = 42;
public static final int MULTIPLE_PERMISSION_REQUEST = 43;

//Marshmallow Permission Model
public boolean requestPermission(String permission /* Manifest.permission...*/) {
    if (ContextCompat.checkSelfPermission(this,
            permission) != PackageManager.PERMISSION_GRANTED) {
        if (Utils.hasMarshmallow())
            ActivityCompat.requestPermissions(this,
                    new String[]{permission}, PERMISSION_REQUEST
            );
        else {
            requestPermissions(new String[]{permission},
                    PERMISSION_REQUEST);
        }
        return false;
    } else {
        return true;
    }
}

public boolean requestPermission(String... permissions) {
    final List<String> permissionsList = new ArrayList<String>();

    for (String perm : permissions) {
        addPermission(permissionsList, perm);
    }

    if (permissionsList.size() > 0) {
        if (Utils.hasMarshmallow())
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    MULTIPLE_PERMISSION_REQUEST);
        else
            ActivityCompat.requestPermissions(this, permissionsList.toArray(new String[permissionsList.size()]),
                    MULTIPLE_PERMISSION_REQUEST);
        return false;
    } else
        return true;
}


private boolean addPermission(List<String> permissionsList, String permission) {
    if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
        permissionsList.add(permission);
        // Check for Rationale Option
        if (Utils.hasMarshmallow())
            if (!shouldShowRequestPermissionRationale(permission))
                return false;
    }
    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST:
        case MULTIPLE_PERMISSION_REQUEST: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

単に例の呼び出し:

activity.requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE);

結果が返されると、許可がすでに付与されているかどうかが通知されます。

0
Spektakulatius

https://material.io/guidelines/patterns/permissions.html このリンクは、アクセス許可を要求できるさまざまなタイプのシナリオを提供します。必要に応じて選択してください。

0
Abhigyan

短いコードが好きです。権限には RxPermission を使用します。

RxPermission は、1行だけで予期しないアクセス許可コードを作成する最良のライブラリです。

RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions
.request(Manifest.permission.CAMERA,
         Manifest.permission.READ_PHONE_STATE) // ask single or multiple permission once
.subscribe(granted -> {
    if (granted) {
       // All requested permissions are granted
    } else {
       // At least one permission is denied
    }
});

build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}

これは簡単ではありませんか?

0
Khemraj