当应用程序通过BACK按钮关闭时,后台服务停止
问题描述:
当用户使用BACK按钮退出应用程序时,Android中的后台服务停止运行。如果应用程序处于前景或背景中,则相同的服务可以正常工作(单击HOME按钮)。当应用程序通过BACK按钮关闭时,后台服务停止
有三种情况:
- 保持该应用运行:每15秒的通知显示(OK)。
- 通过单击HOME按钮把应用程序在后台:通知使显示(OK)
- 单击后退按钮(这将关闭应用程序):后台服务被停止,并没有更多的通知显示(BUG)
预期行为
同样在案例#3中,通知应该每隔15秒继续运行一次。
我的整个源代码如下
MainActivity.java
package com.example.service_demo;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private TextView timerValue;
private Button startTimer;
private Button cancleTimer;
Intent i;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapview();
}
private void mapview() {
timerValue = (TextView) findViewById(R.id.timertext);
startTimer = (Button) findViewById(R.id.starttimer);
cancleTimer = (Button) findViewById(R.id.cancletimer);
startTimer.setOnClickListener(this);
cancleTimer.setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
i = new Intent(this, SimpleService.class);
if (isMyServiceRunning()) {
Toast.makeText(getBaseContext(), "Service is running,",
Toast.LENGTH_SHORT).show();
registerReceiver(broadcastReceiver, new IntentFilter(
SimpleService.BROADCAST_ACTION));
startTimer.setEnabled(false);
} else {
Toast.makeText(getBaseContext(), "There is no service running",
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onClick(View v) {
if (v == startTimer) {
startTimer.setEnabled(false);
i = new Intent(this, SimpleService.class);
startService(i);
registerReceiver(broadcastReceiver, new IntentFilter(
SimpleService.BROADCAST_ACTION));
} else if (v == cancleTimer) {
i = new Intent(this, SimpleService.class);
stopService(i);
timerValue.setText("00:00:00");
startTimer.setEnabled(true);
}
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
private void updateUI(Intent intent) {
String str = intent.getStringExtra("textval");
timerValue.setText(str);
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if (SimpleService.class.getName().equals(
service.service.getClassName())) {
return true;
}
}
return false;
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
i = new Intent(this, SimpleService.class);
startService(i);
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
System.exit(0); // system.exit(0) is mendatory for my app so it can't be
// removed
}
}
SimpleService
package com.example.service_demo;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class SimpleService extends Service {
private NotificationManager mNM;
private long startTime = 0L;
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
long basestart = System.currentTimeMillis();
Timer timer = new Timer();
long timeswap = 0L;
int secs = 0;
int mins = 0;
int hour = 0;
Intent intent;
String s;
public static final String BROADCAST_ACTION = "com.example.service_demo.MainActivity";
private int NOTIFICATION = 1;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
intent = new Intent(BROADCAST_ACTION);
Toast.makeText(this, "Service Started", 2000).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
timer.schedule(new RemindTask(), 0, 1000);
}
});
t.start();
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
mNM.cancel(NOTIFICATION);
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
Toast.makeText(this, "Service Stoped", 2000).show();
}
class RemindTask extends TimerTask {
@Override
public void run() {
timeInMilliseconds = System.currentTimeMillis() - basestart;
timeSwapBuff = timeswap;
updatedTime = timeSwapBuff + timeInMilliseconds;
secs = (int) (updatedTime/1000);
mins = secs/60;
hour = mins/60;
secs = secs % 60;
mins = mins % 60;
s = "" + String.format("%02d", hour) + ":" + ""
+ String.format("%02d", mins) + ":"
+ String.format("%02d", secs);
if (s.equalsIgnoreCase("00:00:15")) {
showNotification();
}
intent.putExtra("textval", s);
sendBroadcast(intent);
}
}
private void showNotification() {
// In this sample, we'll use the same text for the ticker and the
// expanded notification
CharSequence text = s;
// Set the icon, scrolling text and timestamp
@SuppressWarnings("deprecation")
Notification notification = new Notification(R.drawable.ic_launcher,
text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this
// notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, "Notification Label", text,
contentIntent);
// Send the notification.
mNM.notify(NOTIFICATION, notification);
}
}
答
尝试实施前景的服务。 foreground service
前台服务显示通知并且从不停止。
在你的服务的onCreate()中实现这个代码片段。
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
答
在服务的方法onStartCommand()
,返回START_STICKY
。 服务将继续运行,直到您明确地在服务中调用stopSelf()
或从您的活动中调用stopService()
。
答
这个工作对我来说:
notifyIntent.setAction(Intent.ACTION_MAIN);
notifyIntent.addCategory(Intent.CATEGORY_LAUNCHER);
嘿你为什么要使用System.exit(0);你可以删除然后尝试。 – MPG
而不是显示一个吐司,你可以尝试打印日志,看看它是否工作,即使应用程序退出后。 –