[Android] 通知栏常驻

分类:移动端     发布时间:2020-02-01     最后更新:2020-11-18     浏览数:2959
Service 加 Notification 实现通知栏常驻

背景: Ionic 项目,要实现通知栏常驻,就是只要 app 活着,顶部通知栏就要显示“XXX 正在运行中”。 其中涉及 Android 中的两个主要概念。 ServiceNotification 修改的文件涉及三个

一、应用的清单文件(AndroidManifest.xml

要用 service 必须要在 AndroidManifest.xml 中声明,我就踩进这个坑了,半天才爬出来。总结:给点耐心多看官方文档。

<manifest ... >
  ...
  <application ... >
      <service android:name=".MyService" />
      ...
  </application>
</manifest>

二、MyService

不知道说啥好,直接看代码,引入的就不放上来了,用 IDE 解决,缺少什么就引入什么。特别注意的是 Android 8 之后增加 NotificationChannel,要注意兼容,详情请看通知概览

public class MyService extends Service {

    private NotificationManager notificationManager;
    private String notificationId = "stickyChannelId";
    private String notificationName = "Sticky Channel";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // 创建NotificationChannel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(channel);
        }
        startForeground(1, getNotification());
    }

    private Notification getNotification() {
        Notification.Builder builder = new Notification.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("测试服务")
                .setOngoing(true)
                .setContentText("我正在运行");
        // 设置Notification的ChannelID,否则不能正常显示
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(notificationId);
        }
        Notification notification = builder.build();
        return notification;
    }
}

三、使用

还是直接上代码吧,注释也做了说明了。 简单来说就是 onCreate 中调用 startService 或者 startForegroundService 把这个 service 进入前台服务(保活)。 在 onDestroy 回调停止服务

public class MainActivity extends CordovaActivity
{
    private Intent mServiceIntent;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // enable Cordova apps to be started in the background
        Bundle extras = getIntent().getExtras();
        if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
            moveTaskToBack(true);
        }

        // Set by <content src="index.html" /> in config.xml
        loadUrl(launchUrl);

        if (mServiceIntent == null) {
            mServiceIntent = new Intent(MainActivity.this, MyForegroundService.class);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // android8.0 以上通过 startForegroundService 启动 service
            startForegroundService(mServiceIntent);
        } else {
            startService(mServiceIntent);
        }
    }

    /**
     * The final call you receive before your activity is destroyed.
     */
    @Override
    public void onDestroy() {
        if (mServiceIntent != null) {
          this.stopService(mServiceIntent);
        }
        super.onDestroy();
    }
}

注意:

defaultBuildToolsVersion="28.0.3"
defaultMinSdkVersion=19 
defaultTargetSdkVersion=23 // 如果设为 26,常驻通知栏就不显示了。原因不明。
defaultCompileSdkVersion=28

参考:

上一篇: NG ZORRO 动态引入 svg icon 下一篇: CSS 实现纯色背景占容器的百分比