HogeActivity.kt
class HogeActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
supportFragmentManager.beginTransaction().add(
android.R.id.content,
FugaFragment()).commitAllowingStateLoss()
}
@RequiresApi(Build.VERSION_CODES.M)
fun requestContactsPermission() {
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_CONTACTS)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == REQUEST_CONTACTS) {
if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 後続処理
}
}
}
companion object {
private const val REQUEST_CONTACTS = 0
}
}
FugaFragment.kt
class FugaFragment : Fragment() {
@TargetApi(Build.VERSION_CODES.M)
fun requestLocationPermission() {
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
if (requestCode == REQUEST_LOCATION) {
if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 後続処理
}
}
}
companion object {
private const val REQUEST_LOCATION = 1
}
}
ActivityとFragmentでそれぞれ別のパーミッションを要求/チェックする処理を実装した。
(例なのですごくシンプルに書いてます。)
これを実行したとき、FragmentのonRequestPermissionsResultが呼ばれずハマった。
Fragmentのコードを見てみる。
android.support.v4.app.Fragment.java
/**
* Callback for the result from requesting permissions. This method
* is invoked for every call on {@link #requestPermissions(String[], int)}.
* <p>
* <strong>Note:</strong> It is possible that the permissions request interaction
* with the user is interrupted. In this case you will receive empty permissions
* and results arrays which should be treated as a cancellation.
* </p>
*
* @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
* @param permissions The requested permissions. Never null.
* @param grantResults The grant results for the corresponding permissions
* which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
* or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
*
* @see #requestPermissions(String[], int)
*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
/* callback - do nothing */
}
普通にオーバーライドするだけで大丈夫そう。
FragmentActivityのコードを見てみる
android.support.v4.app.FragmentActivity.java
/**
* Callback for the result from requesting permissions. This method
* is invoked for every call on {@link #requestPermissions(String[], int)}.
* <p>
* <strong>Note:</strong> It is possible that the permissions request interaction
* with the user is interrupted. In this case you will receive empty permissions
* and results arrays which should be treated as a cancellation.
* </p>
*
* @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
* @param permissions The requested permissions. Never null.
* @param grantResults The grant results for the corresponding permissions
* which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
* or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
*
* @see #requestPermissions(String[], int)
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
int index = (requestCode >> 16) & 0xffff;
if (index != 0) {
index--;
String who = mPendingFragmentActivityResults.get(index);
mPendingFragmentActivityResults.remove(index);
if (who == null) {
Log.w(TAG, "Activity result delivered for unknown Fragment.");
return;
}
Fragment frag = mFragments.findFragmentByWho(who);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for who: " + who);
} else {
frag.onRequestPermissionsResult(requestCode & 0xffff, permissions, grantResults);
}
}
}
FragmentActivity#onRequestPermissionsResultから、Fragment#onRequestPermissionsResultを呼び出してた。
なので
HogeActivity.java
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
if (requestCode == REQUEST_CONTACTS) {
if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 後続処理
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Activityで要求した権限じゃないときは、super#onRequestPermissionsResultを呼び出すようにしたらうまく動いた。