位置权限 android
In this tutorial, we’ll be discussing and implementing the new location permissions model in our android application.
在本教程中,我们将在android应用程序中讨论和实现新的位置权限模型。
Android 10位置权限 (Android 10 Location Permissions)
With the introduction of Android 10, besides the dialog UI, the way of handling location permissions has also changed.
Now the user is allowed to choose whether they want location updates when the app is in the background.
For that a new permission needs to be declared in the Manifest file:
随着Android 10的引入,除了对话框UI之外,处理位置权限的方式也发生了变化。
现在,允许用户选择在后台运行应用程序时是否要更新位置。
为此,需要在清单文件中声明新的权限:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
Calling this along with COARSE_LOCATION would pop up a dialog with three options:
与COARSE_LOCATION一起调用将弹出一个带有三个选项的对话框:
- Always Allow 总是允许
- Allow only while using the app 仅在使用应用程序时允许
- Deny 拒绝
On selecting Deny, the next time the dialog will show a fourth option – Deny & Do Not Ask Again.
在选择“拒绝”时,下一次对话框将显示第四个选项-“拒绝并不再询问”。
Always Allow ensures that you can poll for location updates in foreground and background.
始终允许确保您可以轮询前景和后台的位置更新。
If you select “Allow only while using the app”, the next time the permission dialog will only ask you to always allow the location permission or deny.
如果您选择“仅在使用应用程序时允许”,则下次权限对话框将仅要求您始终允许位置权限或拒绝。
In the following section, we’ll be implementing our first Android Q Application.
Let’s update the SDK Manager and also create a new AVD with Android Q.
在下一节中,我们将实现我们的第一个Android Q应用程序。
让我们更新SDK Manager,并使用Android Q创建新的AVD。
项目结构 (Project Structure)
Our build.gradle
file is given below:
我们的build.gradle
文件如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 'android-Q'
defaultConfig {
applicationId "com.journaldev.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'
}
We’ve upgraded the dependencies for Android – Q.
我们已经升级了Android – Q的依赖项。
码 (Code)
The code for the activity_main.xml
layout is given below:
下面给出了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>
Inside the MainActivity.java :
在MainActivity.java内部:
package com.journaldev.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();
}
}
In the onRequestPermissionResult
method, we check whether the permission is granted or not.
If the foreground location permission is not granted then we break out of the loop.
This is because, without the foreground permission allowed, the background location permission is of no use.
在onRequestPermissionResult
方法中,我们检查是否授予了权限。
如果未授予前台位置许可,则我们将退出循环。
这是因为,在没有前台许可的情况下,后台位置许可是没有用的。
Once the permission is granted, you can poll for the location updates.
授予权限后,您可以轮询位置更新。
The output of the above application in action is given below:
上面应用程序的输出如下:

Android Q Location Permissions Output 1
Android Q位置权限输出1
We can go to the Settings | Apps | Permissions to view the permission is granted or not as shown in the illustration below:
我们可以转到设置| 应用程式| 权限 ,以查看权限被授予或不如下面的图:

Android Q Location Permissions Settings
Android Q位置权限设置
That brings an end to this tutorial. You can download the complete Android Q Location Permissions Project from the link given below or check out the Github Repository for the full source code.
这样就结束了本教程。 您可以从下面给出的链接下载完整的Android Q位置权限项目 ,也可以查看Github存储库以获取完整的源代码。
翻译自: https://www.journaldev.com/28028/android-10-location-permissions
位置权限 android