安卓8.0之后的通知问题

通知概览

通知是指 Android 在应用的界面之外显示的消息,旨在向用户提供提醒、来自他人的通信信息或应用中的其他实时信息。用户可以点按通知来打开应用,也可以直接在通知中执行某项操作。

 

目前通知在安卓系统上应用广泛,可以在不同的位置以不同的格式显示,例如,状态栏中的图标、抽屉式通知栏中比较详细的条目、应用图标上的标志,以及在配对的穿戴式设备上自动显示。

 

在安卓8.0之后,谷歌引入了Channel(渠道)的概念,将不同的信息根据消息的类型推送到相应的渠道,这样做可以可以做到消息的分类,比如我使用支付宝,我希望收到收钱到账的消息推送,而不希望收到支付宝给我推送商品推荐的消息,这个时候由于这两两种消息处于不同的渠道,我关闭商品推送的渠道即可。

 

安卓官方开发文档中的最后面有如下的说明:

Android 8.0,API 级别 26

  • 现在必须将各个通知放入特定渠道中。
  • 现在,用户可以按渠道关闭通知,而非关闭来自某个应用的所有通知。
  • 包含有效通知的应用将在主屏幕/启动器屏幕上相应应用图标的上方显示通知“标志”。
  • 现在,用户可以从抽屉式通知栏中暂停某个通知。您可以为通知设置自动超时时间。
  • 您还可以设置通知的背景颜色。
  • 部分与通知行为相关的 API 从 Notification 移至了 NotificationChannel。例如,在搭载 Android 8.0 及更高版本的设备中,使用 NotificationChannel.setImportance(),而非 NotificationCompat.Builder.setPriority()

 

我相信在看第一行代码Android第2版的同学都无法实现书中的使用通知案例,并且会发现如下使用出现的横杠:

  • Notification notification = new NotificationCompat.Builder(this);

点上去看,出现"Builder(android.content.Context)' is deprecated 

因为从8.0开始需要使用带有channelld的函数,即

  • Notification notification = new NotificationCompat.Builder(this, "chat");

 

改造书中的代码如下:

AndroidMainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.notificationtest">

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".NotificationActivity"></activity>
        <activity android:name=".MainActivity"
            tools:ignore="Instantiatable">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml中使用LinearLayout,并添加了三个按钮,其中第二个和第三个按钮和本次实验相关,一个用于发送聊天信息,一个用于发送订阅消息。

<?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="vertical"
    android:padding="10dp">

    <Button
        android:id="@+id/send_notice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send notice" />

    <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中的代码,见名知意,不清楚的参见第一行代码相关内容或者本博客的参考资料

package com.example.notificationtest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.view.View;


public class MainActivity extends AppCompatActivity  {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //版本大于等于 26
        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);
        channel.setShowBadge(true);
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
    }


    public void sendChatMsg(View view) {
        Intent intent = new Intent(this, NotificationActivity.class);
        PendingIntent pdIntent = PendingIntent.getActivity(this, 0, intent, 0);

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification notification = new NotificationCompat.Builder(this, "chat")
                .setContentTitle("收到一条聊天消息")
                .setContentText("今天中午吃什么?")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.notification)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_image))
                .setContentIntent(pdIntent)
                .setAutoCancel(true)
                .build();
        manager.notify(1, notification);
    }


    public void sendSubscribeMsg(View view) {
        Intent intent = new Intent(this, NotificationActivity.class);
        PendingIntent pdIntent = PendingIntent.getActivity(this, 0, intent, 0);

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification notification = new NotificationCompat.Builder(this, "subscribe")
                .setContentTitle("收到一条订阅消息")
                .setContentText("Macbook pro大降价!")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.drawable.notification)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_image))
                .setContentIntent(pdIntent)
                .setAutoCancel(true)
                .setNumber(2)
                .build();
        manager.notify(2, notification);
    }


}

notification_layout中的代码,创建一个TextView显示一些信息,用于点击消息时候的跳转到本页面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".NotificationActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="24sp"
        android:text="This is notification layout"
        />

</RelativeLayout>

NotificationActivity中的代码,注释的代码是因为点击通知后需要将通知取消,在MainActivity中的.setAutoCancel(true)可替代这段代码,因此  import android.app.NotificationManager;  可以去掉,考虑到有的同学会打开注释,或者使用它,就不删除了。

package com.example.notificationtest;

import androidx.appcompat.app.AppCompatActivity;

import android.app.NotificationManager;
import android.os.Bundle;

public class NotificationActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notification_layout);
//        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//        manager.cancel(1);
//        manager.cancel(2);
    }
}

运行结果:

随便点一个通知,进入如下界面,然后通知栏清除该通知

说明:

如果出现图片相关的错误而运行不了,是因为以上程序中使用了两张自己导入的图片,我将图片放在这里,按需获取

big_image.jpg

notification.png

参考资料:

1、https://www.jianshu.com/p/559c30cdeed0

2、https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=zh-cn

3、第一行代码

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值