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位置权限设置

一旦选择了拒绝权限并不再询问,对话框将不再打开。