从Android 6.0 (API 23)开始,用户在安装时无需请求权限,开发人员需要在运行时请求权限。在运行时只能请求清单文件中定义的权限。
权限类型
1. 安装时权限:如果是Android 5.1.1 (API 22) 或更低版本,在安装时在Google Play Store请求权限。
如果用户接受权限,则安装应用程序。否则应用程序安装被取消。
2. Run-Time Permissions:如果是Android 6 (API 23) 或更高版本,则在应用程序运行期间的运行时请求权限。
如果用户接受权限,则可以使用应用程序的该功能。否则要使用该功能,应用程序会再次请求权限。
因此,现在在运行时请求权限。在本文中,我们将讨论如何在运行时在 Android 应用程序中请求权限。
在运行时请求权限的步骤
第 1 步:在 Android Manifest 文件中声明权限:在Android中,使用uses-permission标签 在AndroidManifest.xml文件中声明权限。
<uses-permission android:name=”android.permission.PERMISSION_NAME”/>
在这里,我们声明存储和相机权限。
<!--Declaring the required permissions-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
第二步:修改activity_main.xml文件,添加两个按钮来请求按钮点击权限:权限将被检查并在按钮点击时请求。打开activity_main.xml文件并向其中添加两个按钮。
<!--Button to request storage permission-->
<Button
android:id="@+id/storage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Storage"
android:layout_marginTop="16dp"
android:padding="8dp"
android:layout_below="@id/toolbar"
android:layout_centerHorizontal="true"/>
<!--Button to request camera permission-->
<Button
android:id="@+id/camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Camera"
android:layout_marginTop="16dp"
android:padding="8dp"
android:layout_below="@id/storage"
android:layout_centerHorizontal="true"/>
第 3 步: 检查是否已授予权限。如果尚未授予权限,请向用户请求权限:要使用任何服务或功能,都需要权限。因此,我们必须确保为此授予权限。如果不是,则请求权限。
检查权限:从 Android 6.0(API 级别 23)开始,用户有权随时撤销任何应用程序的权限,即使该应用程序的目标 API 级别较低。因此,要使用该服务,应用程序每次都需要检查权限。
句法:
if(ContextCompat.checkSelfPermission ( thisActivity , Manifest.permission.WRITE_CALENDAR)
!= PackageManager.PERMISSION_GRANTED)
{
// 未授予权限
}
请求权限:当上述语法中的checkSelfPermission()方法返回PERMISSION_DENIED时,我们需要提示用户该权限。Android 提供了几种可用于请求权限的方法,例如requestPermissions()。
句法:
ActivityCompat.requestPermissions(MainActivity.this,
permissionArray,
requestCode);
Here permissionArray is an array of type String.
例子:
// Function to check and request permission
public void checkPermission(String permission, int requestCode)
{
// Checking if permission is not granted
if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] { permission }, requestCode);
}
else {
Toast.makeText(MainActivity.this, "Permission already granted", Toast.LENGTH_SHORT).show();
}
}
// Function to check and request permission.
private fun checkPermission(permission: String, requestCode: Int) {
if (ContextCompat.checkSelfPermission(this@MainActivity, permission) == PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(permission), requestCode)
} else {
Toast.makeText(this@MainActivity, "Permission already granted", Toast.LENGTH_SHORT).show()
}
}
如果已授予权限,此功能将显示Toast消息,否则提示用户授予权限。
第 4 步:覆盖 onRequestPermissionsResult() 方法: 在用户授予或拒绝权限时调用onRequestPermissionsResult() 。RequestCode是该函数的参数之一,用于检查用户对相应请求的操作。这里显示了一条 toast 消息,指示权限和用户操作。
例子:
// This function is called when user accept or decline the permission.
// Request Code is used to check which permission called this function.
// This request code is provided when user is prompt for permission.
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_PERMISSION_CODE) {
// Checking whether user granted the permission or not.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Showing the toast message
Toast.makeText(MainActivity.this, "Camera Permission Granted", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(MainActivity.this, "Camera Permission Denied", Toast.LENGTH_SHORT).show();
}
}
else if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Storage Permission Granted", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(MainActivity.this, "Storage Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
// This function is called when the user accepts or decline the permission.
// Request Code is used to check which permission called this function.
// This request code is provided when the user is prompt for permission.
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_PERMISSION_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this@MainActivity, "Camera Permission Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@MainActivity, "Camera Permission Denied", Toast.LENGTH_SHORT).show()
}
} else if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this@MainActivity, "Storage Permission Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@MainActivity, "Storage Permission Denied", Toast.LENGTH_SHORT).show()
}
}
}
下面是这个应用程序的完整代码:
下面是activity_main.xml文件的代码。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<!-- To show toolbar-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:background="@color/colorPrimary"
app:title="GFG | Permission Example"
app:titleTextColor="@android:color/white"
android:layout_height="?android:attr/actionBarSize"/>
<!--Button to request storage permission-->
<Button
android:id="@+id/storage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Storage"
android:layout_marginTop="16dp"
android:padding="8dp"
android:layout_below="@id/toolbar"
android:layout_centerHorizontal="true"/>
<!--Button to request camera permission-->
<Button
android:id="@+id/camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Camera"
android:layout_marginTop="16dp"
android:padding="8dp"
android:layout_below="@id/storage"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
下面是AndroidManifest.xml文件的代码。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.geeksforgeeks.requestPermission">
<!--Declaring the required permissions-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
下面是MainActivity文件的代码。
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
// Defining Buttons
private Button storage, camera;
// Defining Permission codes.
// We can give any value
// but unique for each permission.
private static final int CAMERA_PERMISSION_CODE = 100;
private static final int STORAGE_PERMISSION_CODE = 101;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
storage = findViewById(R.id.storage);
camera = findViewById(R.id.camera);
// Set Buttons on Click Listeners
storage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE_PERMISSION_CODE);
}
});
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.CAMERA, CAMERA_PERMISSION_CODE);
}
});
}
// Function to check and request permission.
public void checkPermission(String permission, int requestCode)
{
if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(MainActivity.this, new String[] { permission }, requestCode);
}
else {
Toast.makeText(MainActivity.this, "Permission already granted", Toast.LENGTH_SHORT).show();
}
}
// This function is called when the user accepts or decline the permission.
// Request Code is used to check which permission called this function.
// This request code is provided when the user is prompt for permission.
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode,
permissions,
grantResults);
if (requestCode == CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Camera Permission Granted", Toast.LENGTH_SHORT) .show();
}
else {
Toast.makeText(MainActivity.this, "Camera Permission Denied", Toast.LENGTH_SHORT) .show();
}
}
else if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Storage Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Storage Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
}
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
companion object {
private const val CAMERA_PERMISSION_CODE = 100
private const val STORAGE_PERMISSION_CODE = 101
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Defining Buttons
val storage: Button? = findViewById(R.id.storage)
val camera: Button? = findViewById(R.id.camera)
// Set Buttons on Click Listeners
storage?.setOnClickListener {checkPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
STORAGE_PERMISSION_CODE)
}
camera?.setOnClickListener {
checkPermission(Manifest.permission.CAMERA,
CAMERA_PERMISSION_CODE)
}
}
// Function to check and request permission.
private fun checkPermission(permission: String, requestCode: Int) {
if (ContextCompat.checkSelfPermission(this@MainActivity, permission) == PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(permission), requestCode)
} else {
Toast.makeText(this@MainActivity, "Permission already granted", Toast.LENGTH_SHORT).show()
}
}
// This function is called when the user accepts or decline the permission.
// Request Code is used to check which permission called this function.
// This request code is provided when the user is prompt for permission.
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>,
grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_PERMISSION_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this@MainActivity, "Camera Permission Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@MainActivity, "Camera Permission Denied", Toast.LENGTH_SHORT).show()
}
} else if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this@MainActivity, "Storage Permission Granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this@MainActivity, "Storage Permission Denied", Toast.LENGTH_SHORT).show()
}
}
}
}
输出:
在启动应用程序时:
第一次单击相机按钮时:
在授予权限时:
再次单击相机按钮时: