0Pricing
Android Academy · レッスン

正しい位置情報権限の扱い

フォアグラウンド位置情報と正確な位置情報を扱います。

「正しい位置情報権限の扱い」はCoddyKit上の無料Android Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAndroid Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Android Academyコースには全4レッスンが含まれています。

パーミッションは必須です

位置情報は、Androidで最も機密性の高いパーミッションの1つです。マニフェストで宣言するだけでは不十分です。最新のAndroidでは、実行時にユーザーへリクエストし、どの回答に対しても適切に処理する必要があります。

このレッスンでは、パーミッションの段階、Composeでのリクエスト方法、拒否への対応、新しい正確な位置情報とおおよその位置情報の違い、バックグラウンドに関するルールを扱います。

3種類の位置情報パーミッション

Androidでは、位置情報を次の段階に分けています。

  • ACCESS_COARSE_LOCATION — おおよその位置情報(市区町村の区画程度)。
  • ACCESS_FINE_LOCATION — 正確な位置情報(GPSレベル)。
  • ACCESS_BACKGROUND_LOCATION — アプリがフォアグラウンドにない間のアクセス。

実際に必要なものだけをリクエストしてください。バックグラウンドアクセスを求めると、Play Storeでより厳しく審査されます。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- only if truly needed: -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Composeでパーミッションをリクエストする

Activity Result APIを使うと、パーミッションダイアログを表示するlauncherを取得できます。Composeでは、RequestMultiplePermissionsコントラクトとrememberLauncherForActivityResultを使用します。

import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts

val launcher = rememberLauncherForActivityResult(
    ActivityResultContracts.RequestMultiplePermissions()
) { result ->
    val fine = result[Manifest.permission.ACCESS_FINE_LOCATION] == true
    val coarse = result[Manifest.permission.ACCESS_COARSE_LOCATION] == true
    // react to the user's choice
}

リクエストを起動する

パーミッションの配列を指定してlaunch()を呼び出すと、ダイアログを表示できます。通常は画面の読み込み時に自動表示するのではなく、ボタンのタップに応じて起動します。

Button(onClick = {
    launcher.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}) {
    Text("Enable location")
}

すでに許可されているか確認する

すでに許可されているパーミッションを再度リクエストしないでください。リクエストを起動する前に、ContextCompat.checkSelfPermissionで確認します。

import androidx.core.content.ContextCompat
import android.content.pm.PackageManager

fun hasFineLocation(context: Context): Boolean {
    return ContextCompat.checkSelfPermission(
        context,
        Manifest.permission.ACCESS_FINE_LOCATION
    ) == PackageManager.PERMISSION_GRANTED
}

正確な位置情報とおおよその位置情報

Android 12(API 31)以降では、正確な位置情報をリクエストしても、ユーザーはおおよその位置情報を許可できます。そのため、正確な位置情報とおおよその位置情報の両方を一緒にリクエストし、ユーザーによっておおよその位置情報に変更される可能性を受け入れる必要があります。

可能であれば、おおよその位置情報でも問題なく動作するよう機能を設計してください。

// Request both — the system shows a Precise/Approximate toggle
launcher.launch(
    arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )
)
// If only COARSE comes back granted, you got approximate location.

理由を説明する

ユーザーが一度拒否した場合、AndroidではshouldShowRequestPermissionRationaleを確認できます。これがtrueの場合は、もう一度リクエストする前に、位置情報がなぜ必要なのかをわかりやすく説明してください。

import androidx.core.app.ActivityCompat

val shouldExplain = ActivityCompat.shouldShowRequestPermissionRationale(
    activity,
    Manifest.permission.ACCESS_FINE_LOCATION
)
if (shouldExplain) {
    // show a dialog: "We use your location to find nearby stores"
}

恒久的な拒否に対応する

ユーザーが今後表示しないを選択した場合(または2回拒否した場合)、システムはダイアログを表示しなくなります。残された方法は、ユーザーをアプリの設定へ案内し、手動で有効にしてもらうことです。

import android.content.Intent
import android.provider.Settings
import android.net.Uri

fun openAppSettings(context: Context) {
    val intent = Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.fromParts("package", context.packageName, null)
    )
    context.startActivity(intent)
}

Accompanist Permissionsを使う

accompanist-permissionsライブラリを使うと、これらすべてをCompose向けの状態として扱えます。rememberMultiplePermissionsStateで許可状態を追跡し、launchMultiplePermissionRequest()を呼び出せます。

import com.google.accompanist.permissions.rememberMultiplePermissionsState

val permissions = rememberMultiplePermissionsState(
    listOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )
)

if (permissions.allPermissionsGranted) {
    // show the map / read location
} else {
    Button(onClick = { permissions.launchMultiplePermissionRequest() }) {
        Text("Grant location")
    }
}

バックグラウンド位置情報のルール

バックグラウンド位置情報には2段階のフローが必要です。まずフォアグラウンド位置情報(高精度/低精度)を許可し、その後、別途ACCESS_BACKGROUND_LOCATIONをリクエストします。Android 11以降ではシステム設定が開きます。Google Playでは、明確な利用理由とプライバシーポリシーが求められます。

アプリを閉じている間も位置情報が本当に必要な場合(ジオフェンシングやフィットネストラッキングなど)にのみリクエストしてください。

// Step 1: request foreground first and confirm it's granted.
// Step 2: only then request background:
launcher.launch(
    arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
// On Android 11+ this sends the user to settings to pick "Allow all the time".

権限で制御する地図

ここまでの内容をまとめ、権限の状態に応じて地図を表示します。許可されるまでは地図を表示せず、代わりにリクエストを促すメッセージを表示してください。これは、ユーザーに配慮した標準的なパターンです。

@Composable
fun LocationGate(permissions: MultiplePermissionsState) {
    when {
        permissions.allPermissionsGranted -> MapScreen()
        else -> Column {
            Text("We need location to show nearby places.")
            Button(onClick = { permissions.launchMultiplePermissionRequest() }) {
                Text("Allow location")
            }
        }
    }
}

クイックチェック

Android 12以降では、ユーザーは正確な位置情報の代わりにおおよその位置情報を選択できます。これは、位置情報のリクエストにどのような影響を与えるでしょうか?

まとめ

位置情報を適切にリクエストする方法を理解できました。

  • マニフェストで低精度/高精度の位置情報を宣言します(バックグラウンド位置情報は不可欠な場合のみ)。
  • Activity Result APIまたはaccompanist-permissionsを使って、実行時にリクエストします。
  • 正確な位置情報/おおよその位置情報の切り替えに対応するため、高精度と低精度を同時にリクエストします。
  • 理由を説明し、恒久的に拒否したユーザーをアプリの設定画面へ誘導します。
  • バックグラウンド位置情報は、理由を明示した別個の2段階フローとして処理します。

これで「Maps & Location Services」は完了です。地図を表示し、ユーザーの位置を取得し、マーカーを配置し、適切な方法で権限を求められるようになりました。

よくある質問

「正しい位置情報権限の扱い」レッスンは無料ですか?

はい。「正しい位置情報権限の扱い」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Android Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Android Academyコースには全4レッスンが含まれています。

「正しい位置情報権限の扱い」で何を学びますか?

フォアグラウンド位置情報と正確な位置情報を扱います。 ブラウザで直接実行するハンズオンコードでAndroid Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Android Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAndroid Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「正しい位置情報権限の扱い」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAndroid Academyレッスンでコードを書いて実行できますか?

はい。すべてのAndroid Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 地図を表示する
  2. ユーザーの位置情報を取得する
  3. マーカーとカメラ
  4. 正しい位置情報権限の扱い
← Android Academyに戻る