私は現在、いくつかの「危険な」許可を必要とするアプリケーションに取り組んでいます。だから私はAndroid Marshmallow(API Level 23)で要求されているように "許可を求める"を追加しようとしましたが、それを行う方法が見つかりませんでした。
アプリで新しい権限モデルを使用してどのように権限を要求できますか?
以下のコードを使用してダイアログを開きます。
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
以下のようにアクティビティの結果を取得します。
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
より多くの情報: https://developer.Android.com/training/permissions/requesting.html
私が使っているこの構造は、私のアプリが許可を持っているかどうかを確認し、許可されていない場合はrequestより確認します。だから私がチェックしたいところから私のメインコードで以下を書く:
int MyVersion = Build.VERSION.SDK_INT;
if (MyVersion > Build.VERSION_CODES.Lollipop_MR1) {
if (!checkIfAlreadyhavePermission()) {
requestForSpecificPermission();
}
}
モジュールcheckIfAlreadyhavePermission()は以下のように実装されています。
private boolean checkIfAlreadyhavePermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
モジュールrequestForSpecificPermission()は以下のように実装されています。
private void requestForSpecificPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
}
アクティビティでオーバーライド:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 101:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//granted
} else {
//not granted
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
詳細については、このリンクを参照してください。 http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html
私はGoogleの開発者によって書かれたこのラッパー(推奨)を使用しました。その超使いやすいです。
https://github.com/googlesamples/easypermissions
確認を担当し、必要に応じて許可を求める機能
public void locationAndContactsTask() {
String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS };
if (EasyPermissions.hasPermissions(this, perms)) {
// Have permissions, do the thing!
Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
} else {
// Ask for both permissions
EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts),
RC_LOCATION_CONTACTS_PERM, perms);
}
}
ハッピーコーディング:)
Androidマシュマロから始めて、特定の権限をユーザーに要求する必要があります。許可がすでに与えられている場合は、コードをチェックすることもできます。これは一般的に必要な権限のリストです:
Android.permission-group.CALENDAR
- Android.permission.READ_CALENDAR
- Android.permission.WRITE_CALENDAR
Android.permission-group.CAMERA
- Android.permission.CAMERA
Android.permission-group.CONTACTS
- Android.permission.READ_CONTACTS
- Android.permission.WRITE_CONTACTS
- Android.permission.GET_ACCOUNTS
Android.permission-group.LOCATION
- Android.permission.ACCESS_FINE_LOCATION
- Android.permission.ACCESS_COARSE_LOCATION
Android.permission-group.MICROPHONE
- Android.permission.RECORD_AUDIO
Android.permission-group.PHONE
- Android.permission.READ_PHONE_STATE
- Android.permission.CALL_PHONE
- Android.permission.READ_CALL_LOG
- Android.permission.WRITE_CALL_LOG
- Android.permission.ADD_VOICEMAIL
- Android.permission.USE_SIP
- Android.permission.PROCESS_OUTGOING_CALLS
Android.permission-group.SENSORS
- Android.permission.BODY_SENSORS
Android.permission-group.SMS
- Android.permission.SEND_SMS
- Android.permission.RECEIVE_SMS
- Android.permission.READ_SMS
- Android.permission.RECEIVE_WAP_Push
- Android.permission.RECEIVE_MMS
- Android.permission.READ_CELL_BROADCASTS
Android.permission-group.STORAGE
- Android.permission.READ_EXTERNAL_STORAGE
- Android.permission.WRITE_EXTERNAL_STORAGE
権限を確認するためのサンプルコードは次のとおりです。
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
alertBuilder.setPositiveButton(Android.R.string.yes, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
}
});
} else {
ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
}
}
Activity
またはFragment
で要求ランタイム許可のための私のクラス
また、 根拠 またはopen 設定 を指定して、ユーザーが許可を拒否した後に許可を有効にする(Never ask again
の有無にかかわらず)オプションが簡単になるようにするのにも役立ちます。
class RequestPermissionHandler(private val activity: Activity? = null,
private val fragment: Fragment? = null,
private val permissions: Set<String> = hashSetOf(),
private val listener: Listener? = null
) {
private var hadShowRationale: Boolean = false
fun requestPermission() {
hadShowRationale = showRationaleIfNeed()
if (!hadShowRationale) {
doRequestPermission(permissions)
}
}
fun retryRequestDeniedPermission() {
doRequestPermission(permissions)
}
private fun showRationaleIfNeed(): Boolean {
val unGrantedPermissions = getPermission(permissions, Status.UN_GRANTED)
val permanentDeniedPermissions = getPermission(unGrantedPermissions, Status.PERMANENT_DENIED)
if (permanentDeniedPermissions.isNotEmpty()) {
val consume = listener?.onShowSettingRationale(unGrantedPermissions)
if (consume != null && consume) {
return true
}
}
val temporaryDeniedPermissions = getPermission(unGrantedPermissions, Status.TEMPORARY_DENIED)
if (temporaryDeniedPermissions.isNotEmpty()) {
val consume = listener?.onShowPermissionRationale(temporaryDeniedPermissions)
if (consume != null && consume) {
return true
}
}
return false
}
fun requestPermissionInSetting() {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val packageName = activity?.packageName ?: run {
fragment?.requireActivity()?.packageName
}
val uri = Uri.fromParts("package", packageName, null)
intent.data = uri
activity?.apply {
startActivityForResult(intent, REQUEST_CODE)
} ?: run {
fragment?.startActivityForResult(intent, REQUEST_CODE)
}
}
fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
if (requestCode == REQUEST_CODE) {
for (i in grantResults.indices) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
markNeverAskAgainPermission(permissions[i], false)
} else if (!shouldShowRequestPermissionRationale(permissions[i])) {
markNeverAskAgainPermission(permissions[i], true)
}
}
var hasShowRationale = false
if (!hadShowRationale) {
hasShowRationale = showRationaleIfNeed()
}
if (hadShowRationale || !hasShowRationale) {
notifyComplete()
}
}
}
fun onActivityResult(requestCode: Int) {
if (requestCode == REQUEST_CODE) {
getPermission(permissions, Status.GRANTED).forEach {
markNeverAskAgainPermission(it, false)
}
notifyComplete()
}
}
fun cancel() {
notifyComplete()
}
private fun doRequestPermission(permissions: Set<String>) {
activity?.let {
ActivityCompat.requestPermissions(it, permissions.toTypedArray(), REQUEST_CODE)
} ?: run {
fragment?.requestPermissions(permissions.toTypedArray(), REQUEST_CODE)
}
}
private fun getPermission(permissions: Set<String>, status: Status): Set<String> {
val targetPermissions = HashSet<String>()
for (p in permissions) {
when (status) {
Status.GRANTED -> {
if (isPermissionGranted(p)) {
targetPermissions.add(p)
}
}
Status.TEMPORARY_DENIED -> {
if (shouldShowRequestPermissionRationale(p)) {
targetPermissions.add(p)
}
}
Status.PERMANENT_DENIED -> {
if (isNeverAskAgainPermission(p)) {
targetPermissions.add(p)
}
}
Status.UN_GRANTED -> {
if (!isPermissionGranted(p)) {
targetPermissions.add(p)
}
}
}
}
return targetPermissions
}
private fun isPermissionGranted(permission: String): Boolean {
return activity?.let {
ActivityCompat.checkSelfPermission(it, permission) == PackageManager.PERMISSION_GRANTED
} ?: run {
ActivityCompat.checkSelfPermission(fragment!!.requireActivity(), permission) == PackageManager.PERMISSION_GRANTED
}
}
private fun shouldShowRequestPermissionRationale(permission: String): Boolean {
return activity?.let {
ActivityCompat.shouldShowRequestPermissionRationale(it, permission)
} ?: run {
ActivityCompat.shouldShowRequestPermissionRationale(fragment!!.requireActivity(), permission)
}
}
private fun notifyComplete() {
listener?.onComplete(getPermission(permissions, Status.GRANTED), getPermission(permissions, Status.UN_GRANTED))
}
private fun getPrefs(context: Context): SharedPreferences {
return context.getSharedPreferences("SHARED_PREFS_RUNTIME_PERMISSION", Context.MODE_PRIVATE)
}
private fun isNeverAskAgainPermission(permission: String): Boolean {
return getPrefs(requireContext()).getBoolean(permission, false)
}
private fun markNeverAskAgainPermission(permission: String, value: Boolean) {
getPrefs(requireContext()).edit().putBoolean(permission, value).apply()
}
private fun requireContext(): Context {
return fragment?.requireContext() ?: run {
activity!!
}
}
enum class Status {
GRANTED, UN_GRANTED, TEMPORARY_DENIED, PERMANENT_DENIED
}
interface Listener {
fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>)
fun onShowPermissionRationale(permissions: Set<String>): Boolean
fun onShowSettingRationale(permissions: Set<String>): Boolean
}
companion object {
const val REQUEST_CODE = 200
}
}
Activity
のように使う
class MainActivity : AppCompatActivity() {
private lateinit var smsAndStoragePermissionHandler: RequestPermissionHandler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
smsAndStoragePermissionHandler = RequestPermissionHandler(this@MainActivity,
permissions = setOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE),
listener = object : RequestPermissionHandler.Listener {
override fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>) {
Toast.makeText(this@MainActivity, "complete", Toast.LENGTH_SHORT).show()
text_granted.text = "Granted: " + grantedPermissions.toString()
text_denied.text = "Denied: " + deniedPermissions.toString()
}
override fun onShowPermissionRationale(permissions: Set<String>): Boolean {
AlertDialog.Builder(this@MainActivity).setMessage("To able to Send Photo, we need SMS and" + " Storage permission")
.setPositiveButton("OK") { _, _ ->
smsAndStoragePermissionHandler.retryRequestDeniedPermission()
}
.setNegativeButton("Cancel") { dialog, _ ->
smsAndStoragePermissionHandler.cancel()
dialog.dismiss()
}
.show()
return true // don't want to show any rationale, just return false here
}
override fun onShowSettingRationale(permissions: Set<String>): Boolean {
AlertDialog.Builder(this@MainActivity).setMessage("Go Settings -> Permission. " + "Make SMS on and Storage on")
.setPositiveButton("Settings") { _, _ ->
smsAndStoragePermissionHandler.requestPermissionInSetting()
}
.setNegativeButton("Cancel") { dialog, _ ->
smsAndStoragePermissionHandler.cancel()
dialog.cancel()
}
.show()
return true
}
})
button_request.setOnClickListener { handleRequestPermission() }
}
private fun handleRequestPermission() {
smsAndStoragePermissionHandler.requestPermission()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
smsAndStoragePermissionHandler.onRequestPermissionsResult(requestCode, permissions,
grantResults)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
smsAndStoragePermissionHandler.onActivityResult(requestCode)
}
}
Android-M、つまりAPI 23が導入されました Runtime Permissions Androidデバイスのセキュリティ欠陥を減らすため、runtime.soでユーザーがアプリのアクセス許可を直接管理できるようになりました。アプリケーションのクエリで言及した許可ダイアログを尋ねることでそれを取得する必要があります。
アクションの前に確認します。つまり、リソースにアクセスする許可があることを確認します link 。アプリケーションにその特定の許可がない場合は、許可を要求することができます link 以下のような許可要求応答。
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
最後に、強制終了を避けるために新しいバージョンを使用する予定がある場合は、 動作の変更 を実行することをお勧めします。
公式のサンプルアプリ こちら をご覧ください。
Android Marshmallow(API 23)以降では、デフォルトですべての危険な許可(公式doc 公式doc による)が無効になっています。アプリが初めて開いたときにインストールした後、あなたは実行時に許可を付与する必要があります。
私はこれを次のようにして達成しました:
public class MarshMallowPermission {
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_GALLERY = 0;
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_CAMERA = 1;
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE = 2;
public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
public static final int LOCATION_PERMISSION_REQUEST_CODE = 4;
Activity activity;
Context mContext;
public MarshMallowPermission(Activity activity) {
this.activity = activity;
this.mContext = activity;
}
public boolean checkPermissionForExternalStorage(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public boolean checkPermissionForCamera(){
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public boolean checkLocationPermission(){
int result = ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
public void requestPermissionForExternalStorage(int requestCode){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(mContext.getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
}
}
public void requestPermissionForCamera(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
Toast.makeText(mContext.getApplicationContext(), "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
}
}
public void requestPermissionForLocation(){
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)){
Toast.makeText(mContext.getApplicationContext(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
}
}
}
INあなたの活動クラス:
public class MainActivity extends AppCompatActivity{
private MarshMallowPermission marshMallowPermission;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("NavHome", "Oncreate_nav");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
marshMallowPermission = new MarshMallowPermission(MainActivity.this);
if (!marshMallowPermission.checkPermissionForExternalStorage()) {
marshMallowPermission.requestPermissionForExternalStorage(MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted successfully
} else {
//permission denied
}
break;
}
}
}
私はこれを基本フラグメントクラスとして使用しています。私はフラグメントから許可を要求するだけですが、あなたはそれをリファクタリングして同様のアクティビティバージョンを作ることができます。
public class BaseFragment extends Fragment {
private static final int PERMISSION_REQUEST_BLOCK_INTERNAL = 555;
private static final String PERMISSION_SHARED_PREFERENCES = "permissions";
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_BLOCK_INTERNAL) {
boolean allPermissionsGranted = true;
for (int iGranting : grantResults) {
if (iGranting != PermissionChecker.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (allPermissionsGranted && permissionBlock != null) {
permissionBlock.run();
}
permissionBlock = null;
}
}
public void runNowOrAskForPermissionsFirst(String permission, Runnable block) {
if (hasPermission(permission)) {
block.run();
} else if (!hasPermissionOrWillAsk(permission)) {
permissionBlock = block;
askForPermission(permission, PERMISSION_REQUEST_BLOCK_INTERNAL);
}
}
public boolean hasPermissionOrWillAsk(String permission) {
boolean hasPermission = hasPermission(permission);
boolean hasAsked = hasPreviouslyAskedForPermission(permission);
boolean shouldExplain = shouldShowRequestPermissionRationale(permission);
return hasPermission || (hasAsked && !shouldExplain);
}
private boolean hasPermission(String permission) {
return (ContextCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED);
}
private boolean hasPreviouslyAskedForPermission(String permission) {
SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
return prefs.getBoolean(permission, false);
}
private void askForPermission(String permission, int requestCode) {
SharedPreferences.Editor editor = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
editor.putBoolean(permission, true);
editor.apply();
requestPermissions(new String[] { permission }, requestCode);
}
}
使用する必要がある主な方法は2つあります。
hasPermissionOrWillAsk - これは、許可が要求され、再度要求されたくないユーザーによって拒否されているかどうかを確認するために使用します。これは、ユーザーが機能を必要としないことについて最終的な答えを出したときにUIを無効にするのに役立ちます。
runNowOrAskForPermissionsFirst - パーミッションを必要とするいくつかのコードを実行するためにこれを使います。ユーザーが既に許可を与えている場合は、コードがただちに実行されます。それ以外の場合、ユーザーが許可を与えた場合、コードは後で実行されます。それともまったく違います。コードを1か所で指定するので便利です。
これが例です:
mFragment.runNowOrAskForPermissionsFirst(Manifest.permission.ACCESS_FINE_LOCATION, new Runnable() {
@Override
public void run() {
...do something if we have permission...
}
});
これについてのフィードバックを得て幸せです。この特定の例は、位置情報サービスがデバイスで有効になっているかどうかも確認する必要があるという点で、少し単純化されています。また、一度に1つの権限しかサポートしませんが、一度に複数の権限をサポートする必要がある場合は、変更が簡単です。
もっときれいな方法かもしれません。すべての権限を次のように配列に追加します
private static final String[] INITIAL_PERMS={
Android.Manifest.permission.ACCESS_FINE_LOCATION,
Android.Manifest.permission.ACCESS_COARSE_LOCATION
};
private static final int INITIAL_REQUEST=1337;
あなたの許可が何であれ、それぞれの許可のためのメソッドを作成してください
@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canAccessFineLocation() {
return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canAccessCoarseLocation() {
return(hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION));
}
@RequiresApi(api = Build.VERSION_CODES.M)
private boolean hasPermission(String perm) {
return(PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}
このメソッドを onCreate で呼び出します。
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if(!canAccessCoarseLocation() || !canAccessFineLocation()){
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
}
}
onRequestPermissionsResult をオーバーライドします。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == INITIAL_REQUEST){
if (canAccessFineLocation() && canAccessCoarseLocation()) {
//call your method
}
else {
//show Toast or alert that this permissions is neccessary
}
}
}
ランタイム権限を処理するために、Googleはライブラリプロジェクトを提供しています。あなたはここからこれをチェックすることができます https://github.com/googlesamples/easypermissions
EasyPermissionsは、build.gradleファイルに次の依存関係を追加することによってインストールされます。
dependencies {
compile 'pub.devrel:easypermissions:0.3.0'
}
EasyPermissionsを使い始めるには、Activity(またはFragment)でonRequestPermissionsResultメソッドをオーバーライドします。
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Some permissions have been granted
// ...
}
@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
// Some permissions have been denied
// ...
}
}
ここでは、このライブラリがどのように動作するかの実用的な例を取得します https://github.com/milon87/EasyPermission
一度に複数の権限を取得する場合はこれを使用できます。私のためのこの仕事..私は別の解決策を得ました。あなたがあなたのtargetSdkVersionを22以下にするなら、それは私のために働きます。そしてそれはmanifest.xmlからパーミッションを取得するような振る舞いをします。テストして私のために働きます。
final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
private void insertDummyContactWrapper() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("GPS");
if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
permissionsNeeded.add("Read Contacts");
if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
permissionsNeeded.add("Write Contacts");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
insertDummyContact();
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
{
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
// All Permissions Granted
insertDummyContact();
} else {
// Permission Denied
Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
.show();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
詳細については。蛇腹リンクをチェック
バックグラウンドサービスで許可が必要なときに許可を要求する必要がある場合に使用できる優れたライブラリがあります。ライブラリの制限は、パーミッションが現在アプリに与えられているかどうかを判断するためには使用できないことです。アプリがまだ持っていない場合は、常にユーザーに確認します。
それは人生が簡単になりますようにそれを試してみてください: Androidのアクセス許可
これを試して
これはマシュマロ版で許可を求める最も簡単な方法です。
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED&&ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
//TO do here if permission is granted by user
}
else
{
//ask for permission if user didnot given
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION}, 0);
}
}
注: - マニフェストファイルにもこれと同じ権限を追加することを忘れないでください
<uses-permission Android:name="Android.permission.CAMERA" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
第2の方法 許可を確認するためのコードが付与されているかどうか
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA}, 1);
そしてメソッドをオーバーライドする
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
// grantResult[0] means it will check for the first postion permission which is READ_EXTERNAL_STORAGE
// grantResult[1] means it will check for the Second postion permission which is CAMERA
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
return;
}
}
}
以下のこのコードは完璧に動作します。例を使って説明しています。
私の場合、私はパーミッションチェックをutilクラスに分けて配置し、適切なクラスからチェックする必要がある特定のパーミッションを渡しました。
以下のコード部分は関数呼び出しを示しています。この場合はAndroid.Manifest.permission.READ_EXTERNAL_STORAGE
パーミッションを要求しています。
//the below call is from a fragment
@OnClick(R.id.button)//butterknife implementation
public void attachPressed() {
if (PermissionUtils.hasThisPermission(getContext(), Android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
onAttachPressed();
} else {
PermissionUtils.isPermissionRequestNeeded(getActivity(), this, Android.Manifest.permission.READ_EXTERNAL_STORAGE, PermissionUtils.REQUEST_GROUP_STORAGE);
}
}
上記の場合、onAttachPressed();
関数が呼び出されることが許可されているかどうかパーミッションがチェックされます。それ以外の場合はリクエストパーミッションがチェックされます。
以下は、私の場合はutilクラスに存在するコードですPermissionUtils
public final class PermissionUtils {
public static final int REQUEST_GROUP_STORAGE = 1508;
private PermissionUtils() {
}
public static boolean hasThisPermission(Context context, String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
} else {
return true;
}
}
public static boolean isPermissionRequestNeeded(Activity activity, Fragment fragment, String permission, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasThisPermission(activity, permission)) {
final String[] permissions = new String[]{permission};
if (fragment == null) {
activity.requestPermissions(permissions, requestCode);
} else {
fragment.requestPermissions(permissions, requestCode);
}
return true;
}
return false;
}
}
リクエスト後にonRequestPermissionsResult
から関数を呼び出したい場合、または関数呼び出しのためにもう一度ボタンを押す必要がある場合は、.
onRequestPermissionsResult
から呼び出すだけです。
//the below call is from a fragment
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PermissionUtils.REQUEST_GROUP_STORAGE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onAttachPressed();
} else {
Log.e("value", "Permission Denied, You cannot use local drive .");
}
}
たくさんのコードを書かずに許可を求める簡単な方法
https://github.com/sachinvarma/EasyPermission
追加する方法:
repositories {
maven { url "https://jitpack.io" }
}
implementation 'com.github.sachinvarma:EasyPermission:1.0.1'
許可を求める方法:
List<String> permission = new ArrayList<>();
permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE);
permission.add(EasyPermissionList.ACCESS_FINE_LOCATION);
new EasyPermissionInit(MainActivity.this, permission);
それが誰かに役立つことを願っています。
許可を求めるには RxPermission libraryを使用します。許可を求めるために書かなければならないのは長いコードだからです。
RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance // Must be done during an initialization phase like onCreate
rxPermissions
.request(Manifest.permission.CAMERA)
.subscribe(granted -> {
if (granted) { // Always true pre-M
// I can control the camera now
} else {
// Oups permission denied
}
});
あなたのbuild.gradle
にこれらの依存関係を追加してください
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}
すべての回答を確認しましたが、必要な回答が完全に満たされていないため、ユーザーが もう一度質問しない のチェックボックスをクリックしても、ここで作成して問題なく動作します。
readContacts()
のようにランタイムパーミッションを要求したいときに呼び出されるメソッドを作成するか、あるいは以下のようにopenCamera()
を持つこともできます。
private void readContacts() {
if (!askContactsPermission()) {
return;
} else {
queryContacts();
} }
これでaskContactsPermission()
を作成する必要があります。askCameraPermission()
、あるいはあなたが尋ねようとしているどんな許可でもそれを名付けることができます。
private boolean askContactsPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(parentLayout, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(Android.R.string.ok, new View.OnClickListener() {
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
}).show();
} else if (contactPermissionNotGiven) {
openPermissionSettingDialog();
} else {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
contactPermissionNotGiven = true;
}
return false;
}
この関数を書く前に、以下のインスタンス変数が示されているように定義されていることを確認してください。
private View parentLayout;
private boolean contactPermissionNotGiven;;
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
次に示すように、onRequestPermissionsResult
メソッドをオーバーライドする最後の手順です。
/**
* Callback received when a permissions request has been completed.
*/
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
queryContacts();
}
}
}
ここではRunTimeパーミッションの設定が完了しました。アドオンはopenPermissionSettingDialog()
です。これは、ユーザーが もう一度尋ねない チェックボックスをクリックしてパーミッションを永久に無効にした場合に設定画面を開きます。以下はその方法です。
private void openPermissionSettingDialog() {
String message = getString(R.string.message_permission_disabled);
AlertDialog alertDialog =
new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setMessage(message)
.setPositiveButton(getString(Android.R.string.ok),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
dialog.cancel();
}
}).show();
alertDialog.setCanceledOnTouchOutside(true);
}
何を逃しましたか? 1. strings.xml
で使われる文字列を定義する
<string name="permission_rationale">"Contacts permissions are needed to display Contacts."</string>
<string name="message_permission_disabled">You have disabled the permissions permanently,
To enable the permissions please go to Settings -> Permissions and enable the required Permissions,
pressing OK you will be navigated to Settings screen</string>
parentLayout
メソッド内でonCreate
変数を初期化する
parentLayout = findViewById(R.id.content);
AndroidManifest.xml
で必要な権限を定義する
<uses-permission Android:name="Android.permission.READ_CONTACTS" />
queryContacts
メソッド。あなたの必要性や、あなたがpermission
を必要としていた前に自分のメソッドを呼び出すことができる実行時の許可に基づいて。私の場合は、以下に示すように、ローダーを使用して連絡先を取得します。
private void queryContacts() {
getLoaderManager().initLoader(0, null, this);}
これはとても幸せなコーディングです:)
アプリケーション内のどこにでもランタイム権限 これは例です
use dependency
maven { url 'https://jitpack.io' }
dependencies {
implementation 'com.github.irshadsparky:PermissionLib:master-SNAPSHOT'
}
そしてこのようなコードを呼び出します。
PermissionHelper.requestCamera(new PermissionHelper.OnPermissionGrantedListener() {
@Override
public void onPermissionGranted() {
}
});
もっと見つけることができます Github
AndroidManifest.xmlに権限を追加します。
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
<application ...>
....
</application>
ランタイムの権限が必要かどうかをAndroidのバージョンで確認します。
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Lollipop_MR1) {
askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 1);
}
許可されていない場合は、許可を許可するようにユーザーに依頼してください。
private void askForPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(c, permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
Toast.makeText(c, "Please grant the requested permission to get your task done!", Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
}
}
}
許可が与えられたかどうかにかかわらず、何かをしてください。
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission with request code 1 granted
Toast.makeText(this, "Permission Granted" , Toast.LENGTH_LONG).show();
} else {
//permission with request code 1 was not granted
Toast.makeText(this, "Permission was not Granted" , Toast.LENGTH_LONG).show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
if (CommonMethod.isNetworkAvailable(MainActivity.this)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
Android.Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
//showing dialog to select image
callFacebook();
Log.e("permission", "granted Marshmallow");
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Android.Manifest.permission.READ_EXTERNAL_STORAGE,
Android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Android.Manifest.permission.CAMERA}, 1);
}
} else {
Log.e("permission", "Not Required Less than Marshmallow Version");
callFacebook();
}
} else {
CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this);
}
あなたは私のライブラリを使用することができます - NoPermission
compile 'ru.alexbykov:nopermission:1.1.1'
サンプル
PermissionHelper permissionHelper = new PermissionHelper(this); //don't use getActivity in fragment!
permissionHelper.check(Manifest.permission.READ_CONTACTS)
.onSuccess(this::onSuccess)
.onDenied(this::onDenied)
.onNeverAskAgain(this::onNeverAskAgain)
.run();
onRequestPermissionResult:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
私は、GoogleのEasyPermissions
よりもapiの方が便利だと思います。