Androidランタイムパーミッションの例
以下の内容を日本語で一つのオプションをご提供いたします:
Androidランタイムパーミッションのサンプルへようこそ。Android 6.0 Marshmallowの導入により、Googleはアプリによって扱われるアプリケーションの許可方法を変更しました。このチュートリアルでは、新たに導入されたAndroidランタイムパーミッションとその扱い方について見ていきます。適切に処理されていない場合、アプリのクラッシュを引き起こす可能性があります。
Androidランタイムパーミッションとは何ですか?
Android 6.0(SDK23)の導入により、ユーザーは必要になった時に特定のパーミッションの要求が表示されます。ですので、私たちが最初に思いつく質問は、古いアプリはアンドロイドマシュマロで動くのでしょうか?答えは、targetSdkVersionが22以下の場合、はいです。そのため、現行のアンドロイドのパーミッションは後方互換性があります。これは、sdkのバージョンを22に設定することで、古いモデルのパーミッションを使用できるという意味ではありません。マシュマロを使用しているユーザーは、設定→アプリ→許可から危険なパーミッション(後で危険なものと通常のものについて話します)を取り消すことができます。したがって、まだ許可されていないパーミッションを必要とする関数を呼び出そうとする場合、関数は突然例外(java.lang.SecurityException)をスローし、アプリがクラッシュします。したがって、私たちは新しいアンドロイドパーミッションモデルをアプリケーションに実装する必要があります。
危険なアンドロイドの許可設定と通常のアンドロイドの許可設定
Androidでは、一部の権限を危険なものとして定義し、一部を通常のものとしています。両方のタイプに共通の点は、それらがマニフェストファイルで定義される必要があることです。Android 6.0以降では、実行時には危険な権限のみがチェックされ、通常の権限はチェックされません。通常の権限の例としては、android.permission.INTERNETがあります。危険な権限は、ユーザーがアプリケーションに許可する内容を理解しやすくするためにカテゴリに分けられています。ユーザーがグループやカテゴリ内の1つの権限を承諾すると、グループ全体を承諾したとみなされます。危険な権限の例としては、android.permission.FINE_LOCATIONとandroid.permission.COARSE_LOCATIONがあります。位置情報のいずれかの権限を有効にすると、すべての権限が有効になります。
Androidランタイムパーミッションのリクエストをお願いします。
requestPermissions(String[] permissions, int requestCode);というメソッドは、危険なパーミッションをリクエストするために使用される公開メソッドです。複数の危険なパーミッションを要求する場合は、パーミッションの文字列配列を渡すことができます。注意:2つの異なるグループに所属するAndroidパーミッションは、それぞれ個別のダイアログでユーザーに確認されます。同じグループに属している場合は、1つのダイアログのみが表示されます。リクエストの結果は、onRequestPermissionResultメソッドに渡されます。例えば、私たちのアプリでカメラと位置情報にアクセスしたいとします。両方とも危険なパーミッションです。アプリケーションが起動された時に、これらのパーミッションにアクセスするように促すプロンプトを表示します。以下のように、パーミッションを文字列配列に追加し、requestPermissionsを呼び出しましょう。
String[] perms = {"android.permission.FINE_LOCATION", "android.permission.CAMERA"};
int permsRequestCode = 200;
requestPermissions(perms, permsRequestCode);
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case 200:
boolean locationAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
boolean cameraAccepted = grantResults[1]==PackageManager.PERMISSION_GRANTED;
break;
}
}
ただし、ユーザーが既に承認した権限を継続的に承認することは望んでいません。以前に許可された権限であっても、後でユーザーがその許可を取り消していないかどうかを確認するために、再度チェックする必要があります。そのために、以下のメソッドを各権限に対して呼び出す必要があります。
checkSelfPermission(String perm);
整数値のPERMISSION_GRANTEDまたはPERMISSION_DENIEDが返されます。注意:ユーザーがアプリ内で重要な権限を拒否した場合、shouldShowRequestPermissionRationale(String permission)を使用して、その権限が必要な理由をユーザーに説明します。パーミッションが既に存在するかどうかをチェックするアプリケーションを開発しましょう。存在しない場合は、実行時にリクエストされます。
Androidのランタイムパーミッションプロジェクトの構造
アンドロイドランタイムパーミッションコード
content_main.xmlには、権限を確認およびリクエストするための2つのボタンが含まれています。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.scdev.runtimepermissions.MainActivity"
tools:showIn="@layout/activity_main">
<Button
android:id="@+id/check_permission"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:text="Check Permission"/>
<Button
android:id="@+id/request_permission"
android:layout_below="@+id/check_permission"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Request Permission"/>
</RelativeLayout>
MainActivity.javaは以下のように定義されています。
package com.scdev.runtimepermissions;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.CAMERA;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int PERMISSION_REQUEST_CODE = 200;
private View view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Button check_permission = (Button) findViewById(R.id.check_permission);
Button request_permission = (Button) findViewById(R.id.request_permission);
check_permission.setOnClickListener(this);
request_permission.setOnClickListener(this);
}
@Override
public void onClick(View v) {
view = v;
int id = v.getId();
switch (id) {
case R.id.check_permission:
if (checkPermission()) {
Snackbar.make(view, "Permission already granted.", Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(view, "Please request permission.", Snackbar.LENGTH_LONG).show();
}
break;
case R.id.request_permission:
if (!checkPermission()) {
requestPermission();
} else {
Snackbar.make(view, "Permission already granted.", Snackbar.LENGTH_LONG).show();
}
break;
}
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION, CAMERA}, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0) {
boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (locationAccepted && cameraAccepted)
Snackbar.make(view, "Permission Granted, Now you can access location data and camera.", Snackbar.LENGTH_LONG).show();
else {
Snackbar.make(view, "Permission Denied, You cannot access location data and camera.", Snackbar.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow access to both the permissions",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ACCESS_FINE_LOCATION, CAMERA},
PERMISSION_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
}
注意:実行時にチェックする権限を、マニフェストファイルのアプリケーションタグの上に追加してください。
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
上記のコードでは、チェックされ、要求される2つの許可はカメラと位置情報です。静的パーミッションフルクラス名をインポートすることで、完全修飾パスの代わりにPERMISSIONオブジェクトを記述することができます。checkPermission()は、それぞれの許可に対してcheckSelfPermission()を呼び出します。requestPermission()は、ActivityCompat.requestPermissions(this、new String[] {ACCESS_FINE_LOCATION、CAMERA}、PERMISSION_REQUEST_CODE)を呼び出します。onRequestPermissionsResultは、許可が許可されているかどうかをチェックします。コードでは、両方の許可が許可されていない場合、許可を要求する必要があるという必須の要件を示すアラートダイアログが表示されます。これを行うために、shouldShowRequestPermissionRationale(String permission)が呼び出され、許可の必要性を示すアラートダイアログが表示されます。設定->アプリ->許可から許可を手動で取り消すこともできます。注意:ランタイム許可固有のメソッドは、API 23以降でのみ使用可能です。したがって、各メソッドで次の条件がチェックされます。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
以下は、Androidランタイムパーミッションの例アプリケーションの実行結果です。これで、このチュートリアルは終了です。最終的なAndroidランタイムパーミッションプロジェクトは、以下のリンクからダウンロードできます。
Android Runtime Permissionのサンプルプロジェクトをダウンロードしてください。
参照:https://developer.android.com/training/permissions/requesting.html
上記のリンクを日本語で自然に言い換えると、次のようになります。
参考:https://developer.android.com/training/permissions/requesting.html