精华内容
下载资源
问答
  • 公司产品课程音频播放播放的需求,其中有一个通知栏呈现市场上网易云和QQ类似功能,可以显示对应内容和音乐播放状态切换,并且其中有一个防假学功能,对应在某个点对应提示有试题作答,并隐藏通知栏视图。...

    需求

    公司产品课程音频播放播放的需求,其中有一个通知栏呈现市场上网易云和QQ类似功能,可以显示对应内容和音乐播放状态切换,并且其中有一个防假学功能,对应在某个点对应提示有试题作答,并隐藏通知栏视图。

    解决思路

    1.音乐播放器状态和通知栏状态一致
    播放器状态变更就是发送通知,进行状态进行刷新;状态栏控制控制播放器,可以通过广播通知播放器去控制音乐播放器状态;
    2.隐藏通知栏
    发送一个通知,进行通知栏隐藏

    代码实现

    音乐播放器状态变更发送通知,并对应通知栏的状态点击监听,关联对应的广播进行触发。

    public void showNotify(PlayerStates states) {
            if (mContext == null) {
                return;
            }
            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext);
            RemoteViews bigView = null;
            RemoteViews smallview = null;
            smallview = new RemoteViews(getPackageName(), R.layout.audio_notification);
            bigView = new RemoteViews(getPackageName(), R.layout.audio_notification_big);
            if (states == PlayerStates.PLAY) {
                smallview.setImageViewResource(R.id.play_btn, R.drawable.icon_play);
                bigView.setImageViewResource(R.id.play_btn, R.drawable.icon_play);
            } else {
                smallview.setImageViewResource(R.id.play_btn, R.drawable.icon_stop);
                bigView.setImageViewResource(R.id.play_btn, R.drawable.icon_stop);
            }
            SharedPreferencesUtil sharedPreferencesUtil = new SharedPreferencesUtil(getContext(), "notification");
            String courseName = sharedPreferencesUtil.getString("courseName", "");
            String teacher = sharedPreferencesUtil.getString("teacher", "");
            smallview.setTextViewText(R.id.title_one_name, courseName);
            bigView.setTextViewText(R.id.title_one_name, courseName);
            if (!teacher.equals("")) {
                smallview.setViewVisibility(R.id.title_two_name, VISIBLE);
                smallview.setTextViewText(R.id.title_two_name, "讲师:" + teacher);
                bigView.setTextViewText(R.id.title_two_name, "讲师:" + teacher);
            } else {
                smallview.setViewVisibility(R.id.title_two_name, GONE);
            }
            PendingIntent homeIntent = PendingIntent.getBroadcast(this.getContext(), 1, new Intent(NotificationBroadcast.ACTION), PendingIntent.FLAG_UPDATE_CURRENT);//动态广播注册
            bigView.setOnClickPendingIntent(R.id.play_btn, homeIntent);//设置通知栏监听,关联广播
            smallview.setOnClickPendingIntent(R.id.play_btn, homeIntent);
            mBuilder.setContent(smallview)//通知栏默认视图
                    .setContentIntent(getDefalutIntent(Notification.FLAG_ONGOING_EVENT))
                    .setWhen(System.currentTimeMillis())
                    .setTicker("")
                    .setOngoing(true)
                    .setCustomBigContentView(bigView)//通知栏大视图
                    .setSmallIcon(R.drawable.audio_background);
            Notification notify = mBuilder.build();
            notify.flags = Notification.FLAG_ONGOING_EVENT;
            NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(200, notify);
        }
    

    对应的广播接收者

    public class NotificationBroadcast extends BroadcastReceiver {
        public static final String ACTION = "com.hb.vplayer.audio.NotificationBroadcast";
        private NotificationInterface mLs;
        public void setListener(NotificationInterface ls){
            this.mLs=ls;
        }
    
        @Override
        public void onReceive(Context context, Intent intent) {
            mLs.onPlayerClick();
        }
        interface NotificationInterface{
            public void onPlayerClick();
        }
    }
    

    对应在某个点对应提示有试题作答,并隐藏通知栏视图,主要通过发送通知,通知系统隐藏对应通知栏

    public void hideNotifaction(String tag) {
            if (mContext == null) {
                return;
            }
            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext);
            RemoteViews bigView = null;
            RemoteViews smallview = null;
            smallview = new RemoteViews(getPackageName(), com.hb.vplayer.R.layout.audio_notification);
            bigView = new RemoteViews(getPackageName(), com.hb.vplayer.R.layout.audio_notification_big);
    
            PendingIntent homeIntent = PendingIntent.getBroadcast(mContext, 1, new Intent(NotificationBroadcast.ACTION), PendingIntent.FLAG_UPDATE_CURRENT);
            bigView.setOnClickPendingIntent(com.hb.vplayer.R.id.play_btn, homeIntent);
            smallview.setOnClickPendingIntent(com.hb.vplayer.R.id.play_btn, homeIntent);
            mBuilder.setContent(smallview)
                    .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))
                    .setWhen(System.currentTimeMillis())
                    .setTicker("")
                    .setOngoing(true)
                    .setCustomBigContentView(bigView)
                    .setSmallIcon(R.drawable.audio_background);
            ;
            Notification notify = mBuilder.build();
            notify.flags = Notification.FLAG_AUTO_CANCEL;//隐藏通知栏的flags的标记
            NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(200, notify);
        }
    

    遇到问题:

    如果android的gradle的编译版本是26以及以上的,就要引入对应渠道,不然通知栏显示不出来。

     public void createNotificationChannel(){
            if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
                NotificationManager mNotificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                String id="default";
                CharSequence name="默认";
                String description="接收一通知";
                int importance= NotificationManager.IMPORTANCE_HIGH;
                NotificationChannel mChannel=new NotificationChannel(id,name,importance);
                mChannel.setDescription(description);
                mChannel.enableLights(false);
                mChannel.enableVibration(false);
                mChannel.setVibrationPattern(new long[]{0});
                mChannel.setSound(null,null);
                mChannel.setLightColor(Color.RED);
                mNotificationManager.createNotificationChannel(mChannel);
            }
        }
    

    对应在创建Notifcation要加入渠道进去

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext, "default");   // gradle 的targetSdkVersion>=26  需要添加渠道
    
    展开全文
  • Android 8.0以上通知栏不显示

    千次阅读 2019-01-26 18:51:44
    Android 8.0以上通知栏不显示 通知栏使用重要的API NotificationManager Notification NotificationChannel 最近在android 8.0的手机上发现通知栏不显示通知了! No Channel found for pkg=camera.test.com.perssion...

    Android 8.0以上通知栏不显示

    通知栏使用重要的API
    NotificationManager
    Notification
    NotificationChannel
    最近在android 8.0的手机上发现通知栏不显示通知了!
    No Channel found for pkg=camera.test.com.perssion, channelId=null, id=1, tag=null, opPkg=camera.test.com.perssion, 
    callingUid=10367, userId=0, incomingUserId=0, notificationUid=10367, notification=Notification(channel=null pri=0 
    contentView=null vibrate=null sound=null defaults=0x0 flags=0x0 color=0x00000000 vis=PRIVATE)
    
    android 8.0之后添加了 推送通道,在8.0以上没有设置通道的话就会包上边的错误。可根据8.0以上设置chanle解决问题
       Notification notification;
            Notification.Builder builder;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                 builder=new Notification.Builder(this,CHANNEL_ID);
            }else {
                 builder=new Notification.Builder(this);
            }
            //设置标题
            builder.setContentTitle("设置标题");
            //设置内容
            builder.setContentText("内容是............");
            //设置状态栏显示的图标,建议图标颜色透明
            builder.setSmallIcon(R.mipmap.ic_launcher);
            // 设置通知灯光(LIGHTS)、铃声(SOUND)、震动(VIBRATE)、(ALL 表示都设置)
            builder.setDefaults(Notification.DEFAULT_ALL);
            //灯光三个参数,颜色(argb)、亮时间(毫秒)、暗时间(毫秒),灯光与设备有关
            builder.setLights(Color.RED, 200, 200);
            // 铃声,传入铃声的 Uri(可以本地或网上)我这没有铃声就不传了
            builder.setSound(Uri.parse("")) ;
            // 震动,传入一个 long 型数组,表示 停、震、停、震 ... (毫秒)
            builder.setVibrate(new long[]{0, 200, 200, 200, 200, 200});
            // 通知栏点击后自动消失
            builder.setAutoCancel(true);
            // 简单通知栏设置 Intent
            builder.setContentIntent(setPendingIntent("简单通知"));
            builder.setPriority(Notification.PRIORITY_HIGH);
    
            //设置下拉之后显示的图片
            builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
                channel.enableLights(true);//是否在桌面icon右上角展示小红点
                channel.setLightColor(Color.GREEN);//小红点颜色
                channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
                notificationManager.createNotificationChannel(channel);
            }
            notification=builder.build();
            notificationManager.notify(1,notification);
    
    展开全文
  • //设置状态栏显示的图标,建议图标颜色透明 builder.setSmallIcon(R.mipmap.ic_launcher); // 设置通知灯光(LIGHTS)、铃声(SOUND)、震动(VIBRATE)、(ALL 表示都设置) builder.setDefaults(Notification....

     Android8.0以上得加channelId

    Intent intent = new Intent(SplashActivity.this,ChatActivity.class);
                    PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
                    Notification notification;
                    Notification.Builder builder;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        builder=new Notification.Builder(this,"5996773");
                    }else {
                        builder=new Notification.Builder(this);
                    }
                    //设置标题
                    builder.setContentTitle("设置标题");
                    //设置内容
                    builder.setContentText("内容是............");
                    //设置状态栏显示的图标,建议图标颜色透明
                    builder.setSmallIcon(R.mipmap.ic_launcher);
                    // 设置通知灯光(LIGHTS)、铃声(SOUND)、震动(VIBRATE)、(ALL 表示都设置)
                    builder.setDefaults(Notification.DEFAULT_ALL);
                    //灯光三个参数,颜色(argb)、亮时间(毫秒)、暗时间(毫秒),灯光与设备有关
                    builder.setLights(Color.RED, 200, 200);
                    // 铃声,传入铃声的 Uri(可以本地或网上)我这没有铃声就不传了
                    builder.setSound(Uri.parse("")) ;
                    // 震动,传入一个 long 型数组,表示 停、震、停、震 ... (毫秒)
                    builder.setVibrate(new long[]{0, 200, 200, 200, 200, 200});
                    // 通知栏点击后自动消失
                    builder.setAutoCancel(true);
                    // 简单通知栏设置 Intent
                    builder.setContentIntent(pendingIntent);
                    builder.setPriority(Notification.PRIORITY_HIGH);
    
                    //设置下拉之后显示的图片
                    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        NotificationChannel channel = new NotificationChannel("5996773", "安卓10a", NotificationManager.IMPORTANCE_DEFAULT);
                        channel.enableLights(true);//是否在桌面icon右上角展示小红点
                        channel.setLightColor(Color.GREEN);//小红点颜色
                        channel.setShowBadge(false); //是否在久按桌面图标时显示此渠道的通知
                        mNManager.createNotificationChannel(channel);
                    }
                    notification=builder.build();
                    mNManager.notify(1,notification);

     

    展开全文
  • 这个时候我触摸下通知栏,就可以显示了。很是费解啊,看我的代码里面却没有log。很奇怪 我把图片也添加上来。有想法的可以交流下。![![图片说明](https://img-ask.csdn.net/upload/201511/05/1446719295_825424.png)...
  • Android通知栏微技巧,8.0系统中通知栏的适配

    万次阅读 多人点赞 2018-04-17 07:39:11
    大家好,今天我们继续来学习Android 8.0系统的适配。...在上一篇文章当中,我们学习了Android 8.0系统应用图标的适配,那么本篇文章,我们自然要将重点放在通知栏上面了,学习一下Android 8.0系统的通知栏适配

    转载请注明出处:https://blog.csdn.net/guolin_blog/article/details/79854070

    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。

    大家好,今天我们继续来学习Android 8.0系统的适配。

    之前我们已经讲到了,Android 8.0系统最主要需要进行适配的地方有两处:应用图标和通知栏。在上一篇文章当中,我们学习了Android 8.0系统应用图标的适配,还没有看过这篇文章的朋友可以先去阅读 Android应用图标微技巧,8.0系统中应用图标的适配

    那么本篇文章,我们自然要将重点放在通知栏上面了,学习一下Android 8.0系统的通知栏适配。

    其实在8.0系统之前,还有一次通知栏变动比较大的版本,就是5.0系统。关于5.0系统需要对通知栏进行适配的内容,我也整理了一篇文章,感兴趣的朋友可以去阅读 Android通知栏微技巧,那些你所没关注过的小细节

    那么下面我们就开始进入本篇文章的正题。


    为什么要进行通知栏适配?

    不得不说,通知栏真是一个让人又爱又恨的东西。

    通知栏是Android系统原创的一个功能,虽说乔布斯一直认为Android系统是彻彻底底抄袭iOS的一个产品,但是通知栏确实是Android系统原创的,反而苹果在iOS 5之后也加入了类似的通知栏功能。

    通知栏的设计确实非常巧妙,它默认情况下不占用任何空间,只有当用户需要的时候用手指在状态栏上向下滑动,通知栏的内容才会显示出来,这在智能手机发展的初期极大地解决了手机屏幕过小,内容展示区域不足的问题。

    可是随着智能手机发展的逐渐成熟,通知栏却变得越来越不讨人喜欢了。各个App都希望能抢占通知栏的空间,来尽可能地宣传和推广自己的产品。现在经常是早上一觉醒来拿起手机一看,通知栏上全是各种APP的推送,不胜其烦。

    我个人虽然是Android应用开发者,但同时也是Android手机的资深用户。我已经使用了8年的Android手机,目前我对于通知栏的这种垃圾推送是零容忍的。现在每当我安装一个新的App时,我都会先到设置里面去找一找有没有推送开关,如果有的话我会第一时间把它关掉。而如果一个App经常给我推送垃圾信息却又无法关闭时,我会直接将它的通知总开关给关掉,如果还不是什么重要的App的话,那么我可能就直接将它卸载掉了。

    为什么一个很好的通知栏功能现在却变得这么遭用户讨厌?很大一部分原因都是因为开发者没有节制地使用导致的。就好像App保活一样,直到今天还是不断有人问我该如何保活App,试想如何每个人都能保活自己的App,那么最终受害的人是谁?还不是使用Android手机的用户。大家的手机只会越来越卡,最后只想把手机丢掉,变成iPhone用户了。也是因为开发者没节制地使用,Android现在的每个版本都会不断收缩后台权限。

    回到通知栏上也是一样,每个开发者都只想着尽可能地去宣传自己的App,最后用户的手机就乱得跟鸡窝一样了。但是通知栏又还是有用处的,比如我们收到微信、短信等消息的时候,确实需要通知栏给我们提醒。因此分析下来,通知栏目前最大的问题就是,无法让用户对感兴趣和不感兴趣的消息进行区分。就比如说,我希望淘宝向我推送卖家发货和物流的相关消息,但是我不想收到那些打折促销或者是让我去买衣服的这类消息。那么就目前来说,是没有办法对这些消息做区分的,我要么同意接受所有消息,要么就屏蔽所有消息,这是当前通知栏的痛点。

    那么在Android 8.0系统中,Google也是从这个痛点开始下手的。

    8.0系统的通知栏适配

    从Android 8.0系统开始,Google引入了通知渠道这个概念。

    什么是通知渠道呢?顾名思义,就是每条通知都要属于一个对应的渠道。每个App都可以自由地创建当前App拥有哪些通知渠道,但是这些通知渠道的控制权都是掌握在用户手上的。用户可以自由地选择这些通知渠道的重要程度,是否响铃、是否振动、或者是否要关闭这个渠道的通知。

    拥有了这些控制权之后,用户就再也不用害怕那些垃圾推送消息的打扰了,因为用户可以自主地选择自己关心哪些通知、不关心哪些通知。举个具体的例子,我希望可以即时收到支付宝的收款信息,因为我不想错过任何一笔收益,但是我又不想收到支付宝给我推荐的周围美食,因为我没钱只吃得起公司食堂。这种情况,支付宝就可以创建两种通知渠道,一个收支,一个推荐,而我作为用户对推荐类的通知不感兴趣,那么我就可以直接将推荐通知渠道关闭,这样既不影响我关心的通知,又不会让那些我不关心的通知来打扰我了。

    对于每个App来说,通知渠道的划分是非常需要仔细考究的,因为通知渠道一旦创建之后就不能再修改了,因此开发者需要仔细分析自己的App一共有哪些类型的通知,然后再去创建相应的通知渠道。这里我们来参考一下Twitter的通知渠道划分:

    可以看到,Twitter就是根据自己的通知类型,对通知渠道进行了非常详细的划分,这样用户的自主选择性就比较高了,也就大大降低了用户不堪其垃圾通知的骚扰而将App卸载的概率。


    我一定要适配吗?

    Google这次对于8.0系统通知渠道的推广态度还是比较强硬的。

    首先,如果你升级了appcompat库,那么所有使用appcompat库来构建通知的地方全部都会进行废弃方法提示,如下所示:

    上图告诉我们,此方法已废弃,需要使用带有通知渠道的方法才行。

    当然,Google也并没有完全做绝,即使方法标为了废弃,但还是可以正常使用的。可是如果你将项目中的targetSdkVersion指定到了26或者更高,那么Android系统就会认为你的App已经做好了8.0系统的适配工作,当然包括了通知栏的适配。这个时候如果还不使用通知渠道的话,那么你的App的通知将完全无法弹出。因此这里给大家的建议就是,一定要适配。

    好了,前面向大家介绍了这么多的背景知识,那么现在开始我们就正式进入正题,来学习一下如何进行8.0系统中通知栏的适配。

    创建通知渠道

    首先我们使用Android Studio来新建一个项目,就叫它NotificationTest吧。

    创建好项目之后,打开app/build.gradle文件检查一下,确保targetSdkVersion已经指定到了26或者更高,如下所示:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 26
        defaultConfig {
            applicationId "com.example.notificationtest"
            minSdkVersion 15
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
    }

    可以看到,这里我在创建新项目的时候默认targetSdkVersion就是26,如果你是低于26的话,说明你的Android SDK有些老了,最好还是更新一下。当然如果你懒得更新也没关系,手动把它改成26就可以了。

    接下来修改MainActivity中的代码,如下所示:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                String channelId = "chat";
                String channelName = "聊天消息";
                int importance = NotificationManager.IMPORTANCE_HIGH;
                createNotificationChannel(channelId, channelName, importance);
    
                channelId = "subscribe";
                channelName = "订阅消息";
                importance = NotificationManager.IMPORTANCE_DEFAULT;
                createNotificationChannel(channelId, channelName, importance);
            }
        }
    
    
        @TargetApi(Build.VERSION_CODES.O)
        private void createNotificationChannel(String channelId, String channelName, int importance) {
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager notificationManager = (NotificationManager) getSystemService(
                    NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
    }

    代码不长,我来简单解释下。这里我们在MainActivity中创建了两个通知渠道,首先要确保的是当前手机的系统版本必须是Android 8.0系统或者更高,因为低版本的手机系统并没有通知渠道这个功能,不做系统版本检查的话会在低版本手机上造成崩溃。

    创建一个通知渠道的方式非常简单,这里我封装了一个createNotificationChannel()方法,里面的逻辑相信大家都看得懂。需要注意的是,创建一个通知渠道至少需要渠道ID、渠道名称以及重要等级这三个参数,其中渠道ID可以随便定义,只要保证全局唯一性就可以。渠道名称是给用户看的,需要能够表达清楚这个渠道的用途。重要等级的不同则会决定通知的不同行为,当然这里只是初始状态下的重要等级,用户可以随时手动更改某个渠道的重要等级,App是无法干预的。

    上述代码我是模拟了这样一个场景。想象一下我们正在开发一个类似于微信的App,其中App通知主要可以分为两类,一类是我和别人的聊天消息,这类消息非常重要,因此重要等级我设为了IMPORTANCE_HIGH。另一类是公众号的订阅消息,这类消息不是那么重要,因此重要等级我设为了IMPORTANCE_DEFAULT。除此之外,重要等级还可以设置为IMPORTANCE_LOW、IMPORTANCE_MIN,分别对应了更低的通知重要程度。

    现在就可以运行一下代码了,运行成功之后我们关闭App,进入到设置 -> 应用 -> 通知当中,查看NotificationTest这个App的通知界面,如下图所示:

    刚才我们创建的两个通知渠道这里已经显示出来了。可以看到,由于这两个通知渠道的重要等级不同,通知的行为也是不同的,聊天消息可以发出提示音并在屏幕上弹出通知,而订阅消息只能发出提示音。

    当然,用户还可以点击进去对该通知渠道进行任意的修改,比如降低聊天消息的重要等级,甚至是可以完全关闭该渠道的通知。

    至于创建通知渠道的这部分代码,你可以写在MainActivity中,也可以写在Application中,实际上可以写在程序的任何位置,只需要保证在通知弹出之前调用就可以了。并且创建通知渠道的代码只在第一次执行的时候才会创建,以后每次执行创建代码系统会检测到该通知渠道已经存在了,因此不会重复创建,也并不会影响任何效率。


    让通知显示出来

    触发通知的代码和之前版本基本是没有任何区别的,只是在构建通知对象的时候,需要多传入一个通知渠道ID,表示这条通知是属于哪个渠道的。

    那么下面我们就来让通知显示出来。

    首先修改activity_main.xml中的代码,如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送聊天消息"
            android:onClick="sendChatMsg"
            />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送订阅消息"
            android:onClick="sendSubscribeMsg"
            />
    </LinearLayout>

    这里我们在布局文件中加入了两个按钮,很显然,一个是用于触发聊天消息渠道通知的,一个是用于触发订阅消息渠道通知的。

    接下来修改MainActivity中的代码,如下所示:

    public class MainActivity extends AppCompatActivity {
    
        ...
    
        public void sendChatMsg(View view) {
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Notification notification = new NotificationCompat.Builder(this, "chat")
                    .setContentTitle("收到一条聊天消息")
                    .setContentText("今天中午吃什么?")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.icon)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon))
                    .setAutoCancel(true)
                    .build();
            manager.notify(1, notification);
        }
    
        public void sendSubscribeMsg(View view) {
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Notification notification = new NotificationCompat.Builder(this, "subscribe")
                    .setContentTitle("收到一条订阅消息")
                    .setContentText("地铁沿线30万商铺抢购中!")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.icon)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.icon))
                    .setAutoCancel(true)
                    .build();
            manager.notify(2, notification);
        }
    }

    这里我们分别在sendChatMsg()和sendSubscribeMsg()方法中触发了两条通知,创建通知的代码就不再多做解释了,和传统创建通知的方法没什么两样,只是在NotificationCompat.Builder中需要多传入一个通知渠道ID,那么这里我们分别传入了chat和subscribe这两个刚刚创建的渠道ID。

    现在重新运行一下代码,并点击发送聊天消息按钮,效果如下图所示:

    由于这是一条重要等级高的通知,因此会使用这种屏幕弹窗的方式来通知用户有消息到来。然后我们可以下拉展开通知栏,这里也能查看到通知的详细信息:

    用户可以通过快速向左或者向右滑动来关闭这条通知。

    接下来点击发送订阅消息按钮,你会发现现在屏幕上不会弹出一条通知提醒了,只会在状态栏上显示一个小小的通知图标:

    因为订阅消息通知的重要等级是默认级别,这就是默认级别通知的展示形式。当然我们还是可以下拉展开通知栏,查看通知的详细信息:

    不过上面演示的都是通知栏的传统功能,接下来我们看一看Android 8.0系统中通知栏特有的功能。

    刚才提到了,快速向左或者向右滑动可以关闭一条通知,但如果你缓慢地向左或者向右滑动,就会看到这样两个按钮:

    其中,左边那个时钟图标的按钮可以让通知延迟显示。比方说这是一条比较重要的通知,但是我暂时没时间看,也不想让它一直显示在状态栏里打扰我,我就可以让它延迟一段后时间再显示,这样我就暂时能够先将精力放在专注的事情上,等过会有时间了这条通知会再次显示出来,我不会错过任何信息。如下所示:

    而右边那个设置图标的按钮就可以用来对通知渠道进行屏蔽和配置了,用户对每一个App的每一个通知渠道都有绝对的控制权,可以根据自身的喜好来进行配置和修改。如下所示:

    比如说我觉得订阅消息老是向我推荐广告,实在是太烦了,我就可以将订阅消息的通知渠道关闭掉。这样我以后就不会再收到这个通知渠道下的任何消息,而聊天消息却不会受到影响,这就是8.0系统通知渠道最大的特色。

    另外,点击上图中的所有类别就可以进入到当前应用程序通知的完整设置界面。


    管理通知渠道

    在前面的内容中我们已经了解到,通知渠道一旦创建之后就不能再通过代码修改了。既然不能修改的话那还怎么管理呢?为此,Android赋予了开发者读取通知渠道配置的权限,如果我们的某个功能是必须按照指定要求来配置通知渠道才能使用的,那么就可以提示用户去手动更改通知渠道配置。

    只讲概念总是不容易理解,我们还是通过具体的例子来学习一下。想一想我们开发的是一个类似于微信的App,聊天消息是至关重要的,如果用户不小心将聊天消息的通知渠道给关闭了,那岂不是所有重要的信息全部都丢了?为此我们一定要保证用户打开了聊天消息的通知渠道才行。

    修改MainActivity中的代码,如下所示:

    public class MainActivity extends AppCompatActivity {
    
        ...
    
        public void sendChatMsg(View view) {
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel channel = manager.getNotificationChannel("chat");
                if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
                    Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
                    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
                    intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.getId());
                    startActivity(intent);
                    Toast.makeText(this, "请手动将通知打开", Toast.LENGTH_SHORT).show();
                }
            }
    
            Notification notification = new NotificationCompat.Builder(this, "chat")
                    ...
                    .build();
            manager.notify(1, notification);
        }
    
        ...
    
    }

    这里我们对sendChatMsg()方法进行了修改,通过getNotificationChannel()方法获取到了NotificationChannel对象,然后就可以读取该通知渠道下的所有配置了。这里我们判断如果通知渠道的importance等于IMPORTANCE_NONE,就说明用户将该渠道的通知给关闭了,这时会跳转到通知的设置界面提醒用户手动打开。

    现在重新运行一下程序,效果如下图所示:

    可以看到,当我们将聊天消息的通知渠道关闭后,下次再次发送聊天消息将会直接跳转到通知设置界面,提醒用户手动将通知打开。

    除了以上管理通知渠道的方式之外,Android 8.0还赋予了我们删除通知渠道的功能,只需使用如下代码即可删除:

    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    manager.deleteNotificationChannel(channelId);

    但是这个功能非常不建议大家使用。因为Google为了防止应用程序随意地创建垃圾通知渠道,会在通知设置界面显示所有被删除的通知渠道数量,如下图所示:

    这样是非常不美观的,所以对于开发者来说最好的做法就是仔细规划好通知渠道,而不要轻易地使用删除功能。


    显示未读角标

    前面我们提到过,苹果是从iOS 5开始才引入了通知栏功能,那么在iOS 5之前,iPhone都是怎么进行消息通知的呢?使用的就是未读角标功能,效果如下所示:

    实际上Android系统之前是从未提供过这种类似于iOS的角标功能的,但是由于很多国产手机厂商都喜欢跟风iOS,因此各种国产手机ROM都纷纷推出了自己的角标功能。

    可是国产手机厂商虽然可以订制ROM,但是却没有制定API的能力,因此长期以来都没有一个标准的API来实现角标功能,很多都是要通过向系统发送广播来实现的,而各个手机厂商的广播标准又不一致,经常导致代码变得极其混杂。

    值得高兴的是,从8.0系统开始,Google制定了Android系统上的角标规范,也提供了标准的API,长期让开发者头疼的这个问题现在终于可以得到解决了。

    那么下面我们就来学习一下如何在Android系统上实现未读角标的效果。

    修改MainActivity中的代码,如下所示:

    public class MainActivity extends AppCompatActivity {
    
        ...
    
        @TargetApi(Build.VERSION_CODES.O)
        private void createNotificationChannel(String channelId, String channelName, int importance) {
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            channel.setShowBadge(true);
            NotificationManager notificationManager = (NotificationManager) getSystemService(
                    NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
    
        public void sendSubscribeMsg(View view) {
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Notification notification = new NotificationCompat.Builder(this, "subscribe")
                    ...
                    .setNumber(2)
                    .build();
            manager.notify(2, notification);
        }
    }

    可以看到,这里我们主要修改了两个地方。第一是在创建通知渠道的时候,调用了NotificationChannel的setShowBadge(true)方法,表示允许这个渠道下的通知显示角标。第二是在创建通知的时候,调用了setNumber()方法,并传入未读消息的数量。

    现在重新运行一下程序,并点击发送订阅消息按钮,然后在Launcher中找到NotificationTest这个应用程序,如下图所示:

    可以看到,在图标的右上角有个绿色的角标,说明我们编写的角标功能已经生效了。

    需要注意的是,即使我们不调用setShowBadge(true)方法,Android系统默认也是会显示角标的,但是如果你想禁用角标功能,那么记得一定要调用setShowBadge(false)方法。

    但是未读数量怎么没有显示出来呢?这个功能还需要我们对着图标进行长按才行,效果如下图所示:

    这样就能看到通知的未读数量是2了。

    可能有些朋友习惯了iOS上的那种未读角标,觉得Android上这种还要长按的方式很麻烦。这个没有办法,因为这毕竟是Android原生系统,Google没有办法像国内手机厂商那样可以肆无忌惮地模仿iOS,要不然可能会吃官司的。但是我相信国内手机厂商肯定会将这部分功能进行定制,风格应该会类似于iOS。不过这都不重要,对于我们开发者来说,最好的福音就是有了统一的API标准,不管国内手机厂商以后怎么定制ROM,都会按照这个API的标准来定制,我们只需要使用这个API来进行编程就可以了。

    好的,关于Android 8.0系统适配的上下两篇文章到这里就结束了,感谢大家阅读。

    文章中的示例源码点击 这里 下载。

    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

    20160507110203928         20161011100137978

    展开全文
  • 显示通知栏

    千次阅读 2014-03-09 21:58:05
    //显示通知栏图标 private void showNotification() { NotificationManager notificationManager = (NotificationManager) this.getSystemService(android.content.Context.NOTIFICATION_SERVICE);
  • 不知不觉安卓都快9.0了(更新的可够快的),随着它的更新会出现...之后研究了一番(诺基亚、华为、小米)小米和华为能弹出,猜测原因可能是系统版本过高或厂家自定义了系统。因为IM接入时,消息通知问题也接入小...
  • 参考这篇文章解决 /** * 发送通知 * @param content */ @SuppressLint("WrongConstant") private void sendNotification(String content) { try { String[] contents = content.spli...
  • 由于测试反馈才发现,之前写好的通知栏下载更新在部分手机上显示不出,导致用户无法更新。起初因为强调是小米手机,所以没有往Android8.0的方向去想,默默的认为是更新方法错误,查看过log日志后可以正常更新,只是...
  • 再接着,打开通知栏,用别的手机发消息给魅族,发现右上角有个小盒子加了个小点,打开盒子,发现消息就在里面 先说结果,再补过程。 魅族手机有个智能管理通知功能,一旦右滑取消通知栏消息5次以上,就会...
  • 1、正常使用通知栏: /** * 创建通知栏管理工具 */ NotificationManager notificationManager = (NotificationManager) getSystemService (NOTIFICATION_SERVICE); /** ...
  • Android 通知栏显示与设置

    千次阅读 2019-04-12 19:42:31
    Android 基础设置和发送通知在通知栏显示。 Android 版本通知适配 Android 8.0 及以上使用通知都必须设置 NotificationChannel 类才能正常在通知栏弹出通知,只需 Application 中设置一次就可以了。 当 ...
  • Android显示通知栏消息

    千次阅读 2016-03-12 17:18:30
    一、说明 andorid应用经常会有一些推送消息,将数据从后台推向...现在来测试一下如何使用通知栏显示消息。 二、了解常用类和方法。 1. NotificationManager : 是状态栏通知的管理类,负责发通知、清楚通知等。
  • 但是我们有时需要显示通知栏,但是通知栏在8.0的系统上面突然消失了,Android8.0中,对于通知栏的下载更新显示需要重新定义,需要优先定义一个应用中唯一的ID和Name。通过下面的代码对比你会发现NotificationChannel...
  • 描述:miui12下拉通知栏有通知看到通知内容 分析 :这是由于miui系统状态栏策略发生改变 步骤: 从左边往下拉是通知,右边是控制中心,按照miui系统这个新操作即可 如果习惯,可以按照此路径修改,设置->...
  • 消息推送接收到后,显示通知栏 public static void showNotifictionIcon(Context context) { Notification
  • Qt for Android:实现本地通知栏显示

    千次阅读 2019-07-22 18:56:24
    QtAndroid通知栏显示以及消息推送 作者:melon 日期:2019/7/18 1.前言 网上查阅了很多资料,没有使用qt写android的通知消息的,必须得通过JNI接口调用java的android原生接口,实现通知栏的显示和各种通知消息...
  • Android中显示消息通知栏

    千次阅读 2019-06-11 16:13:11
    参考网址:https://blog.csdn.net/qq_35749683/article/details/80451791 https://blog.csdn.net/u011286777/article/details/53319535 /** * 消息通知栏 * @param context * 上下文 * @param cl...
  • Android开发之获取通知栏内容

    万次阅读 2018-11-03 16:44:30
    1.拿到通知栏内容 2.将通知栏内容写入本地 3.显示通知内容到屏幕上 这demo目前就这三个小模块 这是获取的微信消息的内容   我们来看下源码: MyNotifiService.java package com.qfy.getnotifiservice;...
  • 仿微信通知栏

    千次阅读 2017-10-28 14:24:00
    点击通知栏后跳转并传值app下载体验点击下载通知栏图片通知栏的小图标建议使用纯白色,在通知栏显示的时候就是白色,拉下来的时候就会变成灰色的 在图片文件夹中放置不同尺寸的图标24 × 24 (mdpi) 36 × 36 (hdpi...
  • 一个Android程序仅仅只能前台 运行...2,通知栏通知消息,系统的notification service实现程序后台运行 实现service程序 后台运行,首先要解决几个问题: 如何判断程序是否后台运行?如何在程序后台运行时去开启服务?
  • App更新进度显示在后台通知栏详解

    千次阅读 2016-12-14 22:01:59
    1.场景还原  最近在项目中遇到App更新的问题,老大更新进度直接...今天就后台通知栏显示更新进度功能给大家伙分享一下,先上图: 2.PendingIntent的介绍  根据pend英文意思就知道是延迟的intent,主要用来在某个事
  • -- 若启用该功能可删除该组件,将拉起其他应用也能被其他应用拉起 --> android:name="cn.jpush.android.service.DaemonService" android:enabled="true" android:exported="true"> 您应用的包名"/> ...
  • 包括:通知栏消息、点亮屏幕、震动、声音、显示样式等。下面是简单的效果图:   这是本文中的例子下载链接 下面主要讲的是: AndroidManifest 的权限配置 静态常量类 Constant MainActivity 主要代码:...
  • Android 半透明通知栏显示 Activity全屏

    千次阅读 2017-06-12 04:33:17
    1. Android 沉浸式通知栏显示 我们来了解“Android的沉浸式”这个词的释义,它是用来显示在APP UI设计上的,通知栏占据APP顶端与其颜色相同。 2.导入systembartint类 将systembartint.jar文件 粘贴到工程 Libs目录...
  • android原生机中 可以在设置中的锁屏设置页面对锁屏时是否显示通知栏进行设置,在代码中对应LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,LOCK_SCREEN_SHOW_NOTIFICATIONS这两个设置字段,但是我一直没有找到锁屏界面...
  • requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.TYPE_...就是这么两行简单的代码就可以使窗口全屏,将通知栏盖住隐藏掉。也可以完完整整的展示一个背景图片。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,148
精华内容 28,859
关键字:

怎么让通知栏不显示内容