アプリの権限をリクエストする場合に、複数同時にリクエストする必要があるケースがあります
Android Studio
2021.2.1
2021.2.1
RequestMultiplePermissions
1 つの権限だけをリクエストするには、RequestPermission を使用しますが
複数の権限を同時にリクエストするには、RequestMultiplePermissions を使用します
複数の権限でも別々の機能である場合は、必要な場面でリクエストすればいいのですが、例えばカメラ撮影の場合、撮影場所の位置情報を同時に取得して画像ファイルに埋め込みます(EXIF規格)そういったケースで位置情報取得の権限とカメラ権限を同時にリクエストすることになります
複数のパーミッションを扱う
複数のパーミッションを扱うには、配列あるいはArrayとして例えばPERMISSIONS[]を作り ます
1 2 3 4 5 |
private var PERMISSIONS = arrayOf( Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION ... ) |
checkSelfPermissionをforで権限の数だけ繰り返します
1 2 3 4 5 6 7 8 9 |
for (perm in PERMISSIONS) { if (ActivityCompat.checkSelfPermission(this, perm) == PackageManager.PERMISSION_GRANTED ) { // Granted } else { // need to request } } |
RequestMultiplePermissions
にてユーザーに権限のリクエストを行う
1 2 3 4 5 6 7 8 9 |
requestPermissionsLauncher = registerForActivityResult( RequestMultiplePermissions() ) { isGranted: Map<String?, Boolean?> -> if (isGranted.containsValue(false)) { // Denied } else { // Permitted } } |
サンプルコード
こちらのサンプルコード(1)に追加してカメラ撮影の権限をリクエストしてみます(実際にはカメラは扱いません)
位置情報といえばGPSと思う人が多いとは思いますが、スマホでの位置情報はGPS以外にWiFiや電話網を駆使して短時間で効率の良い情報を取得し...
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ... <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <application ... </application> </manifest> |
MainActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
//package your.package.name import android.Manifest import android.content.pm.PackageManager import android.os.Bundle import android.widget.Button import android.widget.TextView import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices class MainActivity : AppCompatActivity() { private var PERMISSIONS = arrayOf( Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION ) private val requestPermissionsLauncher = registerForActivityResult( RequestMultiplePermissions() ) { isGranted: Map<String?, Boolean?> -> if (isGranted.containsValue(false)) { Toast.makeText(this, R.string.message2, Toast.LENGTH_SHORT).show() } else { fusedLocation() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val button: Button = findViewById(R.id.button) button.setOnClickListener { v -> for (perm in PERMISSIONS) { if (ActivityCompat.checkSelfPermission(this, perm) == PackageManager.PERMISSION_GRANTED ) { fusedLocation() } else { requestPermissionsLauncher.launch(PERMISSIONS) } } } } private fun fusedLocation() { // 冗長ですが if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return } // 最後に確認された位置情報を取得 val fusedLocationClient: FusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this) fusedLocationClient.getLastLocation() .addOnSuccessListener(this) { location -> if (location != null) { val textView1 = findViewById<TextView>(R.id.text_view1) val textView2 = findViewById<TextView>(R.id.text_view2) // 緯度の表示 val str1 = "Latitude:" + location.getLatitude() textView1.text = str1 // 経度の表示 val str2 = "Longtude:" + location.getLongitude() textView2.text = str2 } } } } |
レイアウトです
activity_main.xml
strings.xml
build.gradle
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/button" android:text="@string/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.501" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.2" /> <TextView android:id="@+id/text_view1" android:text="@string/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" android:textColor="#44f" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.501" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.35" /> <TextView android:id="@+id/text_view2" android:text="@string/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#f44" android:layout_margin="20dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.4" /> </androidx.constraintlayout.widget.ConstraintLayout> |
strings.xml
1 2 3 4 5 6 7 8 |
<resources> <string name="app_name">TestMultiPermissions</string> <string name="button">"位置情報の取得"</string> <string name="text1">Latitude</string> <string name="text2">Longitude</string> <string name="message1">"位置情報の取得が無いままアプリを継続します"</string> <string name="message2">"位置情報の取得が無いままアプリを継続します"</string> </resources> |
build.gradle
1 2 3 4 5 |
... dependencies { implementation 'com.google.android.gms:play-services-location:20.0.0' ... } |
関連記事:
- FusedLocationProviderClient による位置情報の取得
- 複数の権限、LOCATIONとCAMERAをリクエスト
- FusedLocationProvider からGoogle Map地図の表示
- Kotlin でGPS位置情報を取得するアプリを作る
- アプリの権限リクエスト
References:
アプリの権限をリクエストする
直近の位置情報を取得する – Android Developers