Remote Views of Notification in Android

RemoteViews is used to customize the layout of the notification bar notification, here is an introduction.

1. The difference between RemoteViews and Activity

  • RemoteViews are mainly used for notification bar parts and desktop parts, and Activity is used for pages.
  • RemoteViews only supports a few controls, such as TextView, ImageView, Button, ImageButton, ProgressBar, Chronometer (timer) and AnalogClock (analog clock).
  • RemoteViews cannot directly obtain and set control information, and can only modify control information through the set method of the object.

2. Common methods in RemoteViews

  • Constructor: Create a RemoteViews object. The first parameter is the package name, and the second parameter is the layout file id.
  • setViewVisibility: Set whether the specified control is visible.
  • setViewPadding: Set the spacing of the specified control.
  • setTextViewText: Set the text content of the specified TextView or Button control.
  • setTextViewTextSize: Set the text size of the specified TextView or Button control.
  • setTextColor: Set the text color of the specified TextView or Button control.
  • setTextViewCompoundDrawables: Set the icon around the text of the specified TextView or Button control.
  • setImageViewResource: Set the resource number of the ImageView or ImageButton control.
  • setImageViewBitmap: Set the bitmap object of the ImageView or ImageButton control.
  • setChronometer: Set the timer information.
  • setProgressBar: Set the progress bar information, including the maximum value and the current progress.
  • setOnClickPendingIntent: Set the click corresponding action of the specified control.

3. Examples of use

Layout file notify_music.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minHeight="64dp"
    android:orientation="horizontal" >

    <!-- 这是通知栏左侧的图标,仿千千静听 -->
    <ImageView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:scaleType="fitCenter"
        android:src="@mipmap/tt" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="4"
        android:layout_margin="3dp"
        android:orientation="vertical" >

        <!-- 这是展示歌曲播放进度的进度条 -->
        <ProgressBar
            android:id="@+id/pb_play"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:max="100"
            android:progress="10" />

        <!-- 这是正在播放的歌曲名称 -->
        <TextView
            android:id="@+id/tv_play"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            style="@style/NotificationTitle"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <!-- 这是计数器,用于显示歌曲已经播放的时长 -->
        <TextView
            android:id="@+id/chr_play"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:gravity="center"/>

        <!-- 这是控制按钮,用于歌曲的暂停与恢复操作 -->
        <Button
            android:id="@+id/btn_play"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="3"
            android:gravity="center"
            android:background="@drawable/btn_nine_selector"
            android:text="暂停"
            android:textColor="@color/black"
            android:textSize="15sp" />
    </LinearLayout>
</LinearLayout>

Referenced Activity

public class MainActivity extends AppCompatActivity {

    private Button bt;
    private String PAUSE_EVENT = ""; // “暂停/继续”事件的标识串
    private NotificationManager notifyMgr;
    private Handler handler;
    private Runnable runnable;
    private int progress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 从系统服务中获取通知管理器
                notifyMgr = (NotificationManager)
                        getSystemService(Context.NOTIFICATION_SERVICE);
                // 获取自定义消息的通知对象
                handler = new Handler();
                runnable = new Runnable() {
                    @Override
                    public void run() {
                        progress++;
                        Notification notify = getNotify(MainActivity.this, PAUSE_EVENT,
                                "雪绒花", true, progress, SystemClock.elapsedRealtime());
                        // 使用通知管理器推送通知,然后在手机的通知栏就会看到该消息
                        notifyMgr.notify(R.string.app_name, notify);
                        handler.postDelayed(runnable,1000);
                    }
                };
                handler.postDelayed(runnable,100);
            }
        });
    }

    private Notification getNotify(Context ctx, String event, String song, boolean isPlaying, int progress, long time) {
        SimpleDateFormat format = new SimpleDateFormat("mm:ss");
        // 创建一个广播事件的意图
        Intent intent1 = new Intent(event);
        //调用后只有8.0以上执行
        createNotifyChannel(notifyMgr,this,"channel_id");
        // 创建一个用于广播的延迟意图
        PendingIntent broadIntent = PendingIntent.getBroadcast(
                ctx, R.string.app_name, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
        // 根据布局文件notify_music.xml生成远程视图对象
        RemoteViews notify_music = new RemoteViews(ctx.getPackageName(), R.layout.notify_music);
        if (isPlaying) { // 正在播放
            notify_music.setTextViewText(R.id.btn_play, "暂停"); // 设置按钮文字
            notify_music.setTextViewText(R.id.tv_play, song + "正在播放"); // 设置文本文字
            notify_music.setTextViewText(R.id.chr_play,format.format(time)); // 设置计数器
        } else { // 不在播放
            notify_music.setTextViewText(R.id.btn_play, "继续"); // 设置按钮文字
            notify_music.setTextViewText(R.id.tv_play, song + "暂停播放"); // 设置文本文字
            notify_music.setTextViewText(R.id.chr_play,"00:00"); // 设置计数器
        }
        // 设置远程视图内部的进度条属性
        notify_music.setProgressBar(R.id.pb_play, 100, progress, false);
        // 整个通知已经有点击意图了,那要如何给单个控件添加点击事件?
        // 办法是设置控件点击的广播意图,一旦点击该控件,就发出对应事件的广播。
        notify_music.setOnClickPendingIntent(R.id.btn_play, broadIntent);
        // 创建一个跳转到活动页面的意图
        Intent intent2 = new Intent(ctx, MainActivity.class);
        // 创建一个用于页面跳转的延迟意图
        PendingIntent clickIntent = PendingIntent.getActivity(ctx,
                R.string.app_name, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
        // 创建一个通知消息的构造器
        Notification.Builder builder = new Notification.Builder(ctx);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Android 8.0开始必须给每个通知分配对应的渠道
            builder = new Notification.Builder(this,"channel_id");
        }
        builder.setContentIntent(clickIntent) // 设置内容的点击意图
                .setContent(notify_music) // 设置内容视图
                .setTicker(song) // 设置状态栏里面的提示文本
                .setSmallIcon(R.mipmap.tt_s); // 设置状态栏里的小图标
        // 根据消息构造器构建一个通知对象
        Notification notify = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            notify = builder.build();
        }
        return notify;
    }

    /**
     * 创建通知渠道,Android8.0开始必须给每个通知分配对应的渠道
     * @param notifyMgr
     * @param ctx
     * @param channelId
     */
    private void createNotifyChannel(NotificationManager notifyMgr,Context ctx,String channelId){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            //创建一个默认重要性的通知渠道
            NotificationChannel channel = new NotificationChannel(channelId,"Channel",NotificationManager.IMPORTANCE_DEFAULT);
            channel.setSound(null,null);
            channel.setShowBadge(true);
            channel.canBypassDnd();//可否绕过请勿打扰模式
            channel.enableLights(true);//闪光
            channel.setLockscreenVisibility(Notification.FLAG_ONLY_ALERT_ONCE);//锁屏显示通知
            channel.canShowBadge();//桌面ICON是否可以显示角标
            channel.getGroup();//获取通知渠道组
            channel.shouldShowLights();//是否会闪光
            notifyMgr.createNotificationChannel(channel);
        }
    }
}

You can refer to this wording to achieve your own needs.

Guess you like

Origin blog.csdn.net/weixin_38322371/article/details/114019450