通过BACK按钮关闭应用程序后,后台服务停止

时间:2014-04-01 08:49:13

标签: android eclipse background-service

当用户使用BACK按钮退出应用程序时,Android中的后台服务停止运行。如果应用程序位于前台或后台,则相同的服务可以正常工作(单击HOME按钮)。

有3例:

  1. 保持应用运行:每15秒显示一次通知(确定)。
  2. 点击HOME按钮将应用程序置于后台:通知会一直显示(OK)
  3. 单击BACK按钮(关闭应用程序):后台服务已停止,不再显示通知(BUG)
  4. 预期行为

    同样在#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);
        }
    
    }
    

3 个答案:

答案 0 :(得分:1)

在服务的方法onStartCommand()中,返回START_STICKY。 该服务将继续有效,直到您明确致电服务中的stopSelf()或从您的活动中致电stopService()

答案 1 :(得分:0)

尝试实施前台服务。 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);

答案 2 :(得分:0)

这对我有用:

notifyIntent.setAction(Intent.ACTION_MAIN);
notifyIntent.addCategory(Intent.CATEGORY_LAUNCHER);