Фоновая служба не останавливается Android - PullRequest
1 голос
/ 12 марта 2020

У меня есть фоновые службы, которые фиксируют местоположение с устройства пользователя, но когда я прекращаю его с помощью метода stopService из-за другой активности, он не останавливается, и из-за этого приложение вылетает, поскольку приложение не может отправить широту на сервер .

Примечание. У меня есть запрос на переоснащение, отправляемый на сервер, когда местоположение не равно нулю, а также когда я нажимаю кнопку остановки службы в основной операции, уведомление исчезает с устройства, но фактически с службы не останавливается и местоположение регистрируется в logcat. Но он не публикуется на сервере из-за ошибки тайм-аута и сбоя приложения.

Вот класс обслуживания:

public class LiveLocationService extends Service {
    private static final String TAG = LiveLocationService.class.getSimpleName();
    Retrofit retrofitClient;
    CompositeDisposable compositeDisposable = new CompositeDisposable();
    MyService myService;
    String empCode, year, month, date;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        retrofitClient = RetrofitClient.getInstance();
        myService = retrofitClient.create(MyService.class);

        empCode = intent.getStringExtra("empCode");
        year = intent.getStringExtra("year");
        month = intent.getStringExtra("month");
        date = intent.getStringExtra("date");
        return super.onStartCommand(intent, flags, startId);
    }

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

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onCreate() {
        super.onCreate();
        buildNotification();
        requestLocationUpdates();
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void buildNotification() {
        String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
        String channelName = "My Background Service";
        NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        assert manager != null;
        manager.createNotificationChannel(chan);

        PendingIntent intent = PendingIntent.getActivity(this, 0,  new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
        Notification notification = notificationBuilder.setOngoing(true)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentTitle("Service is tracking your location.")
                .setPriority(NotificationManager.IMPORTANCE_HIGH)
                .setCategory(Notification.CATEGORY_SERVICE)
                .setContentIntent(intent)
                .build();
        startForeground(2, notification);

    }

    private void requestLocationUpdates() {
        LocationRequest request = new LocationRequest();
        request.setInterval(10000);
        request.setFastestInterval(5000);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
        int permission = ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION);
        if (permission == PackageManager.PERMISSION_GRANTED) {
                client.requestLocationUpdates(request, new LocationCallback() {
                    @Override
                    public void onLocationResult(LocationResult locationResult) {
                        Location location = locationResult.getLastLocation();
                        if (location != null) {
                            Log.d(TAG, "location update " + location);
                            double lat = location.getLatitude();
                            double lon = location.getLongitude();
                            final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
                            compositeDisposable.add(myService.userLocation(empCode, year, month, date, time, lat, lon)
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Consumer< String >() {
                                        @Override
                                        public void accept(String s) throws Exception {
                                            Log.e("data", s);
                                            if (s.equals("\"done\"")) {
                                                Log.e("status", "location punched");
                                            }
                                        }
                                    }));
                        } else {
                            Log.d("MSER", "location update, no location found. ");
                        }
                    }
                }, null);
        } else {
            Log.e("MSER", "Please enable location.");
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);
        stopSelf();
    }
}

Вот HomeActivity.

public class HomeActivity extends AppCompatActivity {

    String empCode, name;
    private TextView code, displayName;
    private Button punchInBtn, punchOutBtn;
    CompositeDisposable compositeDisposable = new CompositeDisposable();
    MyService myService;
    private Toolbar toolbar;
    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor;
    private static final String SHARED_PREFS = "sharedPrefs";
    private static final int PERMISSIONS_REQUEST = 1;
    LiveLocationService liveLocationService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("Management Services");
        toolbar.setTitleTextColor(getResources().getColor(R.color.white));
        toolbar.setOverflowIcon(getResources().getDrawable(R.drawable.menu));

        Retrofit retrofitClient = RetrofitClient.getInstance();
        myService = retrofitClient.create(MyService.class);

        code = findViewById(R.id.code);
        displayName = findViewById(R.id.name);
        punchInBtn = findViewById(R.id.punchIn);
        punchOutBtn = findViewById(R.id.punchOut);

        empCode = getIntent().getStringExtra("empCode");
        name = getIntent().getStringExtra("name");

        code.setText(empCode);
        displayName.setText(name);

        final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
        final String year = date.substring(0, 4);
        final String month = date.substring(5, 7);
        final String dateToday = date.substring(8, 10);

        punchInBtn.setVisibility(View.INVISIBLE);
        punchOutBtn.setVisibility(View.INVISIBLE);


        compositeDisposable.add(myService.userStatus(empCode)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer< String >() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.e("data", s);
                        if (s.equals("logout")) {
                            Toast.makeText(HomeActivity.this, s, Toast.LENGTH_SHORT).show();
                        } else {
                            JSONObject basicObject = new JSONObject(s);
                            JSONArray attendanceArray = basicObject.getJSONArray("attendance");

                            ArrayList< String > toAdd = new ArrayList<>();

                            if (attendanceArray.length() > 0) {
                                for (int i = 0; i < attendanceArray.length(); i++) {
                                    JSONObject attendanceObject = attendanceArray.getJSONObject(i);
                                    String yearName = attendanceObject.getString("year");
                                    String monthName = attendanceObject.getString("month");
                                    String dateName = attendanceObject.getString("date");
                                    boolean loginStatus = attendanceObject.getBoolean("loginStatus");
                                    if (yearName.equals(year) && monthName.equals(month) && dateName.equals(dateToday) && loginStatus) {
                                        punchInBtn.setVisibility(View.INVISIBLE);
                                        punchOutBtn.setVisibility(View.VISIBLE);
                                        return;
                                    } else {
                                        toAdd.add("punch in");
                                    }
                                }
                                if (toAdd.contains("punch in")) {
                                    punchInBtn.setVisibility(View.VISIBLE);
                                    punchOutBtn.setVisibility(View.INVISIBLE);
                                }
                            } else {
                                punchInBtn.setVisibility(View.VISIBLE);
                            }
                        }
                    }
                }));

        punchInBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Check GPS is enabled
                LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
                if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                    Toast.makeText(HomeActivity.this, "Please enable location services", Toast.LENGTH_SHORT).show();
                    finish();
                }

                // Check location permission is granted - if it is, start
                // the service, otherwise request the permission
                int permission = ContextCompat.checkSelfPermission(HomeActivity.this,
                        Manifest.permission.ACCESS_FINE_LOCATION);
                if (permission == PackageManager.PERMISSION_GRANTED) {

                    final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
                    final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
                    final String year = date.substring(0, 4);
                    final String month = date.substring(5, 7);
                    final String dateToday = date.substring(8, 10);

                    compositeDisposable.add(myService.userStatus(empCode)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new Consumer< String >() {
                                @Override
                                public void accept(String s) throws Exception {
                                    Log.e("data", s);
                                    if (s.equals("logout")) {
                                        Toast.makeText(HomeActivity.this, s, Toast.LENGTH_SHORT).show();
                                    } else {
                                        JSONObject basicObject = new JSONObject(s);

                                        String inTime = basicObject.getString("inTime");
                                        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
                                        Date finalInTime = df.parse(inTime);
                                        Calendar cal = Calendar.getInstance();
                                        cal.setTime(finalInTime);
                                        cal.add(Calendar.MINUTE, 15);
                                        String newTime = df.format(cal.getTime());

                                        String[] timeDivide = time.split(":");
                                        String[] newTimeDivide = newTime.split(":");

                                        int timeHour = Integer.parseInt(timeDivide[0]);
                                        int timeMin = Integer.parseInt(timeDivide[1]);

                                        int newTimeHour = Integer.parseInt(newTimeDivide[0]);
                                        int newTimeMin = Integer.parseInt(newTimeDivide[1]);

                                        String status = "";

                                        if (timeHour > newTimeHour) {
                                            Log.e("status", "Your are late");
                                            status = "Late";
                                        } else if (timeHour == newTimeHour) {
                                            if (timeMin > newTimeMin) {
                                                Log.e("status", "Your are late");
                                                status = "Late";
                                            } else {
                                                Log.e("status", "You are on time");
                                                status = "On Time";
                                            }
                                        } else {
                                            Log.e("status", "You are on time");
                                            status = "On Time";
                                        }

                                        ArrayList< String > toAdd = new ArrayList<>();

                                        JSONArray attendanceArray = basicObject.getJSONArray("attendance");
                                        if (attendanceArray.length() > 0) {
                                            for (int i = 0; i < attendanceArray.length(); i++) {
                                                JSONObject attendanceObject = attendanceArray.getJSONObject(i);
                                                String yearName = attendanceObject.getString("year");
                                                String monthName = attendanceObject.getString("month");
                                                String dateName = attendanceObject.getString("date");
                                                boolean loginStatus = attendanceObject.getBoolean("loginStatus");
                                                if (yearName.equals(year) && monthName.equals(month) && dateName.equals(dateToday) && !loginStatus) {
                                                    Log.e("status", "add new inTime.");
                                                    compositeDisposable.add(myService.userPunchInExisting(empCode, year, month, dateToday, time, status)
                                                            .subscribeOn(Schedulers.io())
                                                            .observeOn(AndroidSchedulers.mainThread())
                                                            .subscribe(new Consumer< String >() {
                                                                @Override
                                                                public void accept(String s) throws Exception {
                                                                    Log.e("data", s);
                                                                    if (s.equals("\"done\"")) {
                                                                        startTrackerService();
                                                                        punchInBtn.setVisibility(View.INVISIBLE);
                                                                        punchOutBtn.setVisibility(View.VISIBLE);
                                                                    }
                                                                }
                                                            }));
                                                    return;
                                                } else {
                                                    toAdd.add("add new attendance");
                                                }
                                            }
                                            if (toAdd.contains("add new attendance")) {
                                                Log.e("status", "add new attendance");
                                                compositeDisposable.add(myService.userPunchInNew(empCode, year, month, dateToday, time, status)
                                                        .subscribeOn(Schedulers.io())
                                                        .observeOn(AndroidSchedulers.mainThread())
                                                        .subscribe(new Consumer< String >() {
                                                            @Override
                                                            public void accept(String s) throws Exception {
                                                                Log.e("data", s);
                                                                if (s.equals("\"done\"")) {
                                                                    startTrackerService();
                                                                    punchInBtn.setVisibility(View.INVISIBLE);
                                                                    punchOutBtn.setVisibility(View.VISIBLE);
                                                                }
                                                            }
                                                        }));
                                            }

                                        } else {
                                            Log.e("status", "add new attendance.");
                                            compositeDisposable.add(myService.userPunchInNew(empCode, year, month, dateToday, time, status)
                                                    .subscribeOn(Schedulers.io())
                                                    .observeOn(AndroidSchedulers.mainThread())
                                                    .subscribe(new Consumer< String >() {
                                                        @Override
                                                        public void accept(String s) throws Exception {
                                                            Log.e("data", s);
                                                            if (s.equals("\"done\"")) {
                                                                startTrackerService();
                                                                punchInBtn.setVisibility(View.INVISIBLE);
                                                                punchOutBtn.setVisibility(View.VISIBLE);
                                                            }
                                                        }
                                                    }));
                                        }
                                    }
                                }
                            }));

                } else {
                    ActivityCompat.requestPermissions(HomeActivity.this,
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            PERMISSIONS_REQUEST);
                }


            }
        });


        punchOutBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                    final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
                    final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
                    final String year = date.substring(0, 4);
                    final String month = date.substring(5, 7);
                    final String dateToday = date.substring(8, 10);

                    compositeDisposable.add(myService.userStatus(empCode)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new Consumer< String >() {
                                @Override
                                public void accept(String s) throws Exception {
                                    Log.e("data", s);
                                    if (s.equals("logout")) {
                                        Toast.makeText(HomeActivity.this, s, Toast.LENGTH_SHORT).show();
                                    } else {
                                        JSONObject basicObject = new JSONObject(s);

                                        JSONArray attendanceArray = basicObject.getJSONArray("attendance");
                                        if (attendanceArray.length() > 0) {
                                            for (int i = 0; i < attendanceArray.length(); i++) {
                                                JSONObject attendanceObject = attendanceArray.getJSONObject(i);
                                                String yearName = attendanceObject.getString("year");
                                                String monthName = attendanceObject.getString("month");
                                                String dateName = attendanceObject.getString("date");
                                                boolean loginStatus = attendanceObject.getBoolean("loginStatus");
                                                if (yearName.equals(year) && monthName.equals(month) && dateName.equals(dateToday) && loginStatus) {
                                                    Log.e("status", "add new outTime.");
                                                    compositeDisposable.add(myService.userPunchOut(empCode, year, month, dateToday, time)
                                                            .subscribeOn(Schedulers.io())
                                                            .observeOn(AndroidSchedulers.mainThread())
                                                            .subscribe(new Consumer< String >() {
                                                                @Override
                                                                public void accept(String s) throws Exception {
                                                                    Log.e("data", s);
                                                                    if (s.equals("\"done\"")) {
                                                                        stopTrackerService();
                                                                        punchOutBtn.setVisibility(View.INVISIBLE);
                                                                        punchInBtn.setVisibility(View.VISIBLE);
                                                                    }
                                                                }
                                                            }));
                                                    return;
                                                }
                                            }
                                        }
                                    }
                                }
                            }));

            }
        });

    }

    private void startTrackerService() {
        final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
        final String year = date.substring(0, 4);
        final String month = date.substring(5, 7);
        final String dateToday = date.substring(8, 10);

        Intent intent = new Intent(this, LiveLocationService.class);
        intent.putExtra("empCode", empCode);
        intent.putExtra("year", year);
        intent.putExtra("month", month);
        intent.putExtra("date", dateToday);
        startService(intent);
    }

    private void stopTrackerService() {
        stopService(new Intent(this, LiveLocationService.class));

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[]
            grantResults) {
        if (requestCode == PERMISSIONS_REQUEST && grantResults.length == 1
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Start the service when the permission is granted
            startTrackerService();
        } else {
            finish();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.logout) {
            sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
            editor = sharedPreferences.edit();
            editor.remove("myKey");
            editor.remove("myKey1");
            editor.remove("myKey2");
            editor.apply();
            Intent intent = new Intent(HomeActivity.this, MainActivity.class);
            startActivity(intent);
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

}

Ответы [ 2 ]

1 голос
/ 12 марта 2020

Запустите службу, как показано ниже:

  Intent intent = new Intent(this, LiveLocationService.class);
  intent.putExtra("empCode", empCode);
  intent.putExtra("year", year);
  intent.putExtra("month", month);
  intent.putExtra("date", dateToday);
  startService(intent);

  ContextCompat.startForegroundService(this, intent)

Остановите службу, как показано ниже:

stopService(new Intent(this, LiveLocationService.class));

Метод onDestory () службы, как показано ниже:

 @Override
    public void onDestroy() {
        super.onDestroy();
        // Stop location udates
       //hide your notification here
    }
0 голосов
/ 12 марта 2020

ваша служба перестает работать, но все еще получает обратные вызовы местоположения, это означает, что вы все еще зарегистрировали обратный вызов в client.requestLocationUpdates().

, при остановке службы также удалите тот же обратный вызов из LocationProvderClient. Для этого сделайте глобальный объект LocationCallback () удалить тот же объект, когда нужно остановить. как:

LocationServices.getFusedLocationProviderClient(this).removeLocationUpdates(locationCallback);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...