我正在开发一个应用程序,我需要使用推送通知。我知道推送通知是正常权限,因此我无法在运行时询问它。但我会在用户下载并安装应用程序时插入权限,以及应用程序应发送推送通知的通知。
我该怎么做?我必须在清单中插入一些东西吗?
2022 年更新
我们在 Android 上请求权限的方式在 Android 13 中发生了巨大变化。请参阅下面提及相同内容的其他答案。
如此处所回答,您不需要推送通知的权限。
其实推送通知权限属于普通类别 类似 Internet 权限,不属于危险类别 许可。
您无需请求推送通知权限。
虽然联系人/位置是危险的权限,因为您 访问用户数据。所以总是需要请求用户允许。
https://developer.android.com/guide/topics/security/permissions.html
以下是新更新的答案: 在 API 33 中,我们需要推送通知的运行时权限: 完整的文档可以在这里找到,但是你可以简单地使用如下:
在应用程序级别:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
您可以使用以下命令触发提示:
pushNotificationPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
处理通知结果:
private val pushNotificationPermissionLauncher = registerForActivityResult(RequestPermission()) { granted ->
viewModel.inputs.onTurnOnNotificationsClicked(granted)
}
以下是如何在 Android 13 (Tiramisu) 中请求通知运行时权限的完整示例
首先,在您的
manifest
文件中添加以下权限
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
使用以下代码请求运行时权限
package com.example.myapplication
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.graphics.Color
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
import android.widget.Button
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.NotificationCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class MainActivity : AppCompatActivity() {
private val notificationPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
hasNotificationPermissionGranted = isGranted
if (!isGranted) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT >= 33) {
if (shouldShowRequestPermissionRationale(android.Manifest.permission.POST_NOTIFICATIONS)) {
showNotificationPermissionRationale()
} else {
showSettingDialog()
}
}
}
} else {
Toast.makeText(applicationContext, "notification permission granted", Toast.LENGTH_SHORT)
.show()
}
}
private fun showSettingDialog() {
MaterialAlertDialogBuilder(this, com.google.android.material.R.style.MaterialAlertDialog_Material3)
.setTitle("Notification Permission")
.setMessage("Notification permission is required, Please allow notification permission from setting")
.setPositiveButton("Ok") { _, _ ->
val intent = Intent(ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
}
.setNegativeButton("Cancel", null)
.show()
}
private fun showNotificationPermissionRationale() {
MaterialAlertDialogBuilder(this, com.google.android.material.R.style.MaterialAlertDialog_Material3)
.setTitle("Alert")
.setMessage("Notification permission is required, to show notification")
.setPositiveButton("Ok") { _, _ ->
if (Build.VERSION.SDK_INT >= 33) {
notificationPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}
}
.setNegativeButton("Cancel", null)
.show()
}
var hasNotificationPermissionGranted = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.btnRequestPermission).setOnClickListener {
if (Build.VERSION.SDK_INT >= 33) {
notificationPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
} else {
hasNotificationPermissionGranted = true
}
}
findViewById<Button>(R.id.btnShowNotification).setOnClickListener {
if (checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
showNotification()
}
}
}
private fun showNotification() {
val channelId = "12345"
val description = "Test Notification"
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel =
NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
notificationChannel.lightColor = Color.BLUE
notificationChannel.enableVibration(true)
notificationManager.createNotificationChannel(notificationChannel)
}
val builder = NotificationCompat.Builder(this, channelId)
.setContentTitle("Hello World")
.setContentText("Test Notification")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(
BitmapFactory.decodeResource(
this.resources, R.drawable
.ic_launcher_background
)
)
notificationManager.notify(12345, builder.build())
}
}
如果您使用jetpack compose,则使用以下代码
class MainActivity : ComponentActivity() {
@RequiresApi(VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
JetpackComposeNotifcationPermissionTheme {
val context = LocalContext.current
val permissionOpenDialog = remember { mutableStateOf(false) }
val rationalPermissionOpenDialog = remember { mutableStateOf(false) }
if (permissionOpenDialog.value) {
ShowSettingDialog(openDialog = permissionOpenDialog)
}
var hasNotificationPermission by remember {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
mutableStateOf(
ContextCompat.checkSelfPermission(
context,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
)
} else mutableStateOf(true)
}
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission(),
onResult = { isGranted ->
if (!isGranted) {
if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
rationalPermissionOpenDialog.value = true
} else {
permissionOpenDialog.value = true
}
} else {
hasNotificationPermission = isGranted
}
}
)
if (rationalPermissionOpenDialog.value) {
ShowRationalPermissionDialog(openDialog = rationalPermissionOpenDialog) {
rationalPermissionOpenDialog.value = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}) {
Text(text = "Request permission")
}
Button(onClick = {
if (hasNotificationPermission) {
showNotification()
}
}) {
Text(text = "Show notification")
}
}
}
}
}
private fun showNotification() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "12345"
val description = "Test Notification"
if (VERSION.SDK_INT >= VERSION_CODES.O) {
val notificationChannel =
NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
notificationChannel.lightColor = Color.BLUE
notificationChannel.enableVibration(true)
notificationManager.createNotificationChannel(notificationChannel)
}
val notification = NotificationCompat.Builder(applicationContext, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Hello Nilesh")
.setContentText("Test Notification")
.build()
notificationManager.notify(1, notification)
}
@Composable
fun ShowSettingDialog(openDialog: MutableState<Boolean>) {
if (openDialog.value) {
AlertDialog(
onDismissRequest = {
openDialog.value = false
},
title = {
Text(text = "Notification Permission")
},
text = {
Text("Notification permission is required, Please allow notification permission from setting")
},
buttons = {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
) {
TextButton(
onClick = {
openDialog.value = false
}
) {
Text("Cancel")
}
Spacer(modifier = Modifier.width(20.dp))
TextButton(
onClick = {
openDialog.value = false
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
},
) {
Text("Ok")
}
}
},
)
}
}
@Composable
fun ShowRationalPermissionDialog(openDialog: MutableState<Boolean>, onclick: () -> Unit) {
if (openDialog.value) {
AlertDialog(
onDismissRequest = {
openDialog.value = false
},
title = {
Text(text = "Alert")
},
text = {
Text("Notification permission is required, to show notification")
},
buttons = {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
) {
TextButton(
onClick = {
openDialog.value = false
}
) {
Text("Cancel")
}
Spacer(modifier = Modifier.width(20.dp))
TextButton(
onClick = onclick,
) {
Text("Ok")
}
}
},
)
}
}
}
如果您的应用面向 Android 13 (Tiramisu) 或更高版本,则必须声明 POST_NOTIFICATIONS 权限,如下所示:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
有关更多详细信息,请参阅 Android 开发人员文档中的通知运行时权限页面。
int permissionState = ContextCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS);
// If the permission is not granted, request it.
if (permissionState == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.POST_NOTIFICATIONS}, 1);
}
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>// add this to menifest file
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.POST_NOTIFICATIONS}, 1);
}
else {
// repeat the permission or open app details
}
}
我使用https://github.com/zoontek/react-native-permissions
import {requestNotifications} from 'react-native-permissions';
await requestNotifications(['alert', 'badge', 'sound']);
并添加
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
到 androidManifest.xml
试试这个:
在您的 Activity 类中,添加以下代码:
private static final int NOTIFICATION_PERMISSION_CODE = 123;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity);
requestNotificationPermission();
// Some code
}
private void requestNotificationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NOTIFICATION_POLICY) == PackageManager.PERMISSION_GRANTED)
return;
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_NOTIFICATION_POLICY)) {
}
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_NOTIFICATION_POLICY}, NOTIFICATION_PERMISSION_CODE );
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
// Checking the request code of our request
if (requestCode == NOTIFICATION_PERMISSION_CODE ) {
// If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Displaying a toast
Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
// Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}