当前位置: 首页 > 知识库问答 >
问题:

Oreo-在前台启动服务

裴凯定
2023-03-14

我创建了一个跟踪设备移动位置的服务。服务由绑定到它的活动启动,在该活动中有一个“开始跟踪”按钮。当按下这个按钮时,我需要服务在前台启动,这样它就可以存储设备移动到的位置,即使与它绑定的活动已经关闭,或者应用程序被最小化。

以下是我的服务:

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

共有1个答案

邹普松
2023-03-14

尝试使用以下代码更改startInForeground()方法:

private void startInForeground() {
        Intent notificationIntent = new Intent(this, WorkoutActivity.class);
        PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notificationIntent,0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this,NOTIFICATION_CHANNEL_ID)
                .setSmallIcon(R.drawable.shsl_notification)
                .setContentTitle("TEST")
                .setContentText("HELLO")
                .setTicker("TICKER") 
                .setContentIntent(pendingIntent);
        Notification notification=builder.build();
        if(Build.VERSION.SDK_INT>=26) {
            NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            channel.setDescription(NOTIFICATION_CHANNEL_DESC);
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
        startForeground(NOTIFICATION_ID, notification);
}

所以,当你的Android版本是奥利奥(或更高版本)通知通道将被创建,否则不会。

 类似资料:
  • 编辑 我的通知是这样创建的,到目前为止,它在数千个API<26的android设备上工作:

  • 如何在Android奥利奥继续后台服务而不显示通知点?我使用通知继续我的后台服务,但我不想显示运行服务的通知。

  • 问题内容: 如何在不显示通知点的情况下继续在Android Oreo中进行后台服务?我使用通知继续后台服务,但我不想显示正在运行的服务的通知。 问题答案: 如果您可以在此处的某处正确阅读 Android Oreo 8.0 文档,则可能未在此处发布此问题。 步骤1: 确保您将服务作为前台启动,如以下代码所示 步骤2: 使用通知显示您的服务正在运行。在的方法中的代码下面添加一行。 步骤3:在服务停止或

  • 问题内容: 我目前正在使用在Oreo中崩溃的startWakefulService函数。我意识到我要么必须切换到startForegroundService()并使用前台服务,要么切换到JobIntentService,但是基于下面的代码,我不确定该怎么做。(对不起,我是android新手)。正确方向的任何观点将不胜感激。 这是在Android 8.x上运行时遇到的当前错误 致命异常:java.l

  • 这是在Android8.x上运行时出现的当前错误 致命异常:java.lang.RuntimeException无法启动接收方com.heyjude.heyjudeapp.gcm.gcmbroadcastreceiver:java.lang.illegalstateException:不允许启动服务意图{act=com.google.android.c2dm.Intent.receive flg=

  • 我正在开发一个需要从后台启动前台服务的SDK。因为它使用后台定位和蓝牙相关的工作。如果应用程序被杀死,监控正在后台执行。这就是我使用前台服务的原因。有一个条件是从后台启动前台服务。 目前,我的SDK使用服务来处理此作业。但Android 12不支持从后台启动服务。 我正在尝试从以下异常引发的后台启动服务。 如何使用WorkManager解决此问题,我的所有处理都由Service类完成,以及如何将S