首页 > 代码库 > 各种Notification详解,含工具类
各种Notification详解,含工具类
昨天一天只写了两篇文章,效率超低。追其原因呢,其实我一直在研究notification的实现方式,今天研究完了给大家分享一下。本来想写个工具类来封装一下代码的,但是我发现notification的个性化元素太多了,做成一个方法的话参数又多的要死,于是我就将比较常见的方法做了封装,写了个不是很规整的工具类,至于内部的逻辑啊,点击跳转的事件啊,大家下载demo后看看代码应该就能明白了,最重要的是根据自己的需要选择好的方法。还有一点需要建议的是,如果你发的通知都是用同一个ID的话可能会出现通知叠加的情况,这点需要注意一下。还是那句话根据实际需要吧,如果我的通知类型都是一样的,用同一个ID叠加就让他叠加吧。好啦,下面我们来看代码。
首先还是布局文件,这里用的全是button,在布局界面直接绑定了监听器。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.kale.notification.MainActivity" android:orientation="vertical"> <Button android:id="@+id/normal_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="普通的通知" android:onClick="buttonListener"/> <Button android:id="@+id/view_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="较为特别的通知" android:onClick="buttonListener"/> <Button android:id="@+id/private_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="自定义布局的通知" android:onClick="buttonListener"/> <Button android:id="@+id/big_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="可以显示多行信息的通知" android:onClick="buttonListener"/> <Button android:id="@+id/progress_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="有进度条的通知" android:onClick="buttonListener"/> <Button android:id="@+id/pic_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="有大图片的通知" android:onClick="buttonListener"/> <Button android:id="@+id/btn_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="有两个按钮的通知" android:onClick="buttonListener"/> <Button android:id="@+id/clear_button_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:text="清除所有的通知" android:onClick="buttonListener"/></LinearLayout>
自定义的通知布局
notification.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000"> <ImageView android:id="@+id/image" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignParentLeft="true" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" android:layout_marginLeft="8.0dip" android:layout_marginRight="10dp" android:src="@drawable/ic_launcher"/> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/title" android:layout_marginTop="3.0dip" android:layout_toLeftOf="@+id/button" android:layout_toRightOf="@id/image" android:text="This is the text" android:textColor="#ffffff" android:textSize="16sp" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/text" android:layout_alignTop="@+id/image" android:textStyle="bold" android:text="title" android:textColor="#ffffff" android:textSize="16sp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/image" android:layout_alignParentRight="true" android:gravity="center_vertical" android:text="跳转" android:textColor="#ffffff" /></RelativeLayout>
点击通知信息,跳转的activity界面
other.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.50" android:layout_gravity="center" android:gravity="center_horizontal" android:text="用PendingIntent跳转到的界面" android:textAppearance="?android:attr/textAppearanceLarge" /></LinearLayout>
这个界面对应的activity就是个空的activity——OtherActivity.java,代码就不贴了。
主界面
MainAcitivity.java
package com.kale.notification;import android.app.Activity;import android.app.PendingIntent;import android.content.Intent;import android.os.Bundle;import android.os.SystemClock;import android.view.View;import android.widget.RemoteViews;public class MainActivity extends Activity { NotificationAdmain admain; static int NOTIFICATION_ID = 13565400; Intent intent; int smallIcon = R.drawable.ic_launcher; String ticker = "来了条新的通知"; int LargeIcon = R.drawable.kale; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置点击后启动的activity intent = new Intent(MainActivity.this, OtherActivity.class); admain = new NotificationAdmain(this,NOTIFICATION_ID); } public void buttonListener(View v) { switch (v.getId()) { case R.id.normal_button_id: admain.normal_notification(intent, smallIcon, ticker, "普通的通知", "采用默认配置,这里的文字只能显示一行,会将多余的字影藏"); break; case R.id.view_button_id: admain.special_notification(intent, smallIcon, ticker, LargeIcon, "特殊的通知", "这里面大小图标同时存在,并且有数字"); break; case R.id.private_button_id: //设置自定义布局中按钮的跳转界面 Intent btnIntent = new Intent(MainActivity.this,OtherActivity.class); btnIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); //如果是启动activity,那么就用PendingIntent.getActivity,如果是启动服务,那么是getService PendingIntent Pintent = PendingIntent.getActivity(this, (int) SystemClock.uptimeMillis(), btnIntent, PendingIntent.FLAG_UPDATE_CURRENT); // 自定义布局 RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification); remoteViews.setImageViewResource(R.id.image, R.drawable.kale); remoteViews.setTextViewText(R.id.title, "自定义通知视图"); remoteViews.setTextViewText(R.id.text, "这个自定义通知栏只能这么高了,不能有再多的内容了"); remoteViews.setOnClickPendingIntent(R.id.button, Pintent);//定义按钮点击后的动作 admain.view_notification(remoteViews, intent, smallIcon, ticker); break; case R.id.big_button_id: admain.big_notification(intent, smallIcon, ticker, "可以随内容变长的通知", "《天之界线》是Jack.Tony在2009年3月开始动笔的一本小说。" + "其内容包涵了悬疑,穿越,魔法,冒险等元素。 Jack.Tony于2009年秋季完成了" + "《天之界线》的序章——沉睡的容器。"); break; case R.id.progress_button_id: admain.progress_notification(intent, smallIcon, ticker, "有进度条的通知信息","正在下载中……"); break; case R.id.pic_button_id: admain.pic_notification(intent, smallIcon, ticker, "有大图片的通知信息", LargeIcon); break; case R.id.btn_button_id: admain.btn_notification(intent,smallIcon, ticker, "有按钮的通知", "下面的按钮可点击"); break; case R.id.clear_button_id: admain.clear(); break; default: break; } }}
好,现在重头戏来了。
NotificationAdmain.java
package com.kale.notification;import android.app.Activity;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.SystemClock;import android.support.v4.app.NotificationCompat;import android.widget.RemoteViews;public class NotificationAdmain { private static int NOTIFICATION_ID; private NotificationManager nm; private Notification notification; private NotificationCompat.Builder cBuilder; private Notification.Builder nBuilder; private Context mContext; int requestCode = (int) SystemClock.uptimeMillis(); private static final int FLAG = Notification.FLAG_INSISTENT; public NotificationAdmain(Context context, int ID) { this.NOTIFICATION_ID = ID; mContext = context; // 获取系统服务来初始化对象 nm = (NotificationManager) mContext .getSystemService(Activity.NOTIFICATION_SERVICE); cBuilder = new NotificationCompat.Builder(mContext); } /** * 设置在顶部通知栏中的各种信息 * * @param intent * @param smallIcon * @param ticker */ private void setCompatBuilder(Intent intent, int smallIcon, String ticker, String title, String msg) { // 如果当前Activity启动在前台,则不开启新的Activity。 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); // 当设置下面PendingIntent.FLAG_UPDATE_CURRENT这个参数的时候,常常使得点击通知栏没效果,你需要给notification设置一个独一无二的requestCode // 将Intent封装进PendingIntent中,点击通知的消息后,就会启动对应的程序 PendingIntent pIntent = PendingIntent.getActivity(mContext, requestCode, intent, FLAG); cBuilder.setContentIntent(pIntent);// 该通知要启动的Intent cBuilder.setSmallIcon(smallIcon);// 设置顶部状态栏的小图标 cBuilder.setTicker(ticker);// 在顶部状态栏中的提示信息 cBuilder.setContentTitle(title);// 设置通知中心的标题 cBuilder.setContentText(msg);// 设置通知中心中的内容 cBuilder.setWhen(System.currentTimeMillis()); /* * 将AutoCancel设为true后,当你点击通知栏的notification后,它会自动被取消消失, * 不设置的话点击消息后也不清除,但可以滑动删除 */ cBuilder.setAutoCancel(true); // 将Ongoing设为true 那么notification将不能滑动删除 // notifyBuilder.setOngoing(true); /* * 从Android4.1开始,可以通过以下方法,设置notification的优先级, * 优先级越高的,通知排的越靠前,优先级低的,不会在手机最顶部的状态栏显示图标 */ cBuilder.setPriority(NotificationCompat.PRIORITY_MAX); /* * Notification.DEFAULT_ALL:铃声、闪光、震动均系统默认。 * Notification.DEFAULT_SOUND:系统默认铃声。 * Notification.DEFAULT_VIBRATE:系统默认震动。 * Notification.DEFAULT_LIGHTS:系统默认闪光。 * notifyBuilder.setDefaults(Notification.DEFAULT_ALL); */ cBuilder.setDefaults(Notification.DEFAULT_ALL); } /** * 设置builder的信息,在用大文本时会用到这个 * * @param intent * @param smallIcon * @param ticker */ private void setBuilder(Intent intent, int smallIcon, String ticker) { nBuilder = new Notification.Builder(mContext); // 如果当前Activity启动在前台,则不开启新的Activity。 intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pIntent = PendingIntent.getActivity(mContext, requestCode, intent, FLAG); nBuilder.setContentIntent(pIntent); nBuilder.setSmallIcon(smallIcon); nBuilder.setTicker(ticker); nBuilder.setWhen(System.currentTimeMillis()); nBuilder.setPriority(NotificationCompat.PRIORITY_MAX); nBuilder.setDefaults(Notification.DEFAULT_ALL); } /** * 普通的通知 * * @param intent * @param smallIcon * @param ticker * @param title * @param msg */ public void normal_notification(Intent intent, int smallIcon, String ticker, String title, String msg) { setCompatBuilder(intent, smallIcon, ticker, title, msg); sent(); } /** * 进行多项设置的通知(在小米上似乎不能设置大图标,系统默认大图标为应用图标) * * @param intent * @param smallIcon * @param ticker * @param LargeIcon * @param title * @param msg */ public void special_notification(Intent intent, int smallIcon, String ticker, int LargeIcon, String title, String msg) { setCompatBuilder(intent, smallIcon, ticker, title, msg); // 如果不设置LargeIcon,那么系统会默认将上面的SmallIcon作为主要图标,显示在通知选项的最左侧,右下角的小图标将不再显示 Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), LargeIcon); cBuilder.setLargeIcon(bitmap); // 将Ongoing设为true 那么notification将不能滑动删除 cBuilder.setOngoing(true); // 删除时 Intent deleteIntent = new Intent(mContext, DeleteService.class); int deleteCode = (int) SystemClock.uptimeMillis(); // 删除时开启一个服务 PendingIntent deletePendingIntent = PendingIntent.getService(mContext, deleteCode, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT); cBuilder.setDeleteIntent(deletePendingIntent); cBuilder.setDefaults(Notification.DEFAULT_SOUND | // 设置使用默认的声音 Notification.DEFAULT_LIGHTS);// 设置使用默认的LED cBuilder.setVibrate(new long[] { 0, 100, 200, 300 });// 设置自定义的振动 cBuilder.setAutoCancel(true); // builder.setSound(Uri.parse("file:///sdcard/click.mp3")); // 设置通知样式为收件箱样式,在通知中心中两指往外拉动,就能出线更多内容,但是很少见 cBuilder.setNumber(3); cBuilder.setStyle(new NotificationCompat.InboxStyle() .addLine("M.Lynn 你好,我是kale").addLine("M.Lynn 已收到,保证完成任务") .addLine("M.Lynn 哈哈,明白了~").setSummaryText("+3 more")); // 设置在细节区域底端添加一行文本 sent(); } /** * 自定义视图的通知 * * @param remoteViews * @param intent * @param smallIcon * @param ticker */ public void view_notification(RemoteViews remoteViews, Intent intent, int smallIcon, String ticker) { setCompatBuilder(intent, smallIcon, ticker, null, null); notification = cBuilder.build(); notification.contentView = remoteViews; // 发送该通知 nm.notify(NOTIFICATION_ID, notification); } /** * 可以容纳多行提示文本的通知信息 (因为在高版本的系统中才支持,所以要进行判断) * * @param intent * @param smallIcon * @param ticker * @param title * @param msg */ public void big_notification(Intent intent, int smallIcon, String ticker, String title, String msg) { final int sdk = android.os.Build.VERSION.SDK_INT; if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { normal_notification(intent, smallIcon, ticker, title, msg); } else { setBuilder(intent, smallIcon, ticker); nBuilder.setContentTitle(title); nBuilder.setPriority(Notification.PRIORITY_HIGH); notification = new Notification.BigTextStyle(nBuilder).bigText(msg) .build(); // 发送该通知 nm.notify(NOTIFICATION_ID, notification); } } /** * 有进度条的通知,可以设置为模糊进度或者精确进度 * * @param intent * @param smallIcon * @param ticker * @param title * @param msg */ public void progress_notification(Intent intent, int smallIcon, String ticker, String title, String msg) { setCompatBuilder(intent, smallIcon, ticker, title, msg); /* * 因为进度条要实时更新通知栏也就说要不断的发送新的提示,所以这里不建议开启通知声音。 * 这里是作为范例,给大家讲解下原理。所以发送通知后会听到多次的通知声音。 */ new Thread(new Runnable() { @Override public void run() { int incr; for (incr = 0; incr <= 100; incr += 10) { // 参数:1.最大进度, 2.当前进度, 3.是否有准确的进度显示 cBuilder.setProgress(100, incr, false); // cBuilder.setProgress(0, 0, true); sent(); try { Thread.sleep(1 * 500); } catch (InterruptedException e) { e.printStackTrace(); } } // 进度满了后,设置提示信息 cBuilder.setContentText("下载完成~").setProgress(0, 0, false); sent(); } }).start(); } /** * 容纳大图片的通知 * * @param intent * @param smallIcon * @param ticker * @param title * @param bigPic */ public void pic_notification(Intent intent, int smallIcon, String ticker, String title, int bigPic) { setCompatBuilder(intent, smallIcon, ticker, title, null); NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle(); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), bigPic); picStyle.bigPicture(bitmap); cBuilder.setStyle(picStyle); sent(); } /** * 里面有两个按钮的通知 * * @param intent * @param smallIcon * @param ticker * @param title * @param msg */ public void btn_notification(Intent intent, int smallIcon, String ticker, String title, String msg) { Intent notifyIntent = new Intent(mContext, OtherActivity.class); int requestCode = (int) SystemClock.uptimeMillis(); PendingIntent pendIntent = PendingIntent.getActivity(mContext, requestCode, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); setCompatBuilder(intent, smallIcon, ticker, title, msg); cBuilder.addAction(android.R.drawable.ic_media_previous, mContext.getString(R.string.previous), pendIntent); cBuilder.addAction(android.R.drawable.ic_media_next, mContext.getString(R.string.next), pendIntent); sent(); } /** * 发送通知 */ private void sent() { notification = cBuilder.build(); // 发送该通知 nm.notify(NOTIFICATION_ID, notification); } /** * 根据id清除通知 */ public void clear() { // 取消通知 nm.cancelAll(); }}
点击通知,或者是删除通知的时候都可以用intent触发一个service或者是activity,这里是删除时候触发的service
DeleteService
package com.kale.notification;import android.app.IntentService;import android.content.Intent;import android.util.Log;public class DeleteService extends IntentService{ public DeleteService() { super(""); // TODO Auto-generated constructor stub } @Override protected void onHandleIntent(Intent intent) { Log.i("LOG", "===========deleteService"); }}
最后,记得注册activity和service,把需要的权限也写上
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kale.notification" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <!-- 闪光灯的权限 --> <uses-permission android:name="android.permission.FLASHLIGHT"/> <!-- 振动的权限 --> <uses-permission android:name="android.permission.VIBRATE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.kale.notification.OtherActivity"/> <service android:name="com.example.notificationtest.DeleteService" /> </application></manifest>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。