2

ユーザーが [戻る] ボタンを使用してアプリを終了すると、Android のバックグラウンド サービスの実行が停止します。アプリがフォアグラウンドまたはバックグラウンド ([ホーム] ボタンをクリック) にある場合、同じサービスが正常に機能します。

3 つのケースがあります。

  1. アプリを実行し続ける: 15 秒ごとに通知が表示されます (OK)。
  2. ホームボタンをクリックしてアプリをバックグラウンドにします: 通知が表示され続けます (OK)
  3. [戻る] ボタンをクリックします (アプリが閉じます): バックグラウンド サービスが停止し、通知が表示されなくなります (バグ)。

予想される行動

また、ケース #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

これは私のために働く:

notifyIntent.setAction(Intent.ACTION_MAIN);
notifyIntent.addCategory(Intent.CATEGORY_LAUNCHER);
于 2016-03-11T06:13:01.943 に答える
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 に答える