1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Android開発30日間マスターシリーズ - Day 7:Androidマニフェストとアプリの権限 - セキュリティとプライバシーの基礎

Last updated at Posted at 2025-09-08

はじめに

Androidアプリ開発において、セキュリティとプライバシーの保護は最重要課題の一つです。今回は、その基盤となるAndroidManifest.xmlとアプリの権限システムについて、実践的な観点から解説します。

1. AndroidManifest.xmlとは?

AndroidManifest.xmlは、すべてのAndroidアプリのルートディレクトリに配置される必須のファイルです。このXMLファイルは、アプリのメタデータをAndroidシステムに宣言する役割を持ちます。

主な宣言内容

  • アプリの識別情報:パッケージ名、バージョンコード、バージョン名
  • アプリコンポーネント:Activity、Service、BroadcastReceiver、ContentProvider
  • 必要な権限:アプリが動作するために必要なシステム権限
  • ハードウェア要件:カメラ、センサーなどの必要な機能
  • 最小・ターゲットAPIレベル:対応するAndroidバージョンの範囲

2. Androidの権限モデル

Androidは、最小権限の原則に基づいた権限モデルを採用しています。アプリは必要最小限の権限のみを要求し、ユーザーは各権限を個別に制御できます。

なぜ権限が必要なのか?

権限システムは以下の目的で設計されています:

  • プライバシー保護:個人情報への不正アクセスを防ぐ
  • セキュリティ確保:悪意のあるアプリからシステムを保護
  • 透明性の確保:アプリがアクセスする情報をユーザーに明示

3. 権限の種類と特徴

3.1 通常権限(Normal Permissions)

ユーザーのプライバシーリスクが低い権限です。

<!-- インターネット接続 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- バイブレーション -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- ネットワーク状態の確認 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

特徴

  • インストール時に自動的に付与
  • ユーザーへの確認ダイアログなし
  • アプリ情報画面で確認可能

3.2 危険権限(Dangerous Permissions)

ユーザーのプライバシーに直接関わる重要な権限です。

<!-- カメラ -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 位置情報(正確) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 連絡先の読み取り -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- ストレージの読み書き(Android 12以前) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

特徴

  • Android 6.0(API 23)以降:ランタイムパーミッションが必要
  • ユーザーが明示的に許可/拒否を選択
  • 権限グループ単位で管理

3.3 特殊な権限(Special Permissions)

特別な承認プロセスが必要な権限です。

<!-- システム設定の変更 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- 他のアプリの上に表示 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

4. 実装例:完全なマニフェストファイル

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.secureapp">

    <!-- 通常権限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <!-- 危険権限 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
    <!-- Android 13以降の新しい権限 -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    
    <!-- カメラ機能を必須とする場合 -->
    <uses-feature 
        android:name="android.hardware.camera"
        android:required="true" />
    
    <!-- カメラ機能をオプションとする場合 -->
    <uses-feature 
        android:name="android.hardware.camera.autofocus"
        android:required="false" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.SecureApp"
        tools:targetApi="31">
        
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <!-- exported属性の明示的な設定(Android 12以降必須) -->
        <activity
            android:name=".CameraActivity"
            android:exported="false" />
            
        <service
            android:name=".LocationService"
            android:exported="false"
            android:foregroundServiceType="location" />
            
    </application>

</manifest>

5. ランタイムパーミッションの実装

Android 6.0以降では、危険権限は実行時に要求する必要があります。

class MainActivity : AppCompatActivity() {
    
    private val CAMERA_PERMISSION_CODE = 100
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // カメラボタンのクリック処理
        cameraButton.setOnClickListener {
            checkCameraPermission()
        }
    }
    
    private fun checkCameraPermission() {
        when {
            // 権限が既に付与されている
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED -> {
                openCamera()
            }
            
            // 権限の説明を表示すべきか
            shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> {
                showPermissionRationale()
            }
            
            // 権限をリクエスト
            else -> {
                requestPermissions(
                    arrayOf(Manifest.permission.CAMERA),
                    CAMERA_PERMISSION_CODE
                )
            }
        }
    }
    
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        
        when (requestCode) {
            CAMERA_PERMISSION_CODE -> {
                if (grantResults.isNotEmpty() && 
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openCamera()
                } else {
                    Toast.makeText(
                        this,
                        "カメラの権限が必要です",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }
}

6. Android バージョン別の注意点

Android 10(API 29)

  • スコープストレージの導入
  • WRITE_EXTERNAL_STORAGE権限の動作変更

Android 11(API 30)

  • パッケージ可視性の制限
  • 位置情報権限の細分化(フォアグラウンドのみ/常時)

Android 12(API 31)

  • exported属性の明示的な設定が必須
  • 概略位置情報権限の追加

Android 13(API 33)

  • 通知権限がランタイムパーミッションに変更
  • メディア権限の細分化(画像、動画、音声)

7. セキュリティのベストプラクティス

7.1 最小権限の原則

<!-- 悪い例:不要な権限を要求 -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<!-- 良い例:必要最小限の権限のみ -->
<uses-permission android:name="android.permission.CAMERA" />

7.2 権限の適切な説明

ユーザーに権限が必要な理由を明確に説明:

private fun showPermissionRationale() {
    AlertDialog.Builder(this)
        .setTitle("カメラ権限が必要です")
        .setMessage("QRコードをスキャンするためにカメラへのアクセスが必要です")
        .setPositiveButton("許可") { _, _ ->
            requestCameraPermission()
        }
        .setNegativeButton("キャンセル", null)
        .show()
}

7.3 権限の動的な確認

機能を使用する直前に権限を確認:

// 良い例:機能使用時に権限確認
fun takePhoto() {
    if (hasCameraPermission()) {
        launchCamera()
    } else {
        requestCameraPermission()
    }
}

8. よくある実装ミス

ミス1:exported属性の未設定

<!-- 悪い例:Android 12以降でクラッシュ -->
<activity android:name=".ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
    </intent-filter>
</activity>

<!-- 良い例:exported属性を明示 -->
<activity 
    android:name=".ShareActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

ミス2:権限グループの誤解

// 注意:READ_CONTACTSを許可してもWRITE_CONTACTSは自動で許可されない
if (hasPermission(READ_CONTACTS)) {
    // WRITE_CONTACTSも個別に確認が必要
    if (hasPermission(WRITE_CONTACTS)) {
        updateContact()
    }
}

まとめ

AndroidManifest.xmlとアプリの権限システムは、Androidアプリのセキュリティとプライバシー保護の基盤です。重要なポイントは:

  1. 必要最小限の権限のみを要求し、その理由をユーザーに明確に説明する
  2. Androidバージョンごとの違いを理解し、適切に対応する
  3. ランタイムパーミッションを正しく実装し、ユーザー体験を損なわない
  4. セキュリティのベストプラクティスに従い、ユーザーの信頼を獲得する

次回は、これらの基礎知識を活用して、実際にIntentを使った画面遷移とデータの受け渡しについて詳しく解説します。セキュアなアプリ間連携の実装方法も含めて、実践的な内容をお届けします。

参考リンク

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?