我正在制作一个包含两项活动的应用程序,其中一项是主要活动。应用启动时,它将创建一个前台服务,该服务注册一个用于USER_PRESENT意图的广播侦听器。广播侦听器获得广播后,将触发第二个活动。我的代码面临两个问题: 1)前台服务通知未到。但是,该服务运行。 2)当我的应用程序是手机上的活动应用程序时,广播侦听器可以正常工作。但是,如果我的应用程序在后台运行,则广播侦听器将无法正常工作。但是该服务正在运行,因为日志中有消息指出该服务已被终止/停止。
如何解决这两个问题?
我正在具有Android 8.1.0的Oppo CPH1859手机上运行该应用程序
Android.manifest +++++++++++++
<uses-sdk android:minSdkVersion="26" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<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">
<service
android:name=".MyFGService"
android:enabled="true"
android:exported="true"></service>
<activity
android:name=".DisplayMessageActivity"
android:parentActivityName=".MainActivity">
<!-- The meta-data tag is required if you support API level 15 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
+++++
在主要活动中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("FIRST APP","Main activity started");
myService = new Intent(MainActivity.this, MyFGService.class);
startService(myService);
}
@Override
public void onDestroy() {
stopService(myService);
Log.v("FIRST APP","Main activity destroyed");
super.onDestroy();
}
++++++++++++
在MyFGService中
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service (re)starting", Toast.LENGTH_SHORT).show();
Log.v("FIRST APP", "Service (re)starting");
// If we get killed, after returning from here, restart
return START_STICKY;
}
private String createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "TEST Name";
String description = "TEST Description";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel( "FirstAppNotifChannel", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
return channel.getId();
}
return null;
}
@Override
public void onCreate(){
super.onCreate();
Log.v("FIRST APP", "Service created");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
String notificationChannelID = createNotificationChannel();
Log.v("FIRST APP","notification channel ID =" + notificationChannelID);
Notification myNotification = new Notification.Builder(this, notificationChannelID)
.setContentTitle("TEST Title")
.setContentText("TEST Content")
.setContentIntent(pendingIntent)
.build();
startForeground(101, myNotification);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(mReciever, filter);
}
@Override
public void onDestroy() {
Toast.makeText(this, "service destroyed", Toast.LENGTH_SHORT).show();
Log.v("FIRST APP", "Service destroyed");
unregisterReceiver(mReciever);
}
答案 0 :(得分:0)
您需要使用ContextCompat.startForgroundService()
来启动FG服务。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("FIRST APP","Main activity started");
myService = new Intent(MainActivity.this, MyFGService.class);
ContextCompat.startForegroundService(myService);
}
但是,要考虑的一件事是 Oreo 设置了后台和广播限制,这解释了为什么您的应用程序在后台时没有接收广播。除了启动前台服务之外,您别无选择。 Background Execution Limits
此外,前台服务未显示的原因是您需要创建通知频道。创建一个名为“ BaseApp”的类,该类扩展了Application
,因为在启动应用程序时该类仅需要运行一次。 Create and Manage Notification Channels
private void createNotificationChannel() { //This function creates a channel, call this channel in `onCreate()` method of your n
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
在您的onCreate()
类的BaseApp
方法中调用此方法。希望在此之后,您的前台服务能够正常工作。另外,请记住,如果您的应用定位到 Android Pie ,那么您需要在 Manifest 文件中添加前台权限。
科林样品
class BaseApp : Application() {
companion object {
const val CHANNEL_1_ID = "foreground_service_channel"
}
override fun onCreate() {
super.onCreate()
createNotificationChannels()
}
private fun createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel1 = NotificationChannel(CHANNEL_1_ID, "CHANNEL 1", NotificationManager.IMPORTANCE_HIGH)
channel1.description = "This channel is used to show notes in notfication"
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel1)
}
}
}
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />