41
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Fragment#requestPermissions() でハマった

Last updated at Posted at 2015-06-29

Android M から新しいパーミッションモデルになり、アプリから一部のパーミッションの権限を要求することが可能になりました。この実装を調べていてハマったところがあるので共有します。

パーミッション権限を要求するときは以下のような感じです。

公式には、 Activity#requestPermissions() を呼び出して、要求結果を Activity#onRequestPermissionsResult() で受け取る、と書いてあります。

if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant

    return;
}

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! do the
                // calendar task you need to do.

            } else {

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

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

ハマったところ

1. Fragment にも requestPermissions() はある

@hotchemi のおかげで Fragment にも requestPermissions() が実装されてるのを知りました。公式を見る限り Activity だけにしか無いように見えるのつらい...

Android M Preview 版のソースコードを見ると、ちゃんと requestPermissions()onRequestPermissionsResult() が実装されていることが分かりました。

なので、安心して Fragment でパーミッション要求を実装できそうですね!!!!!!!!

package android.app;

public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {

    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        if (mHost == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        Intent intent =
                mHost.getContext().getPackageManager().buildRequestPermissionsIntent(permissions);
        mHost.onStartActivityFromFragment(this, intent, requestCode, null);
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        /* callback - do nothing */
    }

2. Fragment に requestPermissions() はなかった

タイトル詐欺です。

Fragment に requestPermissions() があるとのことなので、満身創痍で App Permission のサンプルを実装していましたが、コード補完に requestPermissions() が候補リストに出てきませんでした!!!!!!!!!!!!!!!!

スクリーンショット 2015-06-29 16.46.34.png

「うーーーん......うーーーん......」と時間を無駄に消費したのですが、原因はすごく簡単に解決できるものでした。

まちがい

import android.support.v4.app.Fragment;

public class PermissionFragment extends Fragment {

    private void requestReadContactsPermission() {
        requestPermissions(
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    }

せいかい

import android.app.Fragment;

public class PermissionFragment extends Fragment {

    private void requestReadContactsPermission() {
        requestPermissions(
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    }

まとめ

現状はイカのどれかで対処する必要があります。

  • android.app.Fragment のほうを import する
  • support v4 のアップデートを待つ
  • Activity のほうで実装

無駄にハマった...

追記 7/13

support v4 のソースコードを見たら

    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        if (mHost == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        mHost.onRequestPermissionsFromFragment(this, permissions,requestCode);
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        /* callback - do nothing */
    }

    public boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
        if (mHost != null) {
            return mHost.onShouldShowRequestPermissionRationale(permission);
        }
        return false;
    }

のように、ちゃんと実装されていました。なので、安心して v4 を使えますね。

41
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?