【发布时间】:2017-12-02 18:28:09
【问题描述】:
我创建了一项服务,可在设备移动时跟踪设备的位置。该服务由绑定到它的 Activity 启动,并且在此 Activity 中有一个“开始跟踪”按钮。当按下此按钮时,我需要服务在前台启动,以便它存储设备移动到的位置,即使绑定到它的 Activity 已关闭,或者应用程序已最小化。
我了解,要使服务处于前台,必须显示通知。我已尝试这样做,但是当活动被销毁时,我无法显示通知或服务在前台工作。
由于通知渠道的原因,Oreo 中的通知似乎发生了变化,但我无法弄清楚需要做些什么不同的事情。我正在测试的设备是 8.0.0。
这是我的服务:
public class LocationTrackerService extends Service {
private LocationListener locationListener;
private LocationManager locationManager;
private IBinder binder = new LocalBinder();
private boolean isTracking;
private ArrayList<Location> trackedWaypoints;
private String bestProvider;
private Timer timer;
private Distance distance;
@SuppressLint("MissingPermission")
@Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
bestProvider = locationManager.getBestProvider(criteria, true);
isTracking = false;
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Intent intent = new Intent("location_update");
intent.putExtra("latitude", location.getLatitude());
intent.putExtra("longitude", location.getLongitude());
sendBroadcast(intent);
if (isTracking) {
if (trackedWaypoints.size() > 1) {
distance.add(trackedWaypoints.get(trackedWaypoints.size() - 1).distanceTo(location));
}
trackedWaypoints.add(location);
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) { }
@Override
public void onProviderEnabled(String s) { }
@Override
public void onProviderDisabled(String s) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener);
}
@Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates(locationListener);
}
}
public void startTracking() {
trackedWaypoints = new ArrayList<Location>();
timer = new Timer();
distance = new Distance();
timer.start();
isTracking = true;
startInForeground();
}
private void startInForeground() {
Intent notificationIntent = new Intent(this, WorkoutActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification =
new Notification.Builder(this)
.setContentTitle("TEST")
.setContentText("HELLO")
.setSmallIcon(R.drawable.ic_directions_run_black_24dp)
.setContentIntent(pendingIntent)
.setTicker("TICKER")
.build();
startForeground(101, notification);
}
public void stopTracking() {
isTracking = false;
stopForeground(true);
}
public boolean isTracking() {
return isTracking;
}
public ArrayList<Location> getTrackedWaypoints() {
return trackedWaypoints;
}
public Timer getTime() {
timer.update();
return timer;
}
public Distance getDistance() {
return distance;
}
public int getSteps() {
return 0;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public class LocalBinder extends Binder {
public LocationTrackerService getLocationTrackerInstance() {
return LocationTrackerService.this;
}
}
}
【问题讨论】:
-
你似乎没有打电话给
startTracking()。 -
当按钮被按下时从activity中调用。
-
如果您的
targetSdkVersion为 26 或更高,您将需要定义一个通知通道(如果您之前没有定义它)并在构建器中使用该通道 ID。你也可以考虑切换到NotificationCompat.Builder。 -
定义通知渠道是我迷路的地方。我是否只是将其设置为通知通道设置的整数之一?
-
查看 mac229 发布的答案。然后,您将使用两个参数
Builder构造函数并将PRIMARY_CHANNEL_ID与Context一起传入。另请参阅我的一个示例应用程序中的 these lines 和 these lines。
标签: android android-service android-notifications foreground foregroundnotification