1.官方文档

1.1 通知相关全部、详细文档

  https://developer.android.com/guide/topics/ui/notifiers/notifications

1.2 通知官方示例

  https://github.com/googlesamples/android-Notifications

  https://github.com/googlesamples/android-NotificationChannels

1.3 自定义通知文档

  https://developer.android.com/training/notify-user/custom-notification

    1. NotificationCompat.BigPictureStyle,
    2. NotificationCompat.BigTextStyle
    3. NotificationCompat.InboxStyle ,
    4. NotificationCompat.MessagingStyle,
    5. NotificationCompat.MediaStyle  音乐播放.
  • setStyle(new NotificationCompat.DecoratedCustomViewStyle()) 使用自定义样式.
  • 何时用@style/TextAppearance.Compat.Notification.Title
  • avoid setting a background image on your RemoteViews object, because your text color may become unreadable.
  • 完全自定义时: use setCustomBigContentView(), but do not call setStyle().
  • setContent() 兼容4.1及以下.

1.4 通过通知栏启动activity的方式

  https://developer.android.com/training/notify-user/navigation  

  • 启动常规Activity(含任务栈,保留原来顺序),使用TaskStackBuilder
  • 启动特殊Activity ,intent设置 FLAG_ACTIVITY_NEW_TASK

1.5 通知组

  https://developer.android.com/training/notify-user/group

  • Note: Notification groups are not the same as notification channel groups.
  • Note: If your app sends four or more notifications and does not specify a group, the system automatically groups them together on Android 7.0 and higher.
  • 关键api : setGroup()  setGroupSummary(true)

1.6 渠道管理

  https://developer.android.com/training/notify-user/channels

  • 8.0通过渠道设置通知优先级
  • 如何打开通知设置页面. Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); 等等...
  • 删除渠道.
  • 创建渠道组及何时有必要使用渠道组.

1.7 应用图标的通知角标

  https://developer.android.com/training/notify-user/badges

  • 8.0开始的新特性.
  • 通过渠道参数设置开启这个功能
  • setNumber() 设置通知角标数.

2.自定义通知示例

样式大致这样

2.1 自定义通知布局

 <?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"
android:orientation="vertical"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="64dp"> <ImageView
android:id="@+id/notify_icon"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
app:srcCompat="@mipmap/notify_icon" /> <TextView
android:id="@+id/notify_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxEms="9"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="#333333"
android:layout_toRightOf="@+id/notify_icon"
android:layout_alignTop="@+id/notify_icon"
android:layout_alignBottom="@+id/notify_icon"
android:textSize="10sp" /> <TextView
android:id="@+id/notify_progress_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/notify_icon"
android:layout_alignLeft="@+id/notify_icon"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:gravity="left|center_vertical"
android:maxEms="9"
android:maxLines="1"
android:text="title"
android:layout_toLeftOf="@+id/notify_progress_status"
android:textAllCaps="false"
android:textColor="#333333"
android:textSize="12sp"
android:textStyle="bold" /> <ProgressBar
android:id="@+id/notify_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="4dp"
android:layout_below="@+id/notify_progress_title"
android:layout_alignLeft="@+id/notify_progress_title"
android:layout_alignRight="@+id/notify_progress_status"
android:layout_marginTop="4dp"
android:progressDrawable="@drawable/notify_progress_bar" /> <TextView
android:id="@+id/notify_progress_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="25dp"
android:layout_alignBottom="@+id/notify_progress_title"
android:layout_alignTop="@+id/notify_progress_title"
android:layout_toLeftOf="@+id/notify_down_btn"
android:maxLines="1"
android:maxEms="9"
android:ellipsize="end"
android:textAllCaps="false"
android:textColor="#999999"
android:textSize="10sp"
android:gravity="center"
android:text="status" /> <ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:id="@+id/notify_down_btn"
android:background="@null"
android:layout_alignTop="@+id/notify_close_btn"
android:layout_marginRight="20dp"
android:layout_toLeftOf="@+id/notify_close_btn"
android:src="@mipmap/notify_start"
/> <ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:id="@+id/notify_close_btn"
android:layout_marginRight="15dp"
android:layout_alignTop="@+id/notify_progress_title"
android:src="@mipmap/notify_close"
android:background="@null"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="40dp"
android:layout_height="match_parent"
android:id="@+id/notify_close"
android:background="@color/hot_color"
android:layout_alignBottom="@+id/notify_progress"
android:layout_alignParentRight="true"
android:visibility="visible"
/>
<LinearLayout
android:id="@+id/notify_down"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/notify_close"
android:layout_toLeftOf="@+id/notify_close"
android:background="@color/hot_color"
android:src="@mipmap/notify_start"
android:orientation="vertical"
android:visibility="visible" /> </RelativeLayout>

注意事项:

  • 参考官方文档,考虑不同屏幕大小,通知栏的高度限制为:收起时为64dp,展开时为256dp
  • notify根布局目前(sdk api 28)还不能用约束布局。
  • 布局内不能出现 <View ....>
  • ImageView不要使用 app:srcCompat,用 android:src

2.2 初始化

     NotificationManagerCompat   mNotificationManager;
RemoteViews notifyView;
NotificationCompat.Builder builder; private void initNotify() {
//1.得到 NotificationManagerCompat mNotificationManager = NotificationManagerCompat.from(getApplicationContext());
//2.构造Notify上的View
notifyView = new RemoteViews(getPackageName(), R.layout.notify); //自定义notify上按钮的事件
Intent downIntent = new Intent(getApplicationContext(), NotifyReceiver.class);
downIntent.setAction(NotifyReceiver.DOWN_ACTION);
//用广播接收按钮事件,也可以用服务组件或者activity PendingIntent有一系列函数可选。
PendingIntent down = PendingIntent.getBroadcast(getApplicationContext(), , downIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notifyView.setOnClickPendingIntent(R.id.notify_down, down); Intent closeIntent = new Intent(getApplicationContext(), NotifyReceiver.class);
closeIntent.setAction(NotifyReceiver.CLOSE_ACTION); PendingIntent close = PendingIntent.getBroadcast(getApplicationContext(), , closeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notifyView.setOnClickPendingIntent(R.id.notify_close, close); //3.构造Notify,设置通知的参数
String channelId = getString(R.string.notify_id);//在 strings.xml中定义
builder = new NotificationCompat.Builder(getApplicationContext(),channelId); //点击整个通知栏时,响应通知的应用组件。
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent notifyIntent = PendingIntent.getActivity(getApplicationContext(), , intent, PendingIntent.FLAG_UPDATE_CURRENT); //设置通知栏参数
builder.setWhen(System.currentTimeMillis())
.setPriority(NotificationCompat.PRIORITY_MAX) //优先级.
.setAutoCancel(true)
.setOngoing(false)
.setContentIntent(notifyIntent)
.setCustomContentView(notifyView) //完全自定义,不调用.setStyle()
.setContent(notifyView) //兼容4.1及以下
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
.setOnlyAlertOnce(true)
.setSmallIcon(R.mipmap.notify_logo);
}
  • 初始notify上自定义的view,重点在按钮事件
  • 如果在一定时间内通知的频繁,系统会忽略其中的一部分.
  • OnlyAlterOnce保证频频调用时,声音等警示事件只1次.
  • RemoteViews和NotificationCompat.Builder 保存成成员变量是因为notify的频次高,不用每次都构造.

2.3 发出通知

     public synchronized void showDownloadingNotify() {
//4.根据业务逻辑控制notify上控件的状态
//...这里略
int icon = downloading ? R.mipmap.notify_pause : R.mipmap.notify_start; int pro = (int) (downloaded * 100.00F / total);
Log.e(TAG, "showDownloadingNotify: downloading progress = " + pro); notifyView.setTextViewText(R.id.notify_progress_title, title);
notifyView.setTextViewText(R.id.notify_progress_status,getString(R.string.downloading_downloaded) + " " + pro + "%" );
notifyView.setImageViewResource(R.id.notify_down_btn, icon);
notifyView.setProgressBar(R.id.notify_progress,, pro,false); Notification notify = builder.build(); //5.发出通知
String channelId = getString(R.string.notify_id);//在 strings.xml中定义
mNotificationManager.notify(Integer.valueOf(channelId), notify);
}

  注意控制发出通知的频率,不要太快,如:

         if(last < ){
last = SystemClock.elapsedRealtime() / ;
}
long now = SystemClock.elapsedRealtime() / ;
if (now - last > ){
last = now;
showDownloadingNotify();
}

2.4 接收通知按钮事件的组件

本示例中使用的是广播,也可以用服务和activity

 public class NotifyReceiver extends BroadcastReceiver {
public final static String DOWN_ACTION = "com.cnblogs.sjjg.notifications.intent.action.DownClick";
public final static String CLOSE_ACTION = "com.cnblogs.sjjg.notifications.intent.action.CloseClick"; @Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e("NotifyReceiver", "onReceive: action = " + action);
switch (action) {
case DOWN_ACTION:
//处理第1个按钮事件,开始下载
break;
case CLOSE_ACTION:
//处理第2个按钮事件,关闭通知
break;
default:
break;
}
}
}

在AndroidManifest.xml中注册

      ...
<receiver
android:name=".main.NotifyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.cnblogs.sjjg.notifications.intent.action.DownClick" />
<action android:name="com.cnblogs.sjjg.notifications.intent.action.CloseClick" />
</intent-filter>
</receiver>
...

2.5 取消通知

  取消的id要与发出的id相同。

     public void cancelNotify(){
String channelId = getString(R.string.notify_id);
mNotificationManager.cancel(Integer.valueOf(channelId));
}

3.android 8.0适配

3.1 变化

  • 必须将各个通知放入特定渠道中,否则不显示.一个应用可以有多个渠道.
  • 用户可以按渠道关闭通知,而非关闭来自某个应用的所有通知。
  • 包含有效通知的应用将在主屏幕/启动器屏幕上相应应用图标的上方显示通知“标志”。
  • 用户可以从抽屉式通知栏中暂停某个通知。可以为通知设置自动超时时间。
  • 可以设置通知的背景颜色。
  • 部分与通知行为相关的 API 从 Notification 移至了 NotificationChannel。例如,在搭载 Android 8.0 及更高版本的设备中,使用 NotificationChannel.setImportance(),而非 NotificationCompat.Builder.setPriority()

3.2 创建通知渠道

选择适当时机,创建渠道.

    @RequiresApi(api = Build.VERSION_CODES.O)
private void createNotifyChannel(){
NotificationManager nm = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = getString(R.string.notify_id);
NotificationChannel channel = nm.getNotificationChannel(channelId);
if (channel == null){
channel = new NotificationChannel(channelId, "Downloader", NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true);
channel.setLightColor(Color.RED);
channel.setImportance(NotificationManager.IMPORTANCE_DEFAULT);
channel.setShowBadge(true);
nm.createNotificationChannel(channel);
}
}

3.3 检测通知权限是否打开

        NotificationManagerCompat mNotificationManager;
mNotificationManager = NotificationManagerCompat.from(getContext());
boolean enable = mNotificationManager.areNotificationsEnabled();
if (!enable){
//打开通知权限
...
}

3.4 打开通知权限

         final int NOTIFY_PER = ;
Intent intent = new Intent();
Context context = getContext();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName());
}else if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH){
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra("app_package", context.getPackageName());
intent.putExtra("app_uid", context.getApplicationInfo().uid);
}else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT){
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + context.getPackageName()));
}else{
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
}
startActivityForResult(intent, NOTIFY_PER);

3.5 接收打开结果

     @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
final int NOTIFY_PER = ;
if (requestCode == NOTIFY_PER){
NotificationManagerCompat notifyMgr = NotificationManagerCompat.from(getContext());
boolean enable = notifyMgr.areNotificationsEnabled();
Log.e("MainPresenter", "onActivityResult: request notify = " + enable );
if (!enable){
Snackbar.make(more,"通知功能没有打开,无法在通知栏上显示进度!",Snackbar.LENGTH_SHORT).show();
}
}
}

4.系统自带通知栏

      fun showNotify(warning: Warning){
var mgr = NotificationManagerCompat.from(applicationContext)
var notifyId = getString(R.string.notify_id) var content = warning.oldie.name + " " + warning.getTypeString()
var builder = NotificationCompat.Builder(applicationContext,notifyId)
var intent = Intent(applicationContext, MainActivity::class.java)
var pendingIntent = PendingIntent.getActivity(this, , intent, );
builder.setContentIntent(pendingIntent);
builder.setWhen(System.currentTimeMillis())
.setPriority(NotificationCompat.PRIORITY_MAX) //优先级.
.setAutoCancel(true)
.setOngoing(false) //常驻通知栏
.setContentText(content)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.warning))
.setContentTitle("监护警报")
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
.setOnlyAlertOnce(true)
.setSmallIcon(R.mipmap.icon)
var notify = builder.build()
mgr.notify(notifyId.toInt(),notify)
}
fun cancelNotify(){
var mgr = NotificationManagerCompat.from(applicationContext) val channelId = getString(R.string.notify_id) mgr.cancel(channelId.toInt())
}

px,dp,sp单位转换工具类的更多相关文章

  1. android px,dp,sp大小转换工具

    package com.voole.playerlib.util; import android.content.Context; /** * Android大小单位转换工具类<br/> ...

  2. Android原生系统API自带dp、px、sp单位转换

    Android系统中自带的Api中可以使用TypedValue进行单位转换 1,调用系统api转换单位 // 获得转换后的px值 float pxDimension = TypedValue.appl ...

  3. (转)Android中px与dip,sp与dip等的转换工具类

    功能 通常在代码中设置组件或文字大小只能用px,通过这个工具类我们可以把dip(dp)或sp为单位的值转换为以px为单位的值而保证大小不变.方法中的参数请参考http://www.cnblogs.co ...

  4. DensityUtil【尺寸转换工具类(px、dp互相转换)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于项目中dp.px.sp之间的转换以及指定缩放值下的转换. 效果图 暂不需要 代码分析 常用的方法是px2dip.dip2px: ...

  5. 我的Android进阶之旅------>Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换)

    Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换) 有时候要做出如下所示的展示文件大小的效果时候,需要对文件大小进行转换,然后再进行相关的代码逻辑编写. 下面是一个Java ...

  6. Json与javaBean之间的转换工具类

    /**  * Json与javaBean之间的转换工具类  *  * {@code 现使用json-lib组件实现  *    需要  *     json-lib-2.4-jdk15.jar  * ...

  7. 日期转换工具类 CommUtil.java

    package com.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...

  8. Android Bitmap与DrawAble与byte[]与InputStream之间的转换工具类【转】

    package com.soai.imdemo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; ...

  9. java 二进制数字符串转换工具类

    java 二进制数字符串转换工具类 将二进制转换成八进制 将二进制转换成十进制 将二进制转换成十六进制 将十进制转换成二进制 package com.iteye.injavawetrust.ad; i ...

随机推荐

  1. 幻灯片slider

    <script src="{$GetInstallDir}web/scripts/jquery-1.3.1.js"></script> <style& ...

  2. mysql5.5 Replication 主从同步

    mysql5.5 Replication 主从同步 ------------------[主]------------------[mysqld]server-id=1 log-bin=mysql-b ...

  3. 按键消抖VERILOG实现

    对于消抖,有很多种写法.今天分享一下我的写法. 基本思路: 1. 看图                     图1                                           ...

  4. sharepoint 2010

    Technical diagrams (SharePoint Server 2010) http://technet.microsoft.com/en-us/library/cc263199(offi ...

  5. JDBC连接数据库代码

    //连接是需要导包 http://pan.baidu.com/s/1o6nyuOa /*配合数据库建立表 create database day14 character set utf8 collat ...

  6. VS2010 配置opencv环境

    大家在使用opencv的时候肯定会面对这样一个问题:根据官网以及大多数教程提供的方法中,似乎每一次新建一个opencv的新项目以后都需要重新再配置"VC++目录"中的"包 ...

  7. java集合类(三)About Iterator & Vector(Stack)

    接上篇:java集合类学习(二) Talk about “Iterator”: 任何容器类,在插入元素后,还需要取回元素,因为这是容器的最基本工作.对于一般的容器,插入有add()相关方法(List, ...

  8. maven学习心得整理

    maven的学习心得 已经接触了maven项目有一段时间了,开始时仅仅会使用,在使用中发现了它的强大和方便,于是决心研究一下: 首先,普及一下maven参数: -D:传入属性参数 -P:使用POM中指 ...

  9. c# 取 list前100条数据

    [问] List<KeyWord> sortedList = (from a in keyWordList orderby a.Total descending select a).ToL ...

  10. EXT--表单AJax提交后台,返回前端数据格式的转换

    前言: 前端发送请求至服务端(Java),得到的数据是Java语言对象所表现的形式,经常需要转换为JSON格式的字符串写出至前端:当前端获取后也往往需要将字符串转换为js的对象.本文描述了在EXT作为 ...