技术标签: android 自定义推送布局
Notification的作用
Notification是一种全局效果的通知,在系统的通知栏中显示。既然作为通知,其基本作用有:
显示接收到短消息、即时信息等
显示客户端的推送(广告、优惠、新闻等)
显示正在进行的事物(后台运行的程序,如音乐播放进度、下载进度)
Notification的基本操作:
Notification的基本操作主要有创建、更新和取消三种。一个Notification的必要属性有三项,如果不设置的话在运行时会抛出异常:
小图标,通过setSmallIcon方法设置
标题,通过setContentTitle方法设置
内容,通过setContentText方法设置。
除了以上三项,其他均为可选项,不过一般而言,通知需要有交互的功能,所以一般Notification具有Action属性,这样就能跳转到App的某一个Activity、启动一个service或者发送一个Broadcast。
当系统受到通知时,可以通过震动、铃声、呼吸灯等多种方式进行提醒。
下面就从Notification的基本操作逐条介绍:
Notification的创建
Notification的创建过程主要涉及到Notification.Builder、Notification、NotificationManager
Notification.Builder:
使用建造者模式构建Notification对象。由于Notification.Builder仅支持Android4.1及之后的版本,为了解决兼容性的问题,使用V4兼容库中的NotifivationCompat.Builder类。
Notification:通知对应类,保存通知相关的数据。NotificationManager向系统发送通知时会用到。
NotificationManager:通知管理类,调用NotificationManager的notify方法可以向系统发送通知。
获取 NotificationManager 对象:
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
前面讲到,Notification有三个必要属性以及一个很有必要的属性Action。下面我们就创建一个简单的Notification,主要有以下三步:
获取NotificationManager实例
实例化NotificationCompat.Builder并设置相关属性
通过builder.build方法来生成Notification对象,并发送通知
private voidsendNotification(){
Intent intent= new Intent(this,SettingsActivity.class);
PendingIntent mPendingIntent= PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);
NotificationManager notificationManager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder= (NotificationCompat.Builder) new NotificationCompat.Builder(this)//设置小图标
.setSmallIcon(R.mipmap.ic_launcher)//点击后自动清除
.setAutoCancel(true)//设置通知标题
.setContentTitle("最简单的通知")//设置通知内容
.setContentText("真的很简单很简单很简单")//设置通知的动作
.setContentIntent(mPendingIntent)//设置通知时间,默认为系统发出通知的时间
.setWhen(System.currentTimeMillis());//第一个参数为Notification的id
notificationManager.notify(2,builder.build());
}
其中为了实现Action属性,我们需要创建Intent、PendingIntent和setContentIntent()这几步。
不难发现,其中的PendingIntent的设置才是其中的关键。
PendingIntent支持三种待定的意图:启动Activity,启动Service和发送Broadcast。对应于它的三个接口方法。
static PendingIntent
getActivity(Context context,int requestCode,Intent intent,int flags)
获取一个PendingIntent,该意图发生时,相当于Context.startActivity(Intent)
static PendingIntent
getService (Context context,int requestCode,Intent intent,int flags)
获取一个PendingIntent,该意图发生时,相当于Context.startService (Intent)
static PendingIntent
getBroadcast(Context context,int requestCode,Intent intent,int flags)
获取一个PendingIntent,该意图发生时,相当于Context.sendBroadcast(Intent)
其中context和intent不需要讲,主要说一下requestCode和flags。其中requestCode是PendingIntent发送发的请求码,多数情况下设置为0即可,requestCode会影响到flags的效果。
PendingIntent相同:Intent相同且requestCode也相同。(Intent相同需要ComponentName和intent-filter相同)
flags的常见类型有:
FLAG_ONE_SHOT:只能被使用一次,然后就会被自动cancel,如果后续还有相同的PendingIntent。那么他们的send方法就会调用失败。
FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统不会创建该PendingIntent对象,而是直接返回null。(很少使用)
FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。
FLAG_UPDATE_CURRENT:当前描述的PendingIntent如果已经存在,那么它们会被更新,即Intent中的Extras会被替换到最新的。
Notification的更新
更新通知的操作很简单,只需要再次发送一次相同ID的通知即可,如果之前的通知还没有被取消,则会直接更新该通知相关的属性;如果之前的通知已经被取消,则会重新创建一个新的通知。
更新通知和发送通知采用同样的方法。
Notification的取消
取消通知的方式主要有以下5种:
点击通知栏的清除按钮,会清除所有可清除的通知
设置了setAutoCancel()或者设置了flags为FLAG_AUTO_CANCEL的通知,点击通知时会自动清除。
通过NotificationManager调用cancel(int id)来取消指定id的通知
通过NotificationManager调用cancel(String tag,int id)方法清除指定Tag和ID的通知。
通过NotificationManager调用cancelAll()清除所有该应用之前发送的通知
如果是通过NotificationManager.notify(String tag, int id, Notification notify) 方法创建的通知,那么只能通过 NotificationManager.cancel(String tag, int id) 或cancelAll()方法才能清除对应的通知,调用NotificationManager.cancel(int id) 无效。
Notification的通知效果
前面提到了Notification的通知效果,有了通知效果更能提醒用户去查看Notification。
Notification的通知效果有震动、呼吸灯、铃声三种,可以通过builder中的setDefaults(int defaults)方法来设置,属性有以下四种,一旦设置了默认效果,自定义效果就会失效。
//添加默认震动效果,需要申请震动权限//
Notification.DEFAULT_VIBRATE//添加系统默认声音效果,设置此值后,调用setSound()设置自定义声音无效
Notification.DEFAULT_SOUND//添加默认呼吸灯效果,使用时须与 Notification.FLAG_SHOW_LIGHTS 结合使用,否则无效
Notification.DEFAULT_LIGHTS//添加上述三种默认提醒效果
Notification.DEFAULT_ALL
铃声:
//调用系统默认响铃,设置此属性后setSound()会无效//.setDefaults(Notification.DEFAULT_SOUND)//调用系统多媒体裤内的铃声//.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));//调用自己提供的铃声,位于 /res/values/raw 目录下
.setSound(Uri.parse("android.resource://com.littlejie.notification/" + R.raw.sound))
震动:
long[] vibrate = new long[]{0, 500, 1000, 1500};//使用系统默认的震动参数,会与自定义的冲突//.setDefaults(Notification.DEFAULT_VIBRATE)//自定义震动效果
.setVibrate(vibrate);
呼吸灯
//ledARGB 表示灯光颜色、 ledOnMS 亮持续时间、ledOffMS 暗的时间
.setLights(0xFF0000, 3000, 3000);
另一种方式:
Notification notification =builder.build();//只有在设置了标志符Flags为Notification.FLAG_SHOW_LIGHTS的时候,才支持呼吸灯提醒。
notify.flags=Notification.FLAG_SHOW_LIGHTS;//设置lights参数的另一种方式//notify.ledARGB = 0xFF0000;//notify.ledOnMS = 500;//notify.ledOffMS = 5000;
还可以通过以下几种Flag来设置通知效果
//提醒效果常用 Flag//三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_SHOW_LIGHTS//发起正在运行事件(活动中)
Notification.FLAG_ONGOING_EVENT//让声音、振动无限循环,直到用户响应 (取消或者打开)
Notification.FLAG_INSISTENT//发起Notification后,铃声和震动均只执行一次
Notification.FLAG_ONLY_ALERT_ONCE//用户单击通知后自动消失
Notification.FLAG_AUTO_CANCEL//只有调用NotificationManager.cancel()时才会清除
Notification.FLAG_NO_CLEAR//表示正在运行的服务
Notification.FLAG_FOREGROUND_SERVICE
上面讲到的Notification的布局都是系统默认的,当然有时候处于需求,我们可能需要自定义Notification的布局。
那如何实现Notification的自定义布局呢?
这里就需要提出一个新的知识点RemoteView,望文生义,即远程View。
RemoteView表示的是一种View结构,它可以在其他进程中显示(具体来讲是SystemServer进程),由于它是在其他进程中显示,为了更新它的界面,我们不能简单地使用普通View的那一套方法,RemoteView提供了一系列Set方法用于更新界面。
下面就是一个简单的示例;
packagecom.pignet.remoteviewtest;importandroid.app.Notification;importandroid.app.NotificationManager;importandroid.app.PendingIntent;importandroid.content.Context;importandroid.content.Intent;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;importandroid.widget.RemoteViews;public class MainActivity extendsAppCompatActivity {
@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnNotification=(Button) findViewById(R.id.btn_notification);
btnNotification.setOnClickListener(newView.OnClickListener() {
@Overridepublic voidonClick(View v) {
sendNotification();
}
});
}private voidsendNotification(){
NotificationManager notificationManager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification=newNotification();
notification.icon=R.mipmap.ic_launcher;
notification.when=System.currentTimeMillis();
notification.flags=Notification.FLAG_AUTO_CANCEL;//跳转意图
Intent intent= new Intent(this,SettingsActivity.class);//建立一个RemoteView的布局,并通过RemoteView加载这个布局
RemoteViews remoteViews= newRemoteViews(getPackageName(),R.layout.layout_notification);//为remoteView设置图片和文本
remoteViews.setTextViewText(R.id.message,"第一条通知");
remoteViews.setImageViewResource(R.id.image,R.mipmap.ic_launcher_round);//设置PendingIntent
PendingIntent pendingIntent= PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);//为id为openActivity的view设置单击事件
remoteViews.setOnClickPendingIntent(R.id.openActivity,pendingIntent);//将RemoteView作为Notification的布局
notification.contentView=remoteViews;//将pendingIntent作为Notification的intent,这样当点击其他部分时,也能实现跳转
notification.contentIntent=pendingIntent;
notificationManager.notify(1,notification);
}
}
有图:
java四种引用类型我们知道在java中引用也是一种数据类型,需要在stack中申请内存来保存引用,这点类似C语言中的指针,还不知道什么是引用的推荐这篇博客java值类型和引用类型。java对象的引用分为四种:强引用、软引用、弱引用、虚引用java提供不同引用类型的目的有两个:1,让程序员可以通过代码决定对象的生命周期。2,利于JVM进行垃圾回收。一,分别用一句话总结四种引用的异同1...
1.两数之和class Solution(object): def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ directory=dict()...
Windows下Cmake编译报错解决方案报错: 1. Building for: NMake Makefiles-- The C compiler identification is unknown-- The CXX compiler identification is unknownCMake Error at CMakeLists.txt:5 (PROJECT): The CMAKE_C_COMPILER: cl is not a full path and was
wywrw0512 于 2010-11-01 16:59:29发表:好,支持hbhychl 于 2010-10-06 16:11:53发表:新手报到hbhychl 于 2010-10-06 16:11:50发表:默认总的行数为1000,行号应该是动态的吧,不是很明白。olderlong 于 2010-10-05 21:15:26发表:默认总的行数为1000,行号应该是动态的吧,不是很明白。...
Java 中带参无返回值方法的使用有时方法的执行需要依赖于某些条件,换句话说,要想通过方法完成特定的功能,需要为其提供额外的信息才行。例如,现实生活中电饭锅可以实现“煮饭”的功能,但前提是我们必须提供食材,如果我们什么都不提供,那就真是的“巧妇难为无米之炊”了。我们可以通过在方法中加入参数列表接收外部传入的数据信息,参数可以是任意的基本类型数据或引用类型数据。我们先来看一个带...
原作者:Swagatam Das,Arijit Biswas,Sambarta Dasgupta,和Ajith Abraham[摘 要]细菌觅食优化算法(Bacterial foraging optimization algorithm[BFOA])已经被分布式优化和控制的同行们当作一种全局性的优化算法接受。BFOA是由大肠杆菌的群体觅食行为所启发而总结出来 的。BFOA...
grok默认表达式Logstash 内置了120种默认表达式,可以查看patterns,里面对表达式做了分组,每个文件为一组,文件内部有对应的表达式模式。下面只是部分常用的。常用表达式表达式标识名称详情匹配例子USERNAME 或 USER用户名...
图的总结——基本知识要点汇总,主要对图的基本工作原理进行总结,针对邻接矩阵、邻接表两种存储结构,对图的深度遍历、广度遍历等操作进行归纳,并对最小生成树、最短路径、拓扑排序、关键路径等应用问题进行原理性总结,给出部分操作集汇总
性能优化Q1:Draw Call和Setpass Call,这两个指标主要是看哪一个?关于这点众说纷纭,很多地方都是说看SetPass Call,但是在UWA的性能测试中,还是把Draw Call当成唯一指标。在 Unity 5.x 中,SetPass Call与 Draw Call相比,SetPass Call的指标与性能相关性更大(比如Static Batching
Treasure Hunting<br />http://acm.hdu.edu.cn/showproblem.php?pid=3641<br />Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)<br />Total Submission(s): 616 Accepted Submission(s): 200<br /><br />Problem DescriptionZstu_yh
HttpClient API常用方法解释:1.1 请求执行 HttpClient最重要的功能是执行HTTP方法。执行HTTP方法涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClient内部处理。 用户期望提供一个请求对象来执行,并且希望HttpClient将请求发送到目标服务器返回相应的响应对象,如果执行失败则抛出异常。 很自然,HttpClient API的主...
数值表达式1.奇偶判断2.小数精确计算3.int整数相乘溢出4.负的十六进制与八进制字面常量5.窄数字类型提升至宽类型时使用符号位扩展还是零扩展6.((byte)0x90 == 0x90)?7.三元表达式(?:)8.+=复合赋值问题9.i =++i;与i=i++;的区别10.Integer.MA...