NotificationUtils.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. package com.yc.music.utils;
  2. import android.annotation.TargetApi;
  3. import android.app.Notification;
  4. import android.app.NotificationChannel;
  5. import android.app.NotificationManager;
  6. import android.app.PendingIntent;
  7. import android.content.Context;
  8. import android.content.ContextWrapper;
  9. import android.graphics.Color;
  10. import android.net.Uri;
  11. import android.os.Build;
  12. import android.widget.RemoteViews;
  13. import androidx.annotation.RequiresApi;
  14. import androidx.core.app.NotificationCompat;
  15. import static androidx.core.app.NotificationCompat.PRIORITY_DEFAULT;
  16. import static androidx.core.app.NotificationCompat.VISIBILITY_SECRET;
  17. /**
  18. * <pre>
  19. * @author yangchong
  20. * blog : https://www.jianshu.com/p/514eb6193a06
  21. * time : 2018/2/10
  22. * desc : 通知栏工具类
  23. * revise:
  24. * </pre>
  25. */
  26. public class NotificationUtils extends ContextWrapper {
  27. public static final String CHANNEL_ID = "default";
  28. private static final String CHANNEL_NAME = "Default_Channel";
  29. public static boolean isVibration = false;
  30. private NotificationManager mManager;
  31. private int[] flags;
  32. public NotificationUtils(Context base) {
  33. super(base);
  34. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  35. //android 8.0以上需要特殊处理,也就是targetSDKVersion为26以上
  36. createNotificationChannel();
  37. }
  38. }
  39. @TargetApi(Build.VERSION_CODES.O)
  40. private void createNotificationChannel() {
  41. //第一个参数:channel_id
  42. //第二个参数:channel_name
  43. //第三个参数:设置通知重要性级别
  44. //注意:该级别必须要在 NotificationChannel 的构造函数中指定,总共要五个级别;
  45. //范围是从 NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4)
  46. NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
  47. NotificationManager.IMPORTANCE_DEFAULT);
  48. getManager().createNotificationChannel(channel);
  49. }
  50. /**
  51. * 获取创建一个NotificationManager的对象
  52. * @return NotificationManager对象
  53. */
  54. public NotificationManager getManager() {
  55. if (mManager == null) {
  56. mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  57. }
  58. return mManager;
  59. }
  60. /**
  61. * 清空所有的通知
  62. */
  63. public void clearNotification(){
  64. getManager().cancelAll();
  65. }
  66. /**
  67. * 获取Notification
  68. * @param title title
  69. * @param content content
  70. */
  71. public Notification getNotification(String title, String content , int icon){
  72. Notification build;
  73. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  74. //android 8.0以上需要特殊处理,也就是targetSDKVersion为26以上
  75. //通知用到NotificationCompat()这个V4库中的方法。但是在实际使用时发现书上的代码已经过时并且Android8.0已经不支持这种写法
  76. Notification.Builder builder = getChannelNotification(title, content, icon);
  77. build = builder.build();
  78. } else {
  79. NotificationCompat.Builder builder = getNotificationCompat(title, content, icon);
  80. build = builder.build();
  81. }
  82. if (flags!=null && flags.length>0){
  83. for (int a=0 ; a<flags.length ; a++){
  84. build.flags |= flags[a];
  85. }
  86. }
  87. return build;
  88. }
  89. /**
  90. * 建议使用这个发送通知
  91. * 调用该方法可以发送通知
  92. * @param notifyId notifyId
  93. * @param title title
  94. * @param content content
  95. */
  96. public void sendNotification(int notifyId, String title, String content , int icon) {
  97. Notification build;
  98. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  99. //android 8.0以上需要特殊处理,也就是targetSDKVersion为26以上
  100. //通知用到NotificationCompat()这个V4库中的方法。但是在实际使用时发现书上的代码已经过时并且Android8.0已经不支持这种写法
  101. Notification.Builder builder = getChannelNotification(title, content, icon);
  102. build = builder.build();
  103. } else {
  104. NotificationCompat.Builder builder = getNotificationCompat(title, content, icon);
  105. build = builder.build();
  106. }
  107. if (flags!=null && flags.length>0){
  108. for (int a=0 ; a<flags.length ; a++){
  109. build.flags |= flags[a];
  110. }
  111. }
  112. getManager().notify(notifyId, build);
  113. }
  114. /**
  115. * 调用该方法可以发送通知
  116. * @param notifyId notifyId
  117. * @param title title
  118. * @param content content
  119. */
  120. public void sendNotificationCompat(int notifyId, String title, String content , int icon) {
  121. NotificationCompat.Builder builder = getNotificationCompat(title, content, icon);
  122. Notification build = builder.build();
  123. if (flags!=null && flags.length>0){
  124. for (int a=0 ; a<flags.length ; a++){
  125. build.flags |= flags[a];
  126. }
  127. }
  128. getManager().notify(notifyId, build);
  129. }
  130. private NotificationCompat.Builder getNotificationCompat(String title, String content, int icon) {
  131. NotificationCompat.Builder builder;
  132. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  133. builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
  134. } else {
  135. //注意用下面这个方法,在8.0以上无法出现通知栏。8.0之前是正常的。这里需要增强判断逻辑
  136. builder = new NotificationCompat.Builder(getApplicationContext());
  137. builder.setPriority(PRIORITY_DEFAULT);
  138. }
  139. builder.setContentTitle(title);
  140. builder.setContentText(content);
  141. builder.setSmallIcon(icon);
  142. builder.setPriority(priority);
  143. builder.setOnlyAlertOnce(onlyAlertOnce);
  144. builder.setOngoing(ongoing);
  145. if (remoteViews!=null){
  146. builder.setContent(remoteViews);
  147. }
  148. if (intent!=null){
  149. builder.setContentIntent(intent);
  150. }
  151. if (ticker!=null && ticker.length()>0){
  152. builder.setTicker(ticker);
  153. }
  154. if (when!=0){
  155. builder.setWhen(when);
  156. }
  157. if (sound!=null){
  158. builder.setSound(sound);
  159. }
  160. if (defaults!=0){
  161. builder.setDefaults(defaults);
  162. }
  163. //点击自动删除通知
  164. builder.setAutoCancel(true);
  165. return builder;
  166. }
  167. @RequiresApi(api = Build.VERSION_CODES.O)
  168. private Notification.Builder getChannelNotification(String title, String content, int icon){
  169. Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID);
  170. Notification.Builder notificationBuilder = builder
  171. //设置标题
  172. .setContentTitle(title)
  173. //消息内容
  174. .setContentText(content)
  175. //设置通知的图标
  176. .setSmallIcon(icon)
  177. //让通知左右滑的时候是否可以取消通知
  178. .setOngoing(ongoing)
  179. //设置优先级
  180. .setPriority(priority)
  181. //是否提示一次.true - 如果Notification已经存在状态栏即使在调用notify函数也不会更新
  182. .setOnlyAlertOnce(onlyAlertOnce)
  183. .setAutoCancel(true);
  184. if (remoteViews!=null){
  185. //设置自定义view通知栏
  186. notificationBuilder.setContent(remoteViews);
  187. }
  188. if (intent!=null){
  189. notificationBuilder.setContentIntent(intent);
  190. }
  191. if (ticker!=null && ticker.length()>0){
  192. //设置状态栏的标题
  193. notificationBuilder.setTicker(ticker);
  194. }
  195. if (when!=0){
  196. //设置通知时间,默认为系统发出通知的时间,通常不用设置
  197. notificationBuilder.setWhen(when);
  198. }
  199. if (sound!=null){
  200. //设置sound
  201. notificationBuilder.setSound(sound);
  202. }
  203. if (defaults!=0){
  204. //设置默认的提示音
  205. notificationBuilder.setDefaults(defaults);
  206. }
  207. if (pattern!=null){
  208. //自定义震动效果
  209. notificationBuilder.setVibrate(pattern);
  210. }
  211. return notificationBuilder;
  212. }
  213. private boolean ongoing = false;
  214. private RemoteViews remoteViews = null;
  215. private PendingIntent intent = null;
  216. private String ticker = "";
  217. private int priority = Notification.PRIORITY_DEFAULT;
  218. private boolean onlyAlertOnce = false;
  219. private long when = 0;
  220. private Uri sound = null;
  221. private int defaults = 0;
  222. private long[] pattern = null;
  223. /**
  224. * 让通知左右滑的时候是否可以取消通知
  225. * @param ongoing 是否可以取消通知
  226. * @return
  227. */
  228. public NotificationUtils setOngoing(boolean ongoing){
  229. this.ongoing = ongoing;
  230. return this;
  231. }
  232. /**
  233. * 设置自定义view通知栏布局
  234. * @param remoteViews view
  235. * @return
  236. */
  237. public NotificationUtils setContent(RemoteViews remoteViews){
  238. this.remoteViews = remoteViews;
  239. return this;
  240. }
  241. /**
  242. * 设置内容点击
  243. * @param intent intent
  244. * @return
  245. */
  246. public NotificationUtils setContentIntent(PendingIntent intent){
  247. this.intent = intent;
  248. return this;
  249. }
  250. /**
  251. * 设置状态栏的标题
  252. * @param ticker 状态栏的标题
  253. * @return
  254. */
  255. public NotificationUtils setTicker(String ticker){
  256. this.ticker = ticker;
  257. return this;
  258. }
  259. /**
  260. * 设置优先级
  261. * 注意:
  262. * Android 8.0以及上,在 NotificationChannel 的构造函数中指定,总共要五个级别;
  263. * Android 7.1(API 25)及以下的设备,还得调用NotificationCompat 的 setPriority方法来设置
  264. *
  265. * @param priority 优先级,默认是Notification.PRIORITY_DEFAULT
  266. * @return
  267. */
  268. public NotificationUtils setPriority(int priority){
  269. this.priority = priority;
  270. return this;
  271. }
  272. /**
  273. * 是否提示一次.true - 如果Notification已经存在状态栏即使在调用notify函数也不会更新
  274. * @param onlyAlertOnce 是否只提示一次,默认是false
  275. * @return
  276. */
  277. public NotificationUtils setOnlyAlertOnce(boolean onlyAlertOnce){
  278. this.onlyAlertOnce = onlyAlertOnce;
  279. return this;
  280. }
  281. /**
  282. * 设置通知时间,默认为系统发出通知的时间,通常不用设置
  283. * @param when when
  284. * @return
  285. */
  286. public NotificationUtils setWhen(long when){
  287. this.when = when;
  288. return this;
  289. }
  290. /**
  291. * 设置sound
  292. * @param sound sound
  293. * @return
  294. */
  295. public NotificationUtils setSound(Uri sound){
  296. this.sound = sound;
  297. return this;
  298. }
  299. /**
  300. * 设置默认的提示音
  301. * @param defaults defaults
  302. * @return
  303. */
  304. public NotificationUtils setDefaults(int defaults){
  305. this.defaults = defaults;
  306. return this;
  307. }
  308. /**
  309. * 自定义震动效果
  310. * @param pattern pattern
  311. * @return
  312. */
  313. public NotificationUtils setVibrate(long[] pattern){
  314. this.pattern = pattern;
  315. return this;
  316. }
  317. /**
  318. * 设置flag标签
  319. * @param flags flags
  320. * @return
  321. */
  322. public NotificationUtils setFlags(int... flags){
  323. this.flags = flags;
  324. return this;
  325. }
  326. }