我正在用Java for Android实现StepCounter。如果没有此服务的另一个实例,我创建了一个以ForegroundService形式启动的服务。
package com.**.service.services;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import com.**.R;
import java.util.Timer;
import java.util.TimerTask;
public class StepCountingService extends Service implements SensorEventListener {
private SensorManager sensorManager;
private Sensor steps;
private int numSteps = 0;
private Intent intent;
public static final String BROADCAST_ACTION = "BROADCASTING_STEPS";
public static final String TAG = "StepCountingService";
private static final int UPDATE_DELAY = 5000;
public static StepCountingService instance = null;
public static boolean isStarted() {
return instance != null;
}
@Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
instance = this;
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
steps = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
sensorManager.registerListener(this, steps, SensorManager.SENSOR_DELAY_UI);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
broadcastSensorValue();
}
}, 1000, 5000);
}
@Override
public void onDestroy() {
super.onDestroy();
instance = null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand called");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = "com.sportify.app";
String channelName = "Step Counting";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is counting steps in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
else {
startForeground(1, new Notification());
}
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
Log.i(TAG, "onSensorChanged called " + numSteps);
if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
numSteps++;
}
}
private void broadcastSensorValue() {
if (numSteps > 0) {
intent.putExtra("step_count", String.valueOf(numSteps));
sendBroadcast(intent);
numSteps = 0; //TODO: if broadcast is not received (bcs app is closed), steps are lost! FIX ME!
}
}
}
在我的活动中,服务启动看起来像这样
if (!StepCountingService.isStarted()) {
Intent service = new Intent(parent.getBaseContext(), StepCountingService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
parent.startForegroundService(service);
} else {
parent.startService(service);
}
Log.i(StepCountingService.TAG, "setting up service");
}
else {
Log.i(StepCountingService.TAG, "service already running!");
}
parent.registerReceiver(broadcastReceiverSteps, new IntentFilter(StepCountingService.BROADCAST_ACTION));
和类似的BroadcastReceiver
private BroadcastReceiver broadcastReceiverSteps = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
homeViewModel.setSteps(context, Integer.valueOf(intent.getStringExtra("step_count")));
}
};
[切换到活动4次后,BroadcastReceiver接收4次每条消息,切换到活动10次后,它接收10条每条消息。有人可以告诉我这个问题吗?我以为我只有1个服务,所以每5秒发送1条广播消息。
感谢艺术!
我只需要正确地注销BroadcastReceivers:
@Override
public void onDestroy() {
Activity parent = getActivity();
parent.unregisterReceiver(broadcastReceiverSteps);
parent.unregisterReceiver(broadcastReceiverLocations);
super.onDestroy();
}
现在像魅力一样工作!