質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.46%

  • Android

    6632questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android6.0以上で端末(OS)によってonRequestPermissionsResultが呼ばれないケースはありますか?

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,461

okashi123

score 26

端末によってonRequestPermissionsResultが呼ばれないケースがあるのですがなぜなんでしょうか。
どなたかご存知でしょうか。

以下の内容で権限の許可を行った際に「Nexus 5X Android7.1.2」ではonRequestPermissionsResultが呼ばれ「Nexus 5 Android6.0.1」では呼ばれませんでした。

追記(2017/09/21 19:38)------------
正確にはAndroid6では権限選択後(選択時?)にアプリが終了するような動作をして権限選択後にアプリを再起動する羽目になってしまいます。再起動時にはonRequestPermissionsResultが呼ばれます。
Android7では再起動せずonRequestPermissionsResultが呼び出されます。
Android6でも再起動しないようにしたいのですがどなたかご存知でしょうか

compileSdkVersion 26
buildToolsVersion '26.0.1'
dependencies {
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
compile 'com.google.android.gms:play-services:7.3.0'
}
でビルドしています

public class MainActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
    int requestCode = 1;


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


    private void getPermission(){
        Log.d("getPermission","start");
        String[] permissions = {
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        ActivityCompat.requestPermissions(MainActivity.this, permissions, requestCode);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        Log.d("onRequestRes",requestCode +" / "+ Arrays.toString(permissions)+" / "+Arrays.toString(grantResults));
    }
}


ログ(Android6)

09-22 10:56:44.274 29465-29465/permission.test D/getPermission: start
09-22 10:56:44.292 29465-29568/permission.test D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
09-22 10:56:44.330 29465-29568/permission.test I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 10/21/15, 369a2ea, I96aee987eb
09-22 10:56:44.332 29465-29568/permission.test I/OpenGLRenderer: Initialized EGL, version 1.4
09-22 10:56:47.327 29465-29465/permission.test D/getPermission: start
09-22 10:56:47.327 29465-29465/permission.test W/Activity: Can reqeust only one set of permissions at a time
/**
*権限入力後(ログは出ませんでした)
**/


ログ(Android7)

09-22 11:07:47.232 25582-25582/permission.test  D/getPermission: start
09-22 11:07:47.232 25582-25582/permission.test  W/Activity: Can reqeust only one set of permissions at a time
/**
*権限入力後
**/
09-22 11:08:03.657 25582-25582/permission.test  D/onRequestRes: 1 / [android.permission.READ_PHONE_STATE, android.permission.ACCESS_FINE_LOCATION, android.permission.WRITE_EXTERNAL_STORAGE] / [0, 0, 0]
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • abs123

    2017/09/21 14:11 編集

    gradleのdependenciesに設定しているサポートライブラリとそのバージョンを追記してください。

    キャンセル

  • okashi123

    2017/09/21 19:45

    すいません、バタバタしてて遅れましたが更新いたしました

    キャンセル

回答 4

checkベストアンサー

+1

全くのカンですが。

ActivityCompatを使っているという事は、サポートライブラリを使ってますよね?
であれば、

//public class MainActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
public class MainActivity extends FragmentActivity {

でどうですか。

 Fragmentは使ってなくても構いません。FragmentActivityを継承してください。


アクティビティのライフサイクルは、しっかり把握していますか?

アクティビティがバックグラウンドに移行した以上、いつ破棄されても文句は言えない。(通知はする。)それがAndroidの仕様です。
Nexus5X(Android7)でも、権限確認中に他のアプリを起動したり、長時間放置すれば起きる可能性はあると思います。(もしかすると、画面の向きを変えても起きるかもしれません)

対処としては、破棄を禁止するのではなく、その下の「アクティビティの状態を保存する」に書かれているとおり、Activity#onSaveInstanceStateメソッドで権限確認中かどうかを保存しておき、Activity#onCreateメソッドで引数に渡されたステートを見て処理を振り分けるようにするのが、まっとうな対処だと思います。

アクティビティのライフサイクルについては非常に厄介なので、他にも検索していろんなサイトの情報を見て調べてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/21 12:25

    継承してみましたが変わりませんでした・・・

    キャンセル

  • 2017/09/24 13:29

    なるほど、権限入力の際はバックグラウンド扱いになるという認識でよろしいでしょうか?
    となると権限入力の後確実に動作する保障は無いということになるんでしょうか。

    ライフサイクルについて情報を集めてみることにします。ありがとうございます

    キャンセル

  • 2017/09/25 12:44

    ありがとうございました!
    おかげで原因がわかりました

    キャンセル

0

OnRequestPermissionsResultCallbackはAPI 23から実装された機能で、compileSdkVersionが21ではコンパイルが通らないはずですが。


ActivityCompatはSupport Libraryによって提供されるので、compileSdkVersionが23未満でも使用することができました。その点は訂正します(取り消し線を使いたかったのだが、teratailのMarkdownは取り消し線をサポートしていない・・・?)。ただ、Runtime Permissionに関する機能はやはりcompileSdkVersionを23以上にしなければコンパイルを通せず、むしろ私が21で実現する知識を有していないようです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/20 11:27

    諸事情によりcompileSdkVersion 21を利用する必要があるため、今回は省略していますが実際のソースではバージョンによって権限処理の切り分けを行っています。

    念のためcompileSdkVersion 25を利用してビルドしても同じ現象が発生しています

    キャンセル

  • 2017/09/21 07:36 編集

    余談ですが、ACCESS_FINE_LOCATIONはDangerous permissionではないので、Runtime Permissionによって許可を得る必要のない権限です。ですから、requestPermissions()で要求するリストに加える意味はありません(AndroidManifest.xmlへの記述は従来通り必要)。加えることで害があるわけでもないんだけど。

    キャンセル

  • 2017/09/21 12:25 編集

    ACCESS_FINE_LOCATIONはDangerous permissionのはずですが。。
    https://developer.android.com/guide/topics/security/permissions.html?hl=ja#perm-groups

    キャンセル

  • 2017/09/21 13:27 編集

    申し訳ありません、それも勘違いでした…。何やってるんだろうね。寝呆けてばかりだ。

    キャンセル

  • 2017/09/22 06:44

    外したコメントでご迷惑をおかけしてばかりで、コメントするのが怖いですが・・・(苦笑)

    「アプリが終了するような動作」をしたときには、エラーを示すログが出力されているのでしょうか。また、そのログを追加で示することはできないでしょうか。(それを見てわかるのか何とも言えないが)

    それから、現状示されているコードは常にActivityCompat.requestPermissions()を呼ぶ形となっていますが、すでに許可を得ているか調べるContextConpat.checkSelfPermission()で調べて、PERMISSION_GRANTEDではない場合のみrequestPermissions()を呼ぶ構成とするわけにはいかないのでしょうか。また、そうすることで「アプリが終了」することを回避することができませんか?

    requestPermissions()を常に呼び、onRequestPermissionsResult()の結果も常に受け取って、且つアプリが終了しないことが必須条件であるならば、上記もやはりスカ提案となってしまいますが・・・。

    キャンセル

  • 2017/09/22 11:18

    いえいえ詰まっているのでとてもありがたいです。
    エラーログ事態は出ていません。。一応ログ情報を追加しました、

    このソースからは問題を調べるために除いていますが実際のソースには権限を取得済みかチェックする処理を入れています。

    現状だとアプリインストール時にAndroid6でどうしても再起動することになってしまうのでそれをなるべく避けたいんですよね

    キャンセル

  • 2017/09/24 07:59 編集

    返信が遅れ気味ですみません。

    D/onRequestRes: 1 / [] / []

    このログはなんですか?[]の中は編集されたのですか?それとも、こういうログが本当に出ているのですか?本当に出ているのだとしたら、これが出る直前のrequestPermissions()の第2引数や、onRequestPermissionsResult()の第2引数と第3引数にはどんな値が入っているのでしょうか?

    こんな動作あり得るのだろうか?と不思議な感じがします。

    キャンセル

  • 2017/09/24 13:16 編集

    ログはonRequestPermissionsResultのLog.d("onRequestRes",requestCode +" / "+ Arrays.toString(permissions)+" / "+Arrays.toString(grantResults));
    が表示されています。[]の編集は行っていません

    android7でも同じように呼び出されその後もう一度onRequestPermissionsResultが呼びされている(Android6では呼ばれない)のでこういうものなのかと思っていました

    キャンセル

  • 2017/09/25 01:33 編集

    いや、さすがにどのLog.dによるログなのかというのはわかりますが・・・。

    そうではなく、ここでの表示が[]になるような引数でonRequestPermissionsResult()が呼ばれること自体が奇っ怪ではないかという話です。通常は、requestPermissions()を呼び出し、ポップアップで何かしらの入力を行うことで、初めてonRequestPermissionsResult()が呼び出されるはずです。

    ところが、「何も入力していない」のにonRequestPermissionsResult()が呼び出されているというのはおかしな話です。しかも[]が表示されるような引数になっているのも妙ですし。

    例えば、

    String[] permissions = {""};
    ActivityCompat.requestPermissions(MainActivity.this, permissions, requestCode);

    こういうコードをAndroid 6.0のAVDで動かす実験をしてみました。すると、ポップアップが出ることなくonRequestPermissionsResult()が呼び出され、そのログ出力は

    D/onRequestRes: 1 / [] / [-1]

    のようになっていました。それでもgrantResults[0]が-1になっているので同じ挙動ではないのだけど(同じ挙動になる方法を探してみたが見つからなかった)。

    このような不当な引数の与え方をしていて、それが落ちる原因になっていないか?とも思えます(この実験では落ちなかったけど)。

    キャンセル

  • 2017/09/25 09:07

    それと、

    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'

    とアルファ版のサポートライブラリーを使うのではなく、最新正式版である

    compile 'com.android.support:appcompat-v7:26.1.0'

    とした方がいいでしょう。ただ、26.0.0の正式版以降はgoogleのmavenリポジトリーから取得する方針になったようなので、build.gradle (project) に

    allprojects {
    repositories {
    jcenter()
    maven { url 'https://maven.google.com' }
    }
    }

    のようにリポジトリーのURLを追記する必要があります。

    まあ、この質問の本質にはあまり関係ないと思うけど。

    キャンセル

  • 2017/09/25 11:05

    大変失礼いたしました。、ログの取得に使用するソースが間違えてgetPermissionを2度呼び出していました。
    ログが2つ出ていたのはそれが原因だったようです。修正いたしました。

    キャンセル

0

    private static int requestCode = 1;


にしても同じ挙動でしょうか??

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/25 10:51

    変わりませんでした。

    キャンセル

0

解決しました。
AndroidManifest.xmlにてandroid:noHistory="true"が使用されていました。
そのためアプリがバックグラウンドになった際にキルされていたようです。
提示していた情報とは関係のないところに問題があり申し訳ありません。

ご意見くださった皆様本当にありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

同じタグがついた質問を見る

  • Android

    6632questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。