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

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

新規登録して質問してみよう
ただいま回答率
85.47%
Android

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

Q&A

解決済

1回答

2815閲覧

PermissionsDispatcherの使い方について

komon4242

総合スコア21

Android

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

0グッド

0クリップ

投稿2017/11/30 07:54

編集2017/12/03 07:35

いつもお世話になっています。

Androidの端末ストレージから画像を読込む処理が必要なためpermission.READ_EXTERNAL_STORAGEを許可するMパーミッション対応を行いました。

Mパーミッションの実装はPermissonDispatcherを使用させて頂きました。
https://qiita.com/kazy/items/0ded30d80cef9df54c98 を参考にさせていただきました。

以下の様に変更しました(gradleの設定は省略しています)

java

1 2import android.Manifest; 3import android.database.Cursor; 4import android.net.Uri; 5import android.os.Bundle; 6import android.provider.MediaStore; 7import android.support.v7.app.AppCompatActivity; 8import android.widget.CursorAdapter; 9import android.widget.GridView; 10 11import permissions.dispatcher.NeedsPermission; 12import permissions.dispatcher.RuntimePermissions; 13/* 14 * 15 * 端末のストレージから画像を読み込むために READ_EXTERNAL_STORAGE のMパーミッション対応をしています。 16 * Mパーミッション実装のためにPermissionsDispatcherを利用しています。 17 * 18*/ 19 20@RuntimePermissions 21public class MainActivity extends AppCompatActivity { 22 23 private GridView mGridView = null; 24 25 @NeedsPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_main); 30 31 // パーミッションの要求 32 MainActivityPermissionsDispatcher.onCreateWithPermissionCheck(this, savedInstanceState); 33 } 34 35 @Override 36 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 37 MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); 38 39 // ここで Cursor を使って端末ストレージから画像を取得する 40 } 41} 42

起動してパーミッションの許可を求めるダイアログの表示まではうまくいきました。
しかしパーミッションの「許可」を行った所、onRequestPermissionsResultでエラーが起きて落ちました。

11-30 16:45:20.880 26358-26358/hoge.example.com.gridviewapplication E/AndroidRuntime: FATAL EXCEPTION: main Process: hoge.example.com.gridviewapplication, PID: 26358 java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=0, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {hoge.example.com.gridviewapplication/hoge.example.com.gridviewapplication.MainActivity}: java.lang.IllegalStateException: Already attached at android.app.ActivityThread.deliverResults(ActivityThread.java:3699) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) at android.app.ActivityThread.-wrap16(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.IllegalStateException: Already attached at android.support.v4.app.FragmentManagerImpl.attachController(FragmentManager.java:2939) at android.support.v4.app.FragmentController.attachHost(FragmentController.java:104) at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:275) at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84) at hoge.example.com.gridviewapplication.MainActivity.onCreate(MainActivity.java:31) at hoge.example.com.gridviewapplication.MainActivityPermissionsDispatcher$MainActivityOnCreatePermissionRequest.grant(MainActivityPermissionsDispatcher.java:71) at hoge.example.com.gridviewapplication.MainActivityPermissionsDispatcher.onRequestPermissionsResult(MainActivityPermissionsDispatcher.java:36) at hoge.example.com.gridviewapplication.MainActivity.onRequestPermissionsResult(MainActivity.java:61) at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582) at android.app.Activity.dispatchActivityResult(Activity.java:6460) at android.app.ActivityThread.deliverResults(ActivityThread.java:3695) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)  at android.app.ActivityThread.-wrap16(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5417)  at java.lang.reflect.Method.invoke(Native Method) 

「何度も呼んでんじゃねぇよ!」的なエラーですが、これはどうすれば解決しますか?
try ~ catch で投げるしかないのでしょうか?

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keicha_hrs

2017/12/01 18:41 編集

記事見出し及び本文中のPermissonDispatcherの綴りが微妙に誤っていますので、修正していただけると今後の閲覧者のためにもなるかと思います(解決済になってしまうと直せないのかな?)。
komon4242

2017/12/03 07:33

ご指摘ありがとうございます。修正できるかやってみます。
guest

回答1

0

自己解決

考え方が間違っていました。

@NeedsPermission(Manifest.permission.READ_EXTERNAL_STORAGE)をMパーミッションの要求が呼ばれるメソッドで呼ぶものだと思い込んでいました。
実際は、許可した場合に呼び出すメソッドを認識させるためのアノテーションでした。
書き直しましたのでこれで解決とさせて下さい。

java

1@RuntimePermissions 2public class MainActivity extends AppCompatActivity { 3 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 10 MainActivityPermissionsDispatcher.getThumbnailWithPermissionCheck(this); 11 } 12 13 // 許可した場合はこっちが呼ばれる(一度許可すれば設定で制限を外すまでこちらが呼ばれる) 14 @NeedsPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 15 void getThumbnail() { 16 // TODO: ここにサムネイルを取得した時の処理を書く 17 } 18 19 // 絶対に表示しない状態で呼ばれる 20 @OnNeverAskAgain(Manifest.permission.READ_EXTERNAL_STORAGE) 21 void onNeverAskAgain() { 22 Toast.makeText(this, "call @OnNeverAskAgain", Toast.LENGTH_SHORT).show(); 23 } 24 25 // 許可しない状態の時に呼ばれる(onNeverAskAgain -> onRequestPermissionsResult) 26 @Override 27 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 28 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 29 MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); 30 31 Toast.makeText(this, "call onRequestPermissionsResult", Toast.LENGTH_SHORT).show(); 32 } 33 34 // 許可しない 35 @OnShowRationale(Manifest.permission.READ_EXTERNAL_STORAGE) 36 void onShowRationale(final PermissionRequest request) { 37 Toast.makeText(this, "call @OnShowRationale", Toast.LENGTH_SHORT).show(); 38 39 new AlertDialog.Builder(this) 40 .setTitle("警告") 41 .setMessage("ストレージの権限を許可しないとサムネイルを取得することが出来ません。アプリを使いたい場合は許可して下さい。") 42 .setPositiveButton("OK", new DialogInterface.OnClickListener() { 43 @Override 44 public void onClick(DialogInterface dialog, int which) { 45 // パーミッション許可ダイアログ 46 request.proceed(); 47 } 48 }) 49 .setNegativeButton("Cancel", null) 50 .show(); 51 } 52}

投稿2017/12/01 08:08

編集2017/12/05 04:32
komon4242

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問