0

I have to run a service continuously until my app is uninstalled, In this service I have to send lat long values continuously for every one min

The problem is my service is running properly only for few days after that it is destroying am not getting where I did mistake

my Activity..........

Am calling my service using alarm manager

public void SrartService() {

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent alarmIntent = new Intent(MAinActivity.this, BootReciver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(MAinActivity.this, 7, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        Calendar StartTime = Calendar.getInstance();
        Log.d("trackin", "tracking here");
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, StartTime.getTimeInMillis(), 1000 * 60 * 60, pendingIntent);

}

.......my BootReciver

public void onReceive(Context context, Intent intent) {
       ...
    context.startService(new Intent(context,LongService.class));
..}

My LongService................

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Log.d("first launch", "first oncreate launch");
        dbHandler = new DbHandler(LongService.this);
        buildGoogleApiClient();
        createLocationRequest();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }


    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        Toast.makeText(getBaseContext(), "KiteEye Tracking is Destroyed Please Open it Again ", Toast.LENGTH_SHORT).show();
        super.onDestroy();
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);


        SharedPreferences bb = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
        Saved_Vehicle_ID = bb.getString("VehicleId", "");
        VehicleName = bb.getString("VehicleName", "");
        handler.postDelayed(new Runnable() {
            public void run() {
                Count = Count + 1;
                insertDB(str1, str2, date);
                if (isConnectingToInternet(LongService.this)) {
                    SendOfflineLatLongToServer();
                }
                Log.e(TAG, "count" + Count);
                Log.e(TAG, "(running.!!!!!!!)" + Saved_Vehicle_ID + Saved_interval);
                Log.e(TAG, "(Cuurent location.!!!!!!!)" + Current_Address + Saved_interval);

                if (Count >=60) {
                    Log.e(TAG, "count reached to Maximum ");
                    if(Current_Address!=null) {
                        if (date1 != null) {
                            sendMessageToActivity(getApplicationContext(), Current_Address, date1);
                            KeyguardManager km = (KeyguardManager) getApplicationContext()
                                    .getSystemService(Context.KEYGUARD_SERVICE);
                            final KeyguardManager.KeyguardLock kl = km
                                    .newKeyguardLock("MyKeyguardLock");
                            kl.disableKeyguard();
                            PowerManager pm = (PowerManager) getApplicationContext()
                                    .getSystemService(Context.POWER_SERVICE);
                            PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
                                    | PowerManager.ACQUIRE_CAUSES_WAKEUP
                                    | PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
                            wakeLock.acquire();
                            Count = 0;
                        }
                    }
                }
                sendMessageToActivity(getApplicationContext(), Current_Address, date1);
                handler.postDelayed(this, 60000);
            }
        }, 60000);
    }

    private static void sendMessageToActivity(Context context, String loc, String time) {
        Intent intent = new Intent("CurrentLocation");
        Bundle b = new Bundle();
        b.putString("Location", loc);
        b.putString("Time", time);
        intent.putExtra("Location", b);
        intent.putExtra("Time", b);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    }

    private void insertDB(String str1, String str2, String date) {
        ...
    }

    String S_id, S_lat, S_lon, S_time;

    private void SendOfflineLatLongToServer() {
       ...
    }

    public void SendLatLongToServer(final String _mid, final String lat, final String lon, final String time) {
        ...

    }

    public static boolean isConnectingToInternet(Context _context) {
        .....
    }

    public synchronized void buildGoogleApiClient() {
       ...
    }

    /**
     * Creating location request object
     */
    public void createLocationRequest() {
      ..
    }

    protected void startLocationUpdates() {

      ..
    }

    /**
     * Stopping location updates
     */
    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
    }

    /**
     * Google api callback methods
     */
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
                + result.getErrorCode());
    }

    @Override
    public void onConnected(Bundle arg0) {

       ..
    }

    @Override
    public void onConnectionSuspended(int arg0) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        // Assign the new location
        mLastLocation = location;
        // Displaying the new location on UI
        displayLocation();


    }

    private void displayLocation() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mLastLocation = LocationServices.FusedLocationApi
                .getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) {
            double latitude = mLastLocation.getLatitude();
            double longitude = mLastLocation.getLongitude();
            Geocoder geocoder;
            List<Address> addresses;
            geocoder = new Geocoder(this, Locale.getDefault());
            try {
                addresses = geocoder.getFromLocation(latitude, longitude, 7);
                if (addresses != null) {
                    String address = addresses.get(0).getAddressLine(0);
                    String address1 = addresses.get(0).getSubLocality();
                    String address2 = addresses.get(0).getLocality();
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(address);
                    stringBuilder.append(",");
                    stringBuilder.append(address1);
                    stringBuilder.append(",");
                    stringBuilder.append(address2);
                    Current_Address = stringBuilder.toString();

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            str1 = String.valueOf(latitude);
            str2 = String.valueOf(longitude);

            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date CuurentTime = new Date(mLastLocation.getTime());
            date = format.format(CuurentTime);

            DateFormat format1 = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
            Date CuurentTime1 = new Date(mLastLocation.getTime());
            date1 = format1.format(CuurentTime1);
            Log.d(TAG, "location" + str1 + "\t" + str2);
            Log.d(TAG, "location" + "date and time" + date);

            app_preferences = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
            editor = app_preferences.edit();
            editor.putString("date", date);
            editor.putString("CurrentAddress", Current_Address);
            editor.commit();


            MyApplication.getInstance().getPrefManager().setTime(date);
            MyApplication.getInstance().getPrefManager().setCurrentLocation(Current_Address);
//            if (Count==0) {
//                sendMessageToActivity(getApplicationContext(), Current_Address, date);
//            }
        } else {
            Log.e(TAG, "(Couldn't get the location. Make sure location is enabled on the device)");
        }
    }
    private void displayLocation1() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mLastLocation = LocationServices.FusedLocationApi
                .getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) {
            double latitude = mLastLocation.getLatitude();
            double longitude = mLastLocation.getLongitude();
            str1 = String.valueOf(latitude);
            str2 = String.valueOf(longitude);
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date CuurentTime = new Date(mLastLocation.getTime());
            date = format.format(CuurentTime);
            Log.d(TAG, "loc" + str1 + "\t" + str2);
            Log.d(TAG, "loc" + "date & time" + date);
            insertDB(str1, str2, date);

        } else {
            Log.e(TAG, "(Couldn't get the location. Make sure location is enabled on the device)");
        }
    }
    public void removeDB(String id) {
  ...
}
Kaushik
  • 6,150
  • 5
  • 39
  • 54
Divya
  • 1
  • 4
  • testing on a samsung device? – Tim Jan 17 '17 at 09:48
  • are you sure it is working for few days and then it stopped? @Divya – Pratik Dasa Jan 17 '17 at 09:54
  • yeah am sure its working for few days later the service is destroying – Divya Jan 17 '17 at 09:56
  • Service basically eats lots of memory of device so android anytime can stop it by itself, you have to restart it everytime if its not running, check if its running or not and if not then restart it from every activity. Visit this link may be it should help you: http://stackoverflow.com/questions/16514724/why-does-the-background-service-stops-while-running – Pratik Dasa Jan 17 '17 at 09:58
  • visited the link? @Divya – Pratik Dasa Jan 17 '17 at 10:09
  • how to check whether service is running continuously after few days ,how to restart it again in my activity, when i open my app my service is running as usually,am using samsung tab(23) – Divya Jan 17 '17 at 10:17
  • Have you checked the logcat? Does your Service crash? – David Wasser Jan 17 '17 at 11:15

1 Answers1

0

As @PratikDasa pointed out, Android might clean up long running background services from time to time to reclaim system resources. So if you need to continuously run the service in the background, implement the method onStartCommand. Cut the complete code from your current onStart method and put in onStartCommand (OnStart has been deprecated long back.). onStartCommand must return a value and this is where the trick is. Return START_STICKY from it. You can read more about this constant in Android Service API

When you return START_STICKY from onStartCommand, you basically ask Android system to explicitly restart your service after every time it is stopped. Now there are few caveats which you can read upon on the above link. The most important thing among all the caveats is that, when the system explicitly restarts your service, the delivered intent might be NULL (unless there are some intent pending to start the service), and as such you should handle them accordingly in your code.

Make these changes and do some basic testing. I hope things should be working fine.

Dibzmania
  • 1,934
  • 1
  • 15
  • 32
  • tq fr ur help@PratikDasa.i will try to solve my pblm with this knowledge. – Divya Jan 17 '17 at 10:25
  • its okay @Divya you can ask me anytime without hesitation. You can contact me on my email id if you want. – Pratik Dasa Jan 17 '17 at 10:28
  • If the above solution works for you, do tag this as the answer here for future references for fellow SO mates – Dibzmania Jan 17 '17 at 10:58
  • Again my service kills by its self after few days!! suggest some solutions plz – Divya Jan 24 '17 at 08:04
  • If you have mentioned the service as Sticky, it would be restarted. Please note that mentioning the service as sticky, does not prevent it from killed but it ensures that it will be restarted once killed. – Dibzmania Jan 24 '17 at 12:51