Notification下拉通知

昨天弄手机,突然看到通知栏。看这东西这么简单的效果,心想应该能搞定,然后就拍起来了。

本以为这个下拉通知左边的图片是就有这方法,谁知道还得自己自定义的,累人了。

如有问题请指正。


看了看API  找到一套源码,然后就按着顺序写起来了。实在不记得哪位前辈的成果了,就不打签了,如侵权联系本人。


看一下目录:

第一个ActionNameActivity类没什么意义就是点击弹出的通知进入这个Activity.

不算太麻烦。

1.先看BaseNoticeActivity类MainActivity是继承这个类的

类主要是进行注册系统服务和删除通知栏和兼容适配的。
package com.example.hejingzhou.notifications;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

/**
 * Created by Hejingzhou on 2016/3/13.
 */
public class BaseNoticeActivity extends AppCompatActivity{
    public NotificationManager notificationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InitService();
    }

    private void InitService() {
        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    }

    /**
     * 清除这个编号的通知栏
     * @param noticeNumber
     */
    public void clearThisNotice(int noticeNumber){
        notificationManager.cancel(noticeNumber);
    }

    /**
     * 清除所有的通知
     */
    public void clearAllNotice(){
        notificationManager.cancelAll();
    }

    /**
     * @获取默认的pendingIntent,为了防止2.3及以下版本报错  没有理解为什么这样做   就能防止报错
     * @flags属性:
     * 在顶部常驻:Notification.FLAG_ONGOING_EVENT
     * 点击去除: Notification.FLAG_AUTO_CANCEL
     */
    public PendingIntent getDefalutIntent(int flag){
        PendingIntent pendingIntent = PendingIntent.getActivities(this,1, new Intent[]{new Intent()},flag);
        return pendingIntent;
    }
}

<span style="color:#ff0000;">
</span>

2.BaseTools 两个方法获取APP的版本和SDK的版本

这两个方法在Android开发中挺重要的。

我们在这个程序中要的是SDK版本,而软件的版本号没什么用 ,SDK版本小于等于9可能造成错误,需要避免这个问题。

package com.example.hejingzhou.notifications;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;

/**
 * Created by Hejingzhou on 2016/3/15.
 */
public class BaseTools {
    /**
     * 获得App版本
     * @param context
     * @return
     * @throws Exception
     */
    public static String getAppVersion(Context context) throws Exception{
        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(),0);
        String versionName = packageInfo.versionName;
        return versionName;
    }

    /**
     * 获取当前系统SDK版本号
     * @return
     */
    public static int getSystemVersion(){
        int version = Build.VERSION.SDK_INT;
        return version;
    }
}


3.MainActivity

package com.example.hejingzhou.notifications;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.Toast;

import java.io.File;

/**
 * 首先明白 Intent 与 PendingIntent的大概区别:
 * intent英文意思是意图,pending表示即将发生或来临的事情。
 * PendingIntent这个类用于处理即将发生的事情。
 */
public class MainActivity extends BaseNoticeActivity implements View.OnClickListener {

    private String TAG = getClass().getSimpleName();
    NotificationCompat.Builder mNotiBuilder;//通知构造器类

    private int noticeID01 = 01;
    private int noticeID02 = 02;
    private int noticeID03 = 03;
    private int noticeID04 = 04;
    private int noticeID05 = 05;
    private int noticeID06 = 06;

    public boolean isPaly = false;
    public ButtonBroadcastReceiver broadcastReceiver; //通知栏上的Button按下后会发出intent消息  这是接收消息的类继承接收类
    public final static String ACTION_BUTTON = "ButtonActionFlag";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById();
        initNotice();
        initButtonReceiver();
        /**
         * 获取的当前的APP版本好并没有什么用,只是在软件升级的时候用的到
         * 这里的获取SDK的版本号 是因为自定义的通知须在SDK3.0的版本上支持,低于3.0不响应
         */
        BaseTools baseTools = new BaseTools();
        try {
            String appversion = baseTools.getAppVersion(getApplicationContext());
            Log.i(TAG,"当前的App版本号"+appversion);
            int SystemVersion = baseTools.getSystemVersion();
            Log.i(TAG,"当前的SDK版本号是"+SystemVersion);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initButtonReceiver() {
        broadcastReceiver = new ButtonBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();//意向结构化描述要匹配的值
        intentFilter.addAction(ACTION_BUTTON);
        registerReceiver(broadcastReceiver, intentFilter);//注册
    }

    /**
     * 初始化通知栏
     */
    private void initNotice() {
        mNotiBuilder = new NotificationCompat.Builder(this);

        mNotiBuilder.setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT));
        mNotiBuilder.setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT)).//防止2.3一下报错??
        setContentTitle("Test Title")
                .setContentText("Test Content")
                        /**setContentIntent提供一个当单击通知时,发送
                         *
                         *FLAG_AUTO_CANCEL  该通知能被状态栏的清除按钮给清除掉
                         *FLAG_NO_CLEAR  该通知能被状态栏的清除按钮给清除掉
                         *FLAG_ONGOING_EVENT  通知放置在正在运行
                         */
                .setTicker("通知来了")
                .setWhen(System.currentTimeMillis())//通知的时间一般为系统时间
                .setPriority(Notification.PRIORITY_DEFAULT)//设置优先显示级别 范围 【-2 , 2】
                .setOngoing(false)//设置这是否是一个持续的通知//如果设置为false 可以通过通知栏侧滑删除,true则不能
                .setDefaults(Notification.DEFAULT_VIBRATE)//设置通知默认要使用的选项
                .setNumber(100)//Show出一个数,也不知道使用它有啥用
                .setSmallIcon(R.drawable.feiji);//只是在setTicker弹出的提示的时候是这个图标
    }

    private void findViewById() {
        Button btnBasicNotice = (Button) findViewById(R.id.buttonBasicNotice);
        btnBasicNotice.setOnClickListener(this);
        Button btnBigNotice = (Button)findViewById(R.id.buttonBigNotice);
        btnBigNotice.setOnClickListener(this);
        Button btnPermanent = (Button)findViewById(R.id.buttonPermanent);
        btnPermanent.setOnClickListener(this);
        Button btnClearNotice = (Button)findViewById(R.id.buttonClearNotice);
        btnClearNotice.setOnClickListener(this);
        Button btnActionActivity = (Button)findViewById(R.id.buttonActionActivity);
        btnActionActivity.setOnClickListener(this);
        Button btnClearAllNotice = (Button)findViewById(R.id.buttonClearAllNotice);
        btnClearAllNotice.setOnClickListener(this);
        Button btnInstallApp = (Button)findViewById(R.id.buttonInstallApp);
        btnInstallApp.setOnClickListener(this);
        Button btnUserDefine = (Button)findViewById(R.id.buttonUserDefine);
        btnUserDefine.setOnClickListener(this);
        Button btnUserDefineButton = (Button)findViewById(R.id.buttonUserDefineButton);
        btnUserDefineButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.buttonBasicNotice:
                Log.i(TAG,"Click The Basic Notice");
                showBasicNotice();
                break;
            case R.id.buttonBigNotice:
                showBigNotice();
                break;
            case R.id.buttonPermanent:
                showPermanent();
                break;
            case R.id.buttonClearNotice:
                clearThisNotice(noticeID03);
                break;
            case R.id.buttonActionActivity:
                ActionNewActivity();
                break;
            case R.id.buttonClearAllNotice:
                clearAllNotice();
                break;
            case R.id.buttonInstallApp:
                InstallApp();
                break;
            case R.id.buttonUserDefine://自定义
                UserDefineNotice();
                break;
            case R.id.buttonUserDefineButton://自定义带Button
                UserDefineButtonNotice();
                break;
            default:
                break;
        }
    }

    /**
     * 用户定义的通知
     */
    private void UserDefineNotice() {
        RemoteViews view_notice = new RemoteViews(getPackageName(),R.layout.view_notice);//自定义布局
        view_notice.setImageViewResource(R.id.custom_icon, R.drawable.jian);
        view_notice.setTextViewText(R.id.tv_custom_title, "今日特价");
        view_notice.setTextViewText(R.id.tv_custom_content,"白菜价 ----白菜价 ---  今日只卖白菜");
        mNotiBuilder = new NotificationCompat.Builder(this);
        mNotiBuilder.setContent(view_notice)
                .setPriority(Notification.PRIORITY_DEFAULT)
                .setTicker("今日特价")
                .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))//因为运行时已经初始化了,可以以没有
                .setWhen(System.currentTimeMillis())
                .setOngoing(false)
                .setSmallIcon(R.drawable.qian);
        Notification notification = mNotiBuilder.build();
        notification.contentView = view_notice;
        notificationManager.notify(noticeID05, notification);
    }

    /**
     * 安装APP
     */
    private void InstallApp() {
                mNotiBuilder.setAutoCancel(true)//点击后消失
                .setContentTitle("Download  Over")
                .setContentText("Click Install the App")
                .setTicker("Download Over");
        Intent apkIntent = new Intent();
        apkIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        apkIntent.setAction(android.content.Intent.ACTION_VIEW);
        String appPath = "./mnt/sdcard/ProMonkey_2.0.apk";
        Uri uri = Uri.fromFile(new File(appPath));
        Log.i(TAG,""+uri);
        apkIntent.setDataAndType(uri,"application/vnd.android.package-archive");
        //这个类型不懂动的上   http://zengyan2012.iteye.com/blog/1646492 进行理解 就是定义好的文件类型定值
        PendingIntent contextIntent = PendingIntent.getActivity(this,0,apkIntent,0);
        //getActivity参数类型     context, requestCode, intent, flags, null
        mNotiBuilder.setContentIntent(contextIntent);
        notificationManager.notify(noticeID06, mNotiBuilder.build());
        Toast.makeText(MainActivity.this,"运行了到这里了",Toast.LENGTH_SHORT).show();
    }

    /**
     * 跳转到新的Activity
     */
    private void ActionNewActivity() {
        mNotiBuilder.setAutoCancel(true)//点击后通条消失
        .setContentTitle("ActionNewActivity")
                .setContentText("This is a ActionNewActivity")
                .setTicker("ActionNewActivity Come on...")
                .setSmallIcon(R.drawable.action);
        Intent actionIntent = new Intent(this,ActionNewActivity.class);
        actionIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,actionIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        /**
         * PendingIntent.FLAG_UPDATE_CURRENT  一个标志符  标志操作是否完成
         */
        mNotiBuilder.setContentIntent(pendingIntent);
        notificationManager.notify(noticeID04,mNotiBuilder.build());
    }

    /**
     * 常驻栏
     */
    private void showPermanent() {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), 0);
        /**
         *public static PendingIntent getActivity(Context context, int requestCode,
          Intent intent, @Flags int flags) {
          return getActivity(context, requestCode, intent, flags, null);
          }
        */
        mBuilder.setSmallIcon(R.drawable.ren)
                .setTicker("Permanent Notice ...")
                .setContentTitle("常住栏,无法右划取消")
                .setContentText("This is a Permanent Notice")
                .setContentIntent(pendingIntent);//setContentIntent:提供一个供通知栏单击时响应PendingIntent
        Notification mNotification = mBuilder.build();
        mNotification.iconLevel = R.drawable.ren;//设置图标
        mNotification.flags = Notification.FLAG_ONGOING_EVENT;
        mNotification.defaults = Notification.DEFAULT_VIBRATE;
        mNotification.tickerText = "Notice  Come in...";
        mNotification.when = System.currentTimeMillis();
        notificationManager.notify(noticeID03,mNotification);
    }

    /**
     * 创建一个大的通知栏   没看出效果没什么不同
     */
    private void showBigNotice() {
        NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
        String[] events = new String[6];
        inboxStyle.setBigContentTitle("Big  Notice:");
        for(int i=0;i<events.length;i++){
            inboxStyle.addLine(events[i]);
        }
        mNotiBuilder.setContentTitle("Big Notice")
                .setContentText("This a Big Notice")
                .setSmallIcon(R.drawable.feiji)
                .setTicker("Big Notice Come in...");
        notificationManager.notify(noticeID02,mNotiBuilder.build());
    }

    /**
     * 创建一个基本的通知
     */
    private void showBasicNotice() {
        mNotiBuilder.setContentTitle("Basic");
        mNotiBuilder.setContentText("This is a Basic Notice!!!");
        mNotiBuilder.setTicker("Basic Notice Come in");//首次出现上升滚动
        //mNotiBuilder.setColor(red);
        mNotiBuilder.setSmallIcon(R.drawable.xiao);
        notificationManager.notify(noticeID01, mNotiBuilder.build());
    }

    public final static String INITENT_BUTTONID_TAG = "ButtonId";
    public final static int BUTTON_PREV_ID = 1;
    public final static int BUTTON_PLAY_ID = 2;
    public final static int BUTTON_NEXT_ID = 3;

    /**
     * 创建的负责接收Intent传过来的信息内部类
     */
    private class ButtonBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //public final static String ACTION_BUTTON = "com.notifications.intent.action.ButtonClick";
            if(action.equals(ACTION_BUTTON)){
            //public final static String INITENT_BUTTONID_TAG = "ButtonId";
                int buttonId = intent.getIntExtra(INITENT_BUTTONID_TAG,0);
                switch (buttonId){
                    case BUTTON_PREV_ID:
                        Log.i(TAG, "按下的上一首");
                        Toast.makeText(getApplicationContext(),"点击了上一首",Toast.LENGTH_SHORT);
                        break;
                    case BUTTON_PLAY_ID:
                        Log.i(TAG,"点击了播放");
                        String play_status = "";
                        isPaly = !isPaly;
                        if(isPaly){
                            play_status = "开始播放";
                        }else play_status = "已暂停";
                        UserDefineButtonNotice();
                        Log.i(TAG, play_status);
                        Toast.makeText(getApplicationContext(),play_status,Toast.LENGTH_SHORT).show();
                        break;
                    case BUTTON_NEXT_ID:
                        Log.i(TAG, "下一首");
                        Toast.makeText(getApplicationContext(),"下一首",Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /**
     * 用户自定义的带Button
     */
    private void UserDefineButtonNotice() {
        NotificationCompat.Builder mbBuilder = new NotificationCompat.Builder(this);//构建
        RemoteViews mRemoteViews = new RemoteViews(getPackageName(),R.layout.view_notice_button);
        mRemoteViews.setImageViewResource(R.id.custom_song_icon, R.drawable.yinyue);
        mRemoteViews.setTextViewText(R.id.tv_custom_song_singer,"田嘱");
        mRemoteViews.setTextViewText(R.id.tv_custom_song_name,"采蘑菇的小姑娘");
        if(BaseTools.getSystemVersion() <= 9){
            mRemoteViews.setViewVisibility(R.id.ll_custom_button, View.GONE);
        }else {
            mRemoteViews.setViewVisibility(R.id.ll_custom_button, View.VISIBLE);
            if (isPaly) {
                mRemoteViews.setImageViewResource(R.id.btn_custom_play, R.drawable.btn_pause);
            } else mRemoteViews.setImageViewResource(R.id.btn_custom_play, R.drawable.btn_play);
        }
        //点击事件处理
        Intent buttonIntent = new Intent(ACTION_BUTTON);
        /**
         *  public final static String INITENT_BUTTONID_TAG = "ButtonId";
         *  public final static int BUTTON_PREV_ID = 1;
         * */
        //上一首 发送消息
        buttonIntent.putExtra(INITENT_BUTTONID_TAG,BUTTON_PREV_ID);//传递消息
        PendingIntent intent_prev = PendingIntent.getBroadcast(this,1,buttonIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_prev, intent_prev);
        /**getBroadcast(Context context, int requestCode,Intent intent, @Flags int flags)
         * getBroadcast返回现有连接或新处理意图匹配给定参数
         *
         * setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) {
         * addAction(new SetOnClickPendingIntent(viewId, pendingIntent));
         * 指定键位,与发送内容
         */
        //播放暂停 发送消息
        buttonIntent.putExtra(INITENT_BUTTONID_TAG,BUTTON_PLAY_ID);
        PendingIntent intent_play = PendingIntent.getBroadcast(this,2,buttonIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_play, intent_play);
        //下一首消息
        buttonIntent.putExtra(INITENT_BUTTONID_TAG, BUTTON_NEXT_ID);
        PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mRemoteViews.setOnClickPendingIntent(R.id.btn_custom_next, intent_next);
        mbBuilder.setContent(mRemoteViews)
                .setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT))防止2.3一下报错???!
                .setTicker("playing ...")
                .setPriority(Notification.PRIORITY_DEFAULT)
                .setOngoing(true)
                .setSmallIcon(R.drawable.yinyue);
        Notification notification = mbBuilder.build();//Notification代表着一个持久提交通知
        notification.flags = Notification.FLAG_ONGOING_EVENT;
        notificationManager.notify(200,notification);
        /**
         * void notify(int id, Notification notification)
         * 发布一个通知在状态栏显示。如果一个通知,已经发布的应用程序相同的id和尚未被取消,它将取而代之的是更新的信息。
         * @param id An identifier for this notification unique within your
         *        application.
         * @param notification A {@link Notification} object describing what to show the user. Must not
         *        be null.
         */
    }

    @Override
    protected void onDestroy() {
        if(broadcastReceiver != null){
            unregisterReceiver(broadcastReceiver);
        }
        super.onDestroy();
    }
}
Ps:在启动应用程序的时候我的SD卡存放的程序。路径为我的SD卡。所以APK文件路径还是需要符合您的路径。
访问SD卡是需要添加SD卡的权限,这个不要忘了。
关于这个具体路径按照 Android Device  Monitor 里进行寻找,如果是在Sd卡中的话,就是在mnt/sdcard/里面。
比如我的文件是在内存卡的根目录,那么我的路劲格式为     ./mnt/sdcard/ProMonkey_2.0.apk  千万不能忘记前面的点
打印Uri解析完的日志为


还有一些布局文件,不贴了参考源码吧。
盗个图 ,类方法挺详细的:来自http://yiibai.com/android/android_notifications.html
运行结果:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值