背景:
Ionic 项目,要实现通知栏常驻,就是只要 app 活着,顶部通知栏就要显示“XXX 正在运行中”。
其中涉及 Android 中的两个主要概念。
Service
和 Notification
修改的文件涉及三个
一、应用的清单文件(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, MyService.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