package org.deviceconnect.android.activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.support.annotation.NonNull;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* A utility class to make a permission request.
*
* @author NTT DOCOMO, INC.
*/
public final class PermissionUtility {
private PermissionUtility() {
}
/**
* パーミッションの許諾リクエストを要求する.
*
* <p>
* Android OS 6.0以上の端末では、このメソッドが呼び出されると内部でActivityが起動して、ユーザに対してパーミッションの許諾確認を行う。<br>
* ユーザから許可された場合には、{@link org.deviceconnect.android.activity.PermissionUtility.PermissionRequestCallback#onSuccess}が呼び出され、
* 拒否された場合には、{@link org.deviceconnect.android.activity.PermissionUtility.PermissionRequestCallback#onFail(String)}が呼び出される。
* </p>
* <p>
* Android OS 6.0未満の端末では、{@link org.deviceconnect.android.activity.PermissionUtility.PermissionRequestCallback#onSuccess}が常に呼び出される。
* </p>
* <br>
* サンプルコード:
* <pre>
* {@code
* String[] permissions = new String[] {
* Manifest.permission.ACCESS_COARSE_LOCATION,
* Manifest.permission.ACCESS_FINE_LOCATION
* }
*
* PermissionUtility.requestPermissions(getActivity(), new Handler(),
* permissions,
* new PermissionUtility.PermissionRequestCallback() {
* public void onSuccess() {
* // 許可された時の処理
* }
* public void onFail(final String deniedPermission) {
* // 拒否された時の処理
* }
* });
* }
* </pre>
* @param context コンテキスト
* @param handler ハンドラー
* @param permissions 許可を求めるパーミッション群
* @param callback 許諾通知を行うコールバック
*/
public static void requestPermissions(@NonNull final Context context, @NonNull final Handler handler,
@NonNull final String[] permissions, @NonNull final PermissionRequestCallback callback) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
callback.onSuccess();
} else {
Set<String> mPermissionSet = new HashSet<>(Arrays.asList(permissions));
if (mPermissionSet.size() == 0) {
callback.onSuccess();
return;
}
Set<String> tmp = new HashSet<>(mPermissionSet);
for (final String permission : tmp) {
if (context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
mPermissionSet.remove(permission);
}
}
if (mPermissionSet.size() == 0) {
callback.onSuccess();
} else {
String[] missingPermissions = mPermissionSet.toArray(new String[mPermissionSet.size()]);
PermissionRequestActivity.requestPermissions(context, missingPermissions, new ResultReceiver(handler) {
@Override
protected void onReceiveResult(final int resultCode, final Bundle resultData) {
String[] retPermissions = resultData.getStringArray(PermissionRequestActivity.EXTRA_PERMISSIONS);
int[] retGrantResults = resultData.getIntArray(PermissionRequestActivity.EXTRA_GRANT_RESULTS);
if (retPermissions == null || retGrantResults == null) {
callback.onFail(null);
return;
}
for (int i = 0; i < retPermissions.length; ++i) {
if (retGrantResults[i] == PackageManager.PERMISSION_DENIED) {
callback.onFail(retPermissions[i]);
return;
}
}
callback.onSuccess();
}
});
}
}
}
/**
* パーミッションの許諾リクエストの返答を通知するコールバック.
*/
public interface PermissionRequestCallback {
/**
* パーミッションが許可された場合に呼び出される.
*/
void onSuccess();
/**
* パーミッションが拒否されたときに呼び出される.
* @param deniedPermission 拒否されたパーミッション
*/
void onFail(@NonNull String deniedPermission);
}
}