2

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

有3种情况:

  1. 保持应用程序运行:每 15 秒显示一次通知(确定)。
  2. 通过单击 HOME 按钮将应用程序置于后台:通知继续显示(确定)
  3. 单击 BACK 按钮(这将关闭应用程序):后台服务已停止并且不再显示通知(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
    }

}

简单服务

    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);
    }

}
4

3 回答 3

1

在服务的方法onStartCommand()中,返回START_STICKY。该服务将继续运行,直到您明确调用stopSelf()该服务或stopService()从您的活动中调用。

于 2014-04-01T08:54:14.740 回答
0

尝试实现前台服务。前台服务

前台服务显示通知并且永远不会停止。

在您的服务的 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);
于 2014-04-01T08:51:55.837 回答
0

这对我有用:

notifyIntent.setAction(Intent.ACTION_MAIN);
notifyIntent.addCategory(Intent.CATEGORY_LAUNCHER);
于 2016-03-11T06:13:01.943 回答