0

Hey I m going to develop an location tracker app in which, this app in client device which constantly send it location to the firebase db. Here the problem is that it will send the data to firebase only first 3 minutes then it wont. I don't know whats happening. ? For that even i put a log message that log message is printed perfectly even after three minutes Any one please help on this........! Here i attached 3 file One BackgroundLocation: Which is the service in background which will extract the device location and call the LocationReceiver which extends broadcast receiver where it will print log message and send the data to firebase through FBSender.

Thanks in advance

BackgroundLocation.java Which runs in Background to get the location details and call the broadcast Reveiver. LocationReveiver.java

 /**
 * Created by geekyint on 1/7/16.
 */
public class BackgroundLocation extends Service implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

IBinder mBinder = new LocalBinder();

private GoogleApiClient mGoogleApiClient;
private PowerManager.WakeLock mWakeLock;
private LocationRequest mlocationRequest;

//Flag for boolean request
private boolean mInProgress;

private boolean serviceAvailabe = false;

public class LocalBinder extends Binder {
    public BackgroundLocation getServerInstance() {
        return BackgroundLocation.this;
    }
}

@Override
public void onCreate() {
    super.onCreate();
    mInProgress = false;

    //Create the lcoation request object
    mlocationRequest = LocationRequest.create();

    //Use the acurecy
    mlocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    //The  INTERVAL
    mlocationRequest.setInterval(Constants.UPDATE_INTERVAL);

    //The FAST INTERVAL
    mlocationRequest.setFastestInterval(Constants.FAST_INTERVAL);

    serviceAvailabe = serviceConnected();

    setUpALocationClientIfNeeded();

    ComponentName receiver = new ComponentName(this, LocationReceiver.class);
    PackageManager pm = this.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
    /*ComponentName receiver1 = new ComponentName(this, FireBaseSender.class);
    PackageManager pm1 = this.getPackageManager();
    pm1.setComponentEnabledSetting(receiver1,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);*/
}

private void setUpALocationClientIfNeeded() {
    if (mGoogleApiClient == null) {
        buildGoogleApiClient();
    }
}

//Create the new Connection to the client
private void buildGoogleApiClient() {
    this.mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addOnConnectionFailedListener(this)
            .addConnectionCallbacks(this)
            .addApi(LocationServices.API)
            .build();
}

private boolean serviceConnected() {
    //Check the google Play service availibility
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

    //IF AVAILABLE
    if (resultCode == ConnectionResult.SUCCESS) {
        return true;
    } else {
        return false;
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);

    PowerManager mgr = (PowerManager) getSystemService(Context.POWER_SERVICE);

    if (this.mWakeLock == null) {
        this.mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
    }
    if (!this.mWakeLock.isHeld()) {
        this.mWakeLock.acquire();
    }

    if (!serviceAvailabe || mGoogleApiClient.isConnected() || mInProgress) {
        return START_STICKY;
    }

    setUpALocationClientIfNeeded();

    if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting() || !mInProgress) {
       // appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Started", Constants.LOG_FILE);
        mInProgress = true;
        mGoogleApiClient.connect();
    }
    return START_STICKY;
}

@Override
public void onLocationChanged(Location location) {
    String msg = Double.toString(location.getLatitude()) + "," +
            Double.toString(location.getLongitude());
    Log.d("debug", msg);
    // Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
  //  appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ":" + msg, Constants.LOCATION_FILE);
}

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

public String getTime() {
    SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return mDateFormat.format(new Date());
}

public void appendLog(String text, String filename) {
    File logFile = new File(filename);
    if (!logFile.exists()) {
        try {
            logFile.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    try {
        //BufferedWriter for performance, true to set append to file flag
        BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
        buf.append(text);
        buf.newLine();
        buf.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
public void onDestroy() {
    // Turn off the request flag
    this.mInProgress = false;

    if (this.serviceAvailabe && this.mGoogleApiClient != null) {
        this.mGoogleApiClient.unregisterConnectionCallbacks(this);
        this.mGoogleApiClient.unregisterConnectionFailedListener(this);
        this.mGoogleApiClient.disconnect();
        // Destroy the current location client
        this.mGoogleApiClient = null;
    }
    // Display the connection status
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ":
    // Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();

    if (this.mWakeLock != null) {
        this.mWakeLock.release();
        this.mWakeLock = null;
    }
//        appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Stopped", Constants.LOG_FILE);


    ComponentName receiver = new ComponentName(this, LocationReceiver.class);
    PackageManager pm = this.getPackageManager();
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    /*
    ComponentName receiver1 = new ComponentName(this, FireBaseSender.class);
    PackageManager pm1 = this.getPackageManager();
    pm1.setComponentEnabledSetting(receiver1,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);*/
    super.onDestroy();
}

/*
 * Called by Location Services when the request to connect the
 * client finishes successfully. At this point, you can
 * request the current location or start periodic updates
 */
@Override
public void onConnected(Bundle bundle) {

    // Request location updates using static settings
    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;
    }
    Intent intent  = new Intent (this, LocationReceiver.class);

    PendingIntent pendingIntent = PendingIntent
            .getBroadcast(this, 54321, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    LocationServices.FusedLocationApi.requestLocationUpdates(this.mGoogleApiClient,
            mlocationRequest, pendingIntent);

}

/*
 * Called by Location Services if the connection to the
 * location client drops because of an error.
 */
@Override
public void onConnectionSuspended(int i) {
    // Turn off the request flag
    mInProgress = false;
    // Destroy the current location client
    mGoogleApiClient = null;
    // Display the connection status
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
   // appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected", Constants.LOG_FILE);
}

/*
 * Called by Location Services if the attempt to
 * Location Services fails.
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    mInProgress = false;

    /*
     * Google Play services can resolve some errors it detects.
     * If the error has a resolution, try sending an Intent to
     * start a Google Play services activity that can resolve
     * error.
     */
    if (connectionResult.hasResolution()) {

        // If no resolution is available, display an error dialog
    } else {

    }
}

}

Here The LocationReceiver Code:

public class LocationReceiver extends BroadcastReceiver {

private String TAG = this.getClass().getSimpleName();

private LocationResult mLocationResult;
private double latitude;
private double longitude;
private double speed;
private String time;

@Override
public void onReceive(Context context, Intent intent) {
    // Need to check and grab the Intent's extras like so
    if(LocationResult.hasResult(intent)) {
        this.mLocationResult = LocationResult.extractResult(intent);

        //new SaveToFireB().insertToFireBase(mLocationResult.getLastLocation());

        new FBSender().put(mLocationResult.getLastLocation());

        Log.i(TAG, "Location Received: " + this.mLocationResult.toString());
        String msg = String.valueOf(mLocationResult.getLastLocation().getLongitude()) + "  " +
                    String.valueOf(mLocationResult.getLastLocation().getLatitude());

       // appendLog(DateFormat.getDateTimeInstance().format(new Date()) + ":" + msg, Constants.LOCATION_FILE);

    }

}

public void appendLog(String text, String filename) {
    File logFile = new File(filename);
    if (!logFile.exists()) {
        try {
            logFile.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    try {
        //BufferedWriter for performance, true to set append to file flag
        BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
        buf.append(text);
        buf.newLine();
        buf.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

Here Which will call FBSender to send the data to firebase. Ther real problems comes here. It will send the data only in first three minutes then it wont send the data to firebase For confirmation whether the control going there or not i put log message there that log message will be printed perfectly even after 3 minutes from the start of the app

Here is FBSender.Java

public class FBSender extends Service {
private String TAG = "FBSender";
private double latitude;
private double longitude;
private double speed;
private String time;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    return super.onStartCommand(intent, flags, startId);
}

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

public void put (Location location) {

    latitude = location.getLatitude();
    longitude = location.getLongitude();
    speed = location.getSpeed();
    time = DateFormat.getTimeInstance().format(new Date());

    Log.e(TAG, "Entering the run ()");

    final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    final DatabaseReference reference = database.getReference("users/" + user.getUid() + "/vehicles");
    Log.e(TAG, "I M in the middle");
    Map mLocations = new HashMap();
    mLocations.put("latitude", latitude);
    mLocations.put("longitude", longitude);
    mLocations.put("speed", speed);
    mLocations.put("time", time);

    reference.setValue(mLocations);

    Log.e(TAG, "Exiting The run ()");

}
}
Sudarshan
  • 363
  • 1
  • 9

1 Answers1

0

To get more information about why the database writes are not completing after 3 minutes, add a CompetionListener to your setValue():

reference.setValue(mLocations, new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        if (databaseError == null) {
            Log.i(TAG, "onComplete: OKAY");
        } else {
            Log.e(TAG, "onComplete: FAILED " + databaseError.getMessage());
        }
    }
});

When you hit the 3 minute mark, if the callback fires with an error, such as permission failure, you can investigate why. If it stops firing at all, that probably means you've lost connection with the Firebase server. You can monitor the connection status using a listener, as described in the documentation.

Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
  • Hey, Thanks, I even did what you had suggested, but Till 3 minutes it will print 07-06 23:08:41.972 10540-10540/com.geekyint.instapo I/FBSender: onComplete: OKAY after 3 minutes it wont prints anything i.e databaseError message, I think it wont go for else part – Sudarshan Jul 06 '16 at 17:43
  • Sounds like you lose connection at 3 minutes. – Bob Snyder Jul 06 '16 at 17:53
  • How can i refresh the connection? – Sudarshan Jul 06 '16 at 20:15
  • You shouldn't have to. It should remain connected, if needed. Try enabling DEBUG logs using [FirebaseDatabase.setLogLevel()](https://developers.google.com/android/reference/com/google/firebase/database/FirebaseDatabase). The debug log messages include a lot of information about connection status. – Bob Snyder Jul 06 '16 at 20:36
  • Although your symptoms are not identical to [this other issue](http://stackoverflow.com/questions/37575093/firebase-android-regularly-losing-database-connection), you might want to look at it for ideas. – Bob Snyder Jul 06 '16 at 21:38
  • If you enable Firebase debug logging and post the logcat output, I'll take a look at it. Please understand that your problem could have many different causing including the version of Firebase you are using, the Android version, the phone, your network configuration, etc. People cannot help you without more information about your setup and log message output. I have run your code on my phone for 10+ minutes and not seen the problem. – Bob Snyder Jul 07 '16 at 17:42
  • Okay thanks for the help. Yeah i had enabled . and will post it soon – Sudarshan Jul 07 '16 at 18:16
  • LogCat was too large how can i post – Sudarshan Jul 07 '16 at 18:31