AndroidのDangerousパーミッションについての基本の基

##AndroidのDangerousパーミッションについての基本の基
Androidのパーミッションはいつもなんとなくで利用していましたので、改めて、基本をおさらいしたくここにまとめさせていただくことといたしました。

##そもそもAndroidの権限について
一言で言うと、アプリがなんでも自由にアクセスし悪さなどができないようにそれぞれのデータや機能に対してアクセス・利用などについての権限制度とその許可を必要とする機能です。

[公式ページ - Android での権限](https://developer.android.com/guide/topics/permissions/overview?hl=ja)
※以下、公式ページより抜粋

権限の目的は、Android ユーザーのプライバシーを保護することです。Android アプリは、ユーザーの機密データ（連絡先や SMS）と特定のシステム機能（カメラやインターネット）にアクセスする権限をリクエストする必要があります。機能に応じて、システムは権限を自動的に付与するか、またはユーザーにリクエストの承認を求めます。

Android セキュリティ アーキテクチャの設計においては、他のアプリ、オペレーティング システム、またはユーザーに悪影響を及ぼしかねないオペレーションの実行権限を、いかなるアプリにもデフォルトで付与しないよう徹底されています。そうしたオペレーションとしては、ユーザーの個人情報（連絡先やメールアドレス）の読み取りまたは書き込み、他のアプリのファイルの読み取りまたは書き込み、ネットワークへのアクセス、デバイスのスリープモードへの移行の抑止などがあります。

##権限の保護レベルにも強弱がある
保護レベルはNormal・Signature・Dangerousの3つです。

以下、公式ページより抜粋
###Normal
標準の権限に該当するのは、アプリがアプリのサンドボックス外のデータやリソースにアクセスする必要があるが、ユーザーのプライバシーまたは他のアプリのオペレーションに影響する危険がほとんどないケースです。

たとえば、タイムゾーンを設定する権限は、標準の権限です。

###Signature
このタイプの権限については、権限の使用を要求するアプリが権限を定義しているアプリと同じ証明書で署名されている場合に限り、システムはインストール時に権限をアプリに付与します。

###Dangerous
危険な権限に該当するのは、アプリがユーザーの個人情報を含むデータやリソースを要求するケースや、ユーザーが保存したデータや他のアプリのオペレーションに影響を及ぼす可能性があるケースです。

たとえば、ユーザーの連絡先を読み取る機能には、危険な権限が必要です。危険な権限が必要であるとアプリが宣言した場合、ユーザーは明示的にアプリに権限を付与することを求められます。ユーザーが権限を承認しない限り、アプリはその権限に依存する機能を提供できません。

アプリが危険な権限を使用するには、実行時に権限の付与をユーザーにリクエストする必要があります。ユーザーにプロンプトを表示する方法の詳細については、危険な権限をリクエストするプロンプトをご覧ください。

##NormalとDangerousの許可方法の違い
前述の通り、Androidでは保護レベルによって許可方法が異なります。

###Normal

 AndroidManifest.xml に許可を記載するだけで利用できます!

###Dangerous

 AndroidManifest.xml への記述　+ アプリ起動時にダイアログ表示をしてユーザーの許可を取得する必要があります!

ユーザーとして利用しているとAndroidでもiOSでも、最初の方に「アプリに〇〇を許可しますか？」と言うようなポップアップでのアイアログが表示される場面をよく見ると思います。
最近は通知を許可するかどうかで見る機会が多いかと思いますが、このようにユーザーに同意いただいて許可のボタンを押していただく必要があります。

##Dangerousのパーミッションの取得コード例
今回は「CALL_PHONE：電話発信の許可」を例にコード例を記載していきます

###STEP1: AndroidManifest.xml でパーミッションを設定する

```java:AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="・・・">
   <uses-permission android:name="android.permission.CALL_PHONE" />
</manifest>
```
###STEP2: Dangerous パーミッションの許可を確認
現在、該当のDangerousパーミッションが許可されているか確認します

```java:MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     //許可状況の確認
     int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE);
     if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
       // すでにユーザーがパーミッションを許可している場合の処理
     } else {
       // ユーザーはパーミッションを許可していない場合の処理
     }
}
```

###STEP3: Dangerousパーミッションの許可されていない場合、ユーザーに許可を求める画面を表示

Dangerousパーミッションの許可されていない場合、ユーザーに許可を求める画面を表示します

```java:MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     //許可状況の確認
     int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE);
     if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
       // すでにユーザーがパーミッションを許可している場合の処理
     } else {
       // ユーザーはパーミッションを許可していない場合の処理
       
       //ユーザーに許可を求める画面を表示
       //ここから
       ActivityCompat.requestPermissions(MainActivity.this,new String[] { Manifest.permission.CALL_PHONE },0);
       //ここまで

     }
}
```

※requestPermissionsのリクエストコードについて、具体的な利用方法などご存知の方がいたら教えていただけますと幸いです。

###STEP5: Dangerous パーミッションのリクエスト結果の処理
リクエスト結果は、リクエストを行ったActivityインスタンスのonRequestPermissionsResultメソッドの中で、リクエストが許可されたか確認できます。
リクエスト結果に合わせてそれぞれに合った処理を記載して完了です。

```java:MainActivity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

     //許可状況の確認
     int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE);
     if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
       // すでにユーザーがパーミッションを許可している場合の処理
     } else {
       // ユーザーはパーミッションを許可していない場合の処理
       
       //ユーザーに許可を求める画面を表示
       ActivityCompat.requestPermissions(MainActivity.this,new String[] { Manifest.permission.CALL_PHONE },0);

     }

    //ここから
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if (requestCode == 0) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Dangerous パーミッションのリクエストが許可！！
            } else {
                // Dangerous パーミッションのリクエストが拒否。
            }
         }
    }
    //ここまで
}
```

##まとめ
・必要なパーミッションを確認しましょう
・まずはマニュフェストにパーミッションを記載しましょう
・現在のパーミッションの状況を確認しましょう
・未許可の場合、許可を求める画面を表示しましょう
・ユーザーの許可結果を取得し、結果に合わせてアプリ側で必要な処理を実装しましょう