Android前台服务和通知

前台服务

Android 13及以上系统需要动态获取通知权限。

//android 13及以上系统动态获取通知权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {checkPostNotificationPermission();
}
private void checkPostNotificationPermission() {if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions((Activity) this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, 200);} else if (manager != null) {//通知ID设置(您可以使用任何您想要的ID,相同ID通知只会显示一个)。manager.notify(2, builder.build());}
}@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 200) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//允许了通知权限} else {Toast.makeText(this, "您拒绝了通知权限", Toast.LENGTH_SHORT).show();}}
}

别忘记添加通知权限

<!--发布通知权限-->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

开启前台服务需要添加前台服务权限

<!--前台服务权限-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

通知震动需要添加震动权限

<!--振动器权限-->
<uses-permission android:name="android.permission.VIBRATE" />

前台服务代码

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;import com.example.javatest.MainActivity;
import com.example.javatest.R;/*** created by cwj on 2023-10-19* Description: 前台服务*/
public class ForegroundService extends Service {@Overridepublic void onCreate() {super.onCreate();if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {CharSequence name = getString(R.string.app_name);int importance = NotificationManager.IMPORTANCE_DEFAULT;NotificationChannel channel = new NotificationChannel("CHANNEL_ID", name, importance);channel.setDescription("前台服务守护进程");NotificationManager notificationManager = getSystemService(NotificationManager.class);notificationManager.createNotificationChannel(channel);}//设置服务跳转Intent intent = new Intent(this, MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CHANNEL_ID")// 设置通知的小图标。.setSmallIcon(R.mipmap.ic_launcher)//设置通知的标题。.setContentTitle(getString(R.string.app_name))//设置通知的内容.setContentText("进程守护中")//设置通知的优先级。.setPriority(NotificationCompat.PRIORITY_DEFAULT)//震动模式的通知在Android O及以上。.setVibrate(new long[]{0, 1000, 500, 1000})//在Android O及以上的系统上使用LED光色和微信号。.setLights(Color.RED, 1000, 1000)//设置Android O及以上版本的通知声音。.setSound(Uri.parse("android.resource://" + this.getPackageName() + "/raw/notification_sound"))//如果需要,在Android O及以上版本设置较大的通知标题。// .setLargeTitle("Large Title Text")//如果需要,在Android O及以上版本设置通知的子文本。// .setSubText("Sub Text")//如果需要,在Android O及以上版本设置大字体通知。// .setStyle(new NotificationCompat.BigTextStyle().bigText("Big Text"))//如果需要,在Android O及以上版本设置通知摘要文本(当有多个具有相同优先级的通知时显示摘要文本)。// .setSummaryText("Summary Text")//如果需要,在通知中添加动作按钮(可用于启动活动或发送广播)。// .addAction(R.drawable.ic_action, "Action Title", PendingIntent)//设置可点击跳转.setContentIntent(pendingIntent);// 将通知设置为前台服务startForeground(1, builder.build());}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 在这里执行需要在前台运行的任务// 返回START_STICKY表示服务在被杀死后会自动重启return START_STICKY;}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onDestroy() {super.onDestroy();// 停止前台服务stopForeground(true);stopSelf();}
}

application中添加服务

<serviceandroid:name=".service.ForegroundService"android:enabled="true"android:exported="false" />

activity中启动服务

Intent intent = new Intent(this, ForegroundService.class);
// Android 8.0使用startForegroundService在前台启动新服务
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {startForegroundService(intent);
} else {startService(intent);

创建通知

 模拟发送通知

binding.iv.setOnClickListener(v ->showNotification(getString(R.string.app_name), dateToString(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "您收到一条消息")
);

创建通知及通知点击取消通知

private NotificationCompat.Builder builder;
private NotificationManagerCompat manager;private void showNotification(String title, String content) {// 创建通知频道,如果用户没有创建,则会自动创建。String CHANNEL_ID = "message";if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {if (getSystemService(NotificationManager.class).getNotificationChannel(CHANNEL_ID) == null) {NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "消息", NotificationManager.IMPORTANCE_DEFAULT);//通知的振动模式。channel.setVibrationPattern(new long[]{0, 1000, 500, 1000});//为通知通道启用振动。channel.enableVibration(true);//设置通道的颜色。channel.setLightColor(Color.RED);//设置通道的锁屏可见性。channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);getSystemService(NotificationManager.class).createNotificationChannel(channel);}}//设置服务跳转Intent intent = new Intent(this, MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);// 创建并分发通知。builder = new NotificationCompat.Builder(this, CHANNEL_ID)// 设置通知的小图标。.setSmallIcon(R.mipmap.ic_launcher)//设置通知的标题。.setContentTitle(title)//设置通知的内容.setContentText(content)//设置通知的优先级。.setPriority(NotificationCompat.PRIORITY_DEFAULT)//震动模式的通知在Android O及以上。.setVibrate(new long[]{0, 1000, 500, 1000})//在Android O及以上的系统上使用LED光色和微信号。.setLights(Color.RED, 1000, 1000)//设置Android O及以上版本的通知声音。.setSound(Uri.parse("android.resource://" + this.getPackageName() + "/raw/notification_sound"))//如果需要,在Android O及以上版本设置较大的通知标题。// .setLargeTitle("Large Title Text")//如果需要,在Android O及以上版本设置通知的子文本。// .setSubText("Sub Text")//如果需要,在Android O及以上版本设置大字体通知。// .setStyle(new NotificationCompat.BigTextStyle().bigText("Big Text"))//如果需要,在Android O及以上版本设置通知摘要文本(当有多个具有相同优先级的通知时显示摘要文本)。// .setSummaryText("Summary Text")//如果需要,在通知中添加动作按钮(可用于启动活动或发送广播)。// .addAction(R.drawable.ic_action, "Action Title", PendingIntent)//设置可点击跳转.setContentIntent(pendingIntent)//开启点按通知后自动移除通知.setAutoCancel(true);manager = NotificationManagerCompat.from(this);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {checkPostNotificationPermission();} else {// 在 Android 10 或更早版本中,不需要请求此权限。//ID要和前台服务ID区分开,相同ID只能显示一条通知。manager.notify(2, builder.build());}

activity完整代码

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;import android.Manifest;
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;import com.example.javatest.databinding.ActivityMainBinding;
import com.example.javatest.service.ForegroundService;import java.text.SimpleDateFormat;
import java.util.Date;public class MainActivity extends AppCompatActivity {private ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());initView();initData();}private void initView() {//android 13及以上系统动态获取通知权限if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {checkPostNotificationPermission();}Intent intent = new Intent(this, ForegroundService.class);// Android 8.0使用startForegroundService在前台启动新服务if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {startForegroundService(intent);} else {startService(intent);}}private void initData() {binding.iv.setOnClickListener(v ->showNotification(getString(R.string.app_name), dateToString(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "您收到一条消息"));}private String dateToString(long time, String format) {Date date = new Date(time);SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);return simpleDateFormat.format(date);}private NotificationCompat.Builder builder;private NotificationManagerCompat manager;private void showNotification(String title, String content) {// 创建通知频道,如果用户没有创建,则会自动创建。String CHANNEL_ID = "message";if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {if (getSystemService(NotificationManager.class).getNotificationChannel(CHANNEL_ID) == null) {NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "消息", NotificationManager.IMPORTANCE_DEFAULT);//通知的振动模式。channel.setVibrationPattern(new long[]{0, 1000, 500, 1000});//为通知通道启用振动。channel.enableVibration(true);//设置通道的颜色。channel.setLightColor(Color.RED);//设置通道的锁屏可见性。channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);getSystemService(NotificationManager.class).createNotificationChannel(channel);}}//设置服务跳转Intent intent = new Intent(this, MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);// 创建并分发通知。builder = new NotificationCompat.Builder(this, CHANNEL_ID)// 设置通知的小图标。.setSmallIcon(R.mipmap.ic_launcher)//设置通知的标题。.setContentTitle(title)//设置通知的内容.setContentText(content)//设置通知的优先级。.setPriority(NotificationCompat.PRIORITY_DEFAULT)//震动模式的通知在Android O及以上。.setVibrate(new long[]{0, 1000, 500, 1000})//在Android O及以上的系统上使用LED光色和微信号。.setLights(Color.RED, 1000, 1000)//设置Android O及以上版本的通知声音。.setSound(Uri.parse("android.resource://" + this.getPackageName() + "/raw/notification_sound"))//如果需要,在Android O及以上版本设置较大的通知标题。// .setLargeTitle("Large Title Text")//如果需要,在Android O及以上版本设置通知的子文本。// .setSubText("Sub Text")//如果需要,在Android O及以上版本设置大字体通知。// .setStyle(new NotificationCompat.BigTextStyle().bigText("Big Text"))//如果需要,在Android O及以上版本设置通知摘要文本(当有多个具有相同优先级的通知时显示摘要文本)。// .setSummaryText("Summary Text")//如果需要,在通知中添加动作按钮(可用于启动活动或发送广播)。// .addAction(R.drawable.ic_action, "Action Title", PendingIntent)//设置可点击跳转.setContentIntent(pendingIntent)//开启点按通知后自动移除通知.setAutoCancel(true);manager = NotificationManagerCompat.from(this);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {checkPostNotificationPermission();} else {// 在 Android 10 或更早版本中,不需要请求此权限。//显示ID为1的通知(您可以使用任何您想要的ID)。manager.notify(2, builder.build());}}private void checkPostNotificationPermission() {if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions((Activity) this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, 200);} else if (manager != null) {//显示ID为1的通知(您可以使用任何您想要的ID)。manager.notify(2, builder.build());}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 200) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//允许了通知权限} else {Toast.makeText(this, "您拒绝了通知权限", Toast.LENGTH_SHORT).show();}}}
}

完整配置文件AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><!--网络权限--><uses-permission android:name="android.permission.INTERNET" /><!--前台服务权限--><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><!--振动器权限--><uses-permission android:name="android.permission.VIBRATE" /><!--全屏意图权限--><uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /><!--发布通知权限--><uses-permission android:name="android.permission.POST_NOTIFICATIONS" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.JavaTest"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><serviceandroid:name=".service.ForegroundService"android:enabled="true"android:exported="false" /></application></manifest>

build.gradle.kts文件中添加viewBinding支持

buildFeatures{viewBinding = true
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/117997.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信息检索与数据挖掘 | 【实验】排名检索模型

文章目录 &#x1f4da;实验内容&#x1f4da;相关概念&#x1f4da;实验步骤&#x1f407;分词预处理&#x1f407;构建倒排索引表&#x1f407;计算query和各个文档的相似度&#x1f407;queries预处理及检索函数&#x1f525;对输入的文本进行词法分析和标准化处理&#x1f…

【Docker】Dockerfile使用技巧

开启Buildkit BuildKit是Docker官方社区推出的下一代镜像构建神器&#xff0c;可以更加快速&#xff0c;有效&#xff0c;安全地构建docker镜像。 尽管目前BuildKit不是Docker的默认构建工具&#xff0c;但是完全可以考虑将其作为Docker&#xff08;v18.09&#xff09;的首选…

一个注解让 Spring Boot 项目接口返回数据脱敏

1 背景 需求是某些接口返回的信息&#xff0c;涉及到敏感数据的必须进行脱敏操作 2 思路 ①要做成可配置多策略的脱敏操作&#xff0c;要不然一个个接口进行脱敏操作&#xff0c;重复的工作量太多&#xff0c;很显然违背了“多写一行算我输”的程序员规范。思来想去&#xff…

css如何将border线加到元素内部,占内边距,不占外边距

要将边框线添加到元素的内部&#xff0c;可以使用CSS的box-sizing属性和内边距&#xff08;padding&#xff09;来实现。 首先&#xff0c;将元素的box-sizing属性设置为border-box。这会使元素的宽度和高度包括边框和内边距在内。例如&#xff1a; .element {box-sizing: bo…

软件工程与计算总结(二十三)软件工程职业基础

本系列最后一更&#xff0c;《软计》系列总结的大结局&#xff01;本栏目告一段落&#xff0c;之后会结合真题和练习题再发布新的总结~ 往期链接&#xff1a; 《软件工程与计算》总结 一.软件工程职业 1.行业的发展 20世纪50年代&#xff1a;计算机还是研究型机器&#xff…

C++中显示构造和隐式构造

截图来源于C primerplus 第六版。

tomcat的负载均衡、动静分离(nginx联动)

动静分离&#xff1a; 访问静态页面和动态页面分开 实现动态和静态页面负载均衡 实验5台虚拟机 一、动态负载均衡 3台虚拟机模拟&#xff1a; 代理服务器&#xff1a;30 tomcat动态页面&#xff1a;21、22 代理服务器&#xff1a; proxy_pass http://tomcat; proxy_set_h…

buuctf[HCTF 2018]WarmUp 1

题目环境&#xff1a; 发现除了表情包&#xff0c;再无其他F12试试发现source.php文件访问这个文件&#xff0c;格式如下&#xff1a;url/source.php回显如下&#xff1a;PHP代码审计&#xff1a; <?php highlight_file(__FILE__); class emmm {public static function ch…

GIS在地质灾害危险性评估与灾后重建中的实践技术应用及python机器学习灾害易发性评价模型建立与优化

地质灾害是指全球地壳自然地质演化过程中&#xff0c;由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下&#xff0c;地质灾害在世界范围内频繁发生。我国除滑坡灾害外&#xff0c;还包括崩塌、泥石流、地面沉…

我们在 Linux 环境中用 C 编程时,如果对文件读写,Linux 会自动给文件加锁嘛?

先说结论&#xff0c;结论是不会 我写了一个这样的程序 #include <stdio.h> #include <unistd.h>int main() {const char* pathname "your_file_pathname.txt";FILE* file NULL;int count 100;if(access(pathname, F_OK) 0) {file fopen(pathname…

Onnx精度转换 FP32->FP16

Onnx精度转换 FP32->FP16 1、依赖包 onnxonnxmltools 2、转换 from onnxmltools.utils.float16_converter import convert_float_to_float16 from onnxmltools.utils import load_model,save_modelonnx_model load_model("model.onnx") fp16_model convert_…

C语言进阶第九课 --------动态内存管理

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

各种添加路由的方法

Linux 篇&#xff1a; ipv4: #添加到主机的路由 # route add –host 192.168.168.110 dev eth0 # route add –host 192.168.168.119 gw 192.168.168.1 #添加到网络的路由 # route add –net IP netmask MASK eth0 # route add –net IP netmask MASK gw IP # route add –n…

k8s-----19、Helm

Helm 1、引入2、概述2.1 重点2.2 V3版本的Helm2.2.1 与之前版本的不同之处2.2.2 V3版本的运行流程 3、安装和配置仓库、一些附带操作3.1 安装3.2 配置仓库3.3 常用命令3.4 添加helm的自动补齐 4、快速部署应用(weave应用)5、 自行创建Chart5.1 Chart目录内容解析5.2 简单安装部…

codeforces (C++ Haunted House)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、由题目可知&#xff0c;他想让我们判断交换相邻字符位置后将二进制转为十进制后&#xff0c;能否整除2的次方。能整除即输出需要交换的次数&#xff0c;不能则输出-1。&#xff08;例&#xff1a;输入3和010这组数据就…

论文学习:漏洞检测SnapVuln

SnapVuln SnapVuln是一种基于学习的漏洞检测方法&#xff0c;它应用多个针对特定漏洞的跨函数算法来识别源和汇点&#xff0c;以捕捉各种漏洞类型的精确程序语义。通过从源代码中提取跨函数的图形&#xff08;IG&#xff09;&#xff0c;SnapVuln可以综合使用PDG、CFG和调用图…

WebDAV之π-Disk派盘 +Polaris Office

推荐一款可以实现在Windows桌面PC,Mac,Android设备和iOS设备上同步的移动办公软件,还支持通过WebDAV添加葫芦儿派盘。Polaris Office是一款功能全面的办公自动化套件,软件集成了Word、Excel、幻灯片(PPT)、ODT等文档格式,并且可以完美兼容任何Microsoft Office,PDF,TXT或…

封装、继承、多态的概念

封装&#xff1a;将数据&#xff08;属性&#xff09;和函数&#xff08;操作&#xff09;合成一个整体&#xff0c;封装在类里面。 继承&#xff1a;派生与独立设计若干相关的类&#xff0c;前者工作量更少&#xff0c;重复的部分可以从基类继承来&#xff0c;不需要单独编程…

html web前端 登录,短信验证码登录

html web前端 登录&#xff0c;短信验证码登录 1&#xff0c;手机号码格式校验 2&#xff0c;按钮点击60秒倒计时&#xff0c;按钮限制点击 3&#xff0c;验证码/或密码长度校验&#xff08;被注释&#xff0c;公司发的验证码长度不一致&#xff0c;不一定是6位&#xff09; 4…

linux两块硬盘挂载同一个目录

参考&#xff1a;https://zhuanlan.zhihu.com/p/456193585 第一步&#xff1a;查看磁盘信息 查看现有物理卷信息 pvdisplay如果没有安装逻辑卷管理系统工具 apt install lvm2 ## 我用的 Ubuntu查看磁盘分区 fdisk -l我要用以下两块 SSD 来挂载到同一目录。 执行结果&…