px,dp,sp单位转换工具类
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
- https://developer.android.com/training/notify-user/expanded.html 已有通知的样式,可以扩展它们.
- NotificationCompat.BigPictureStyle,
- NotificationCompat.BigTextStyle
- NotificationCompat.InboxStyle ,
- NotificationCompat.MessagingStyle,
- 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单位转换工具类的更多相关文章
- android px,dp,sp大小转换工具
package com.voole.playerlib.util; import android.content.Context; /** * Android大小单位转换工具类<br/> ...
- Android原生系统API自带dp、px、sp单位转换
Android系统中自带的Api中可以使用TypedValue进行单位转换 1,调用系统api转换单位 // 获得转换后的px值 float pxDimension = TypedValue.appl ...
- (转)Android中px与dip,sp与dip等的转换工具类
功能 通常在代码中设置组件或文字大小只能用px,通过这个工具类我们可以把dip(dp)或sp为单位的值转换为以px为单位的值而保证大小不变.方法中的参数请参考http://www.cnblogs.co ...
- DensityUtil【尺寸转换工具类(px、dp互相转换)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 用于项目中dp.px.sp之间的转换以及指定缩放值下的转换. 效果图 暂不需要 代码分析 常用的方法是px2dip.dip2px: ...
- 我的Android进阶之旅------>Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换)
Java文件大小转换工具类 (B,KB,MB,GB,TB,PB之间的大小转换) 有时候要做出如下所示的展示文件大小的效果时候,需要对文件大小进行转换,然后再进行相关的代码逻辑编写. 下面是一个Java ...
- Json与javaBean之间的转换工具类
/** * Json与javaBean之间的转换工具类 * * {@code 现使用json-lib组件实现 * 需要 * json-lib-2.4-jdk15.jar * ...
- 日期转换工具类 CommUtil.java
package com.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...
- Android Bitmap与DrawAble与byte[]与InputStream之间的转换工具类【转】
package com.soai.imdemo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; ...
- java 二进制数字符串转换工具类
java 二进制数字符串转换工具类 将二进制转换成八进制 将二进制转换成十进制 将二进制转换成十六进制 将十进制转换成二进制 package com.iteye.injavawetrust.ad; i ...
随机推荐
- 幻灯片slider
<script src="{$GetInstallDir}web/scripts/jquery-1.3.1.js"></script> <style& ...
- mysql5.5 Replication 主从同步
mysql5.5 Replication 主从同步 ------------------[主]------------------[mysqld]server-id=1 log-bin=mysql-b ...
- 按键消抖VERILOG实现
对于消抖,有很多种写法.今天分享一下我的写法. 基本思路: 1. 看图 图1 ...
- sharepoint 2010
Technical diagrams (SharePoint Server 2010) http://technet.microsoft.com/en-us/library/cc263199(offi ...
- JDBC连接数据库代码
//连接是需要导包 http://pan.baidu.com/s/1o6nyuOa /*配合数据库建立表 create database day14 character set utf8 collat ...
- VS2010 配置opencv环境
大家在使用opencv的时候肯定会面对这样一个问题:根据官网以及大多数教程提供的方法中,似乎每一次新建一个opencv的新项目以后都需要重新再配置"VC++目录"中的"包 ...
- java集合类(三)About Iterator & Vector(Stack)
接上篇:java集合类学习(二) Talk about “Iterator”: 任何容器类,在插入元素后,还需要取回元素,因为这是容器的最基本工作.对于一般的容器,插入有add()相关方法(List, ...
- maven学习心得整理
maven的学习心得 已经接触了maven项目有一段时间了,开始时仅仅会使用,在使用中发现了它的强大和方便,于是决心研究一下: 首先,普及一下maven参数: -D:传入属性参数 -P:使用POM中指 ...
- c# 取 list前100条数据
[问] List<KeyWord> sortedList = (from a in keyWordList orderby a.Total descending select a).ToL ...
- EXT--表单AJax提交后台,返回前端数据格式的转换
前言: 前端发送请求至服务端(Java),得到的数据是Java语言对象所表现的形式,经常需要转换为JSON格式的字符串写出至前端:当前端获取后也往往需要将字符串转换为js的对象.本文描述了在EXT作为 ...