码迷,mamicode.com
首页 > 其他好文 > 详细

各种Notification详解,含工具类

时间:2014-07-23 15:17:07      阅读:369      评论:0      收藏:0      [点我收藏+]

标签:android   des   style   blog   http   java   

bubuko.com,布布扣                                                          bubuko.com,布布扣 

  bubuko.com,布布扣 bubuko.com,布布扣 bubuko.com,布布扣

bubuko.com,布布扣 bubuko.com,布布扣 bubuko.com,布布扣

 

 

昨天一天只写了两篇文章,效率超低。追其原因呢,其实我一直在研究notification的实现方式,今天研究完了给大家分享一下。本来想写个工具类来封装一下代码的,但是我发现notification的个性化元素太多了,做成一个方法的话参数又多的要死,于是我就将比较常见的方法做了封装,写了个不是很规整的工具类,至于内部的逻辑啊,点击跳转的事件啊,大家下载demo后看看代码应该就能明白了,最重要的是根据自己的需要选择好的方法。还有一点需要建议的是,如果你发的通知都是用同一个ID的话可能会出现通知叠加的情况,这点需要注意一下。还是那句话根据实际需要吧,如果我的通知类型都是一样的,用同一个ID叠加就让他叠加吧。好啦,下面我们来看代码。

 

首先还是布局文件,这里用的全是button,在布局界面直接绑定了监听器。

bubuko.com,布布扣

<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

bubuko.com,布布扣

<?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

bubuko.com,布布扣

<?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>

各种Notification详解,含工具类,布布扣,bubuko.com

各种Notification详解,含工具类

标签:android   des   style   blog   http   java   

原文地址:http://www.cnblogs.com/tianzhijiexian/p/3862910.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!