Android 10 –位置权限
时间:2020-02-23 14:28:43 来源:igfitidea点击:
在本教程中,我们将在android应用程序中讨论和实现新的位置权限模型。
注意:Google已绕过Android按字母顺序排列的版本。
Android Q已重命名为Android10。
由于本教程是在Google决定执行此操作之前编写的,因此您会在本文的某些地方看到AndroidQ。
Android 10位置权限
随着Android 10的引入,除了对话框UI之外,处理位置权限的方式也发生了变化。
现在,允许用户选择在后台运行应用程序时是否要更新位置。
为此,需要在列表文件中声明新的权限:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
与COARSE_LOCATION一起调用将弹出一个带有三个选项的对话框:
- 总是允许
- 仅在使用应用程序时允许
- 拒绝
在选择"拒绝"时,下一次对话框将显示第四个选项–拒绝&不再询问。
始终允许确保您可以轮询前景和后台的位置更新。
如果您选择"仅在使用该应用程序时允许",则下一次权限对话框将仅要求您始终允许位置权限或者拒绝。
在以下部分中,我们将实现第一个Android Q应用程序。
让我们更新SDK Manager,并使用Android Q创建新的AVD。
项目结构
我们的build.gradle
文件如下:
apply plugin: 'com.android.application' android { compileSdkVersion 'android-Q' defaultConfig { applicationId "com.theitroad.androidqlocationpermissions" minSdkVersion 16 targetSdkVersion 'Q' versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0-alpha03' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }
我们已经升级了Android的依赖关系-问。
代码
下面给出了" activity_main.xml"布局的代码:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" tools:context=".MainActivity"> <Button android:id="@+id/btnPermissions" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="LOCATION PERMISSION" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" </android.support.constraint.ConstraintLayout>
在MainActivity.java内部:
package com.theitroad.androidqlocationpermissions; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; public class MainActivity extends AppCompatActivity { Button btnPermissions; public static final int REQUEST_CODE_PERMISSIONS = 101; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnPermissions = findViewById(R.id.btnPermissions); btnPermissions.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { requestLocationPermission(); } }); } private void requestLocationPermission() { boolean foreground = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (foreground) { boolean background = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; if (background) { handleLocationUpdates(); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, REQUEST_CODE_PERMISSIONS); } } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION}, REQUEST_CODE_PERMISSIONS); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_PERMISSIONS) { boolean foreground = false, background = false; for (int i = 0; i < permissions.length; i++) { if (permissions[i].equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)) { //foreground permission allowed if (grantResults[i] >= 0) { foreground = true; Toast.makeText(getApplicationContext(), "Foreground location permission allowed", Toast.LENGTH_SHORT).show(); continue; } else { Toast.makeText(getApplicationContext(), "Location Permission denied", Toast.LENGTH_SHORT).show(); break; } } if (permissions[i].equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) { if (grantResults[i] >= 0) { foreground = true; background = true; Toast.makeText(getApplicationContext(), "Background location location permission allowed", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "Background location location permission denied", Toast.LENGTH_SHORT).show(); } } } if (foreground) { if (background) { handleLocationUpdates(); } else { handleForegroundLocationUpdates(); } } } } private void handleLocationUpdates() { //foreground and background Toast.makeText(getApplicationContext(),"Start Foreground and Background Location Updates",Toast.LENGTH_SHORT).show(); } private void handleForegroundLocationUpdates() { //handleForeground Location Updates Toast.makeText(getApplicationContext(),"Start foreground location updates",Toast.LENGTH_SHORT).show(); } }
在" onRequestPermissionResult"方法中,我们检查是否授予许可。
如果未授予前台位置许可,则我们将退出循环。
这是因为,在没有前台许可的情况下,后台位置许可是没有用的。
授予权限后,您可以轮询位置更新。
上面应用程序的输出如下:
Android Q位置权限输出1
我们可以转到设置|应用程式|如下图所示,查看权限是否被授予:
Android Q位置权限设置
一旦选择了拒绝权限并不再询问,对话框将不再打开。