Служба Foreground для обновления местоположения в Oreo + не работает - PullRequest
0 голосов
/ 12 июня 2019

Мое приложение требует, чтобы пользователи регулярно отслеживались.это мой класс обслуживания местоположения, предназначенный для предоставления обновлений местоположения в заданном интервале.этот код работает нормально до нуга, но не работает от Oreo.Этот код работал нормально несколько дней назад, не зная, что пошло не так.Предложения и отзывы приветствуются.

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        startMyOwnForeground();
    else{
        startForeground(1, createNotification());}
    getLocationUpdates();
    thread = new LocationMonitoringThread();
    thread.start();
    mLocationCallback = new LocationCallback(){
        @Override
        public void onLocationResult(LocationResult locationResult) {
            sendNewLocationBroadcast(locationResult);
        }
    };

    return START_STICKY;
}

private void startMyOwnForeground() {

    String CHANNEL_ID = "my_channel_01";
    CharSequence name = "Project U";
    String Description = "You are being Monitored";

    int NOTIFICATION_ID = 234;

    NotificationManager notificationManager = (NotificationManager) 
getSystemService(Context.NOTIFICATION_SERVICE);


    if (android.os.Build.VERSION.SDK_INT >= 
android.os.Build.VERSION_CODES.O) {

        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, 
name, importance);
        mChannel.setDescription(Description);
        mChannel.setVibrationPattern(new long[]{ 0 });
        mChannel.enableVibration(true);
        if (notificationManager != null) {

            notificationManager.createNotificationChannel(mChannel);
        }

    }

    NotificationCompat.Builder builder = new 
NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentText("You Are being Monitored")
            .setSmallIcon(R.drawable.ic_baseline_satellite_24px)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(true);
    builder.setOngoing(true);

    if (notificationManager != null) {

        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }

}


private void getLocationUpdates() {

    mLocationProviderClient = 
LocationServices.getFusedLocationProviderClient(this);

    mLocationRequest = new LocationRequest();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(900000);
    mLocationRequest.setFastestInterval(20000);

}

private void sendNewLocationBroadcast(LocationResult result){

    Log.i(TAG, "sendNewLocationBroadcast: ");

    Intent intent = new Intent("com.example.projectu.LocationService");

    double latitude = result.getLastLocation().getLatitude();
    double longtitude = result.getLastLocation().getLongitude();
    int complete = 1;
    Log.d(TAG, "date: " + latitude);
    Log.d(TAG, "date: " + longtitude);
    intent.putExtra("latitude", latitude);
    intent.putExtra("longtitude", longtitude);
    intent.putExtra("complete", complete);
    sendBroadcast(intent);
    FirebaseApp.initializeApp(this);

    if (FirebaseAuth.getInstance().getCurrentUser() != null) {
        uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    }
    adb = FirebaseFirestore.getInstance();
    Map<String, Object> att = new HashMap<>();
    att.put("Location", (new GeoPoint(latitude, longtitude)));
    att.put("latestUpdateTimestamp", FieldValue.serverTimestamp());
    adb.collection("Users").document(uid + "")
            .update(att);
}


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

private Notification createNotification(){
    String CHANNEL_ID = "my_channel_01";
    NotificationCompat.Builder builder = new 
NotificationCompat.Builder(this,
            CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_baseline_satellite_24px)
            .setContentTitle("Project U")
            .setContentText("You are being Monitored")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    builder.setOngoing(true);
    return builder.build();

}

class LocationMonitoringThread extends Thread{

    Looper looper;

    @Override
    public void run() {
        if (ActivityCompat.checkSelfPermission(LocationService.this, 
Manifest.permission.ACCESS_FINE_LOCATION) != 
PackageManager.PERMISSION_GRANTED) {
             return;
        }
        getLocationUpdates();
        looper = Looper.myLooper();
        looper.prepare();
        mLocationProviderClient.requestLocationUpdates(
                mLocationRequest,
                mLocationCallback,
                looper
        );

        looper.loop();
    }

  }

}

1 Ответ

0 голосов
/ 13 июня 2019

Вот две распространенные ловушки с сервисами переднего плана в Android> = O:

1.Вы запрашивали разрешение службы Foreground Service?См. здесь :

Примечание. Приложения, предназначенные для Android 9 (уровень API 28) или выше и использующие службы переднего плана, должны запрашивать разрешение FOREGROUND_SERVICE.Это нормальное разрешение, поэтому система автоматически предоставляет его запрашивающему приложению.

Если приложение с целевым уровнем API 28 или выше пытается создать службу переднего плана без запроса FOREGROUND_SERVICE, система выдает исключение SecurityException.

2.Вы запустили службу, используя Context.startForegroundService()?

Если приложению необходимо создать службу переднего плана, приложение должно вызвать startForegroundService ().Этот метод создает фоновый сервис, но метод сигнализирует системе, что сервис будет продвигаться на передний план.Как только служба создана, она должна вызвать метод startForeground () в течение пяти секунд.

Пример кода из одного из моих проектов, чтобы убедиться, что вызывается правильный метод для запуска службы:

Intent i = new Intent(context, MyService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(i);
} else {
    context.startService(i);
}
...