本文介绍了Android:Firebase更新问题当应用程序处于后台时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿我要开发一个位置跟踪器应用程序,其中,此应用程序在客户端设备中不断将其位置发送到firebase数据库。
这里的问题是它只会在前3分钟将数据发送到firebase,然后就不会了。我不知道发生了什么事。 ?
为此,即使我发了一条日志消息,即使在三分钟后也能完美地打印日志消息
任何人请帮助这个........!
这里我附上了3个文件一个BackgroundLocation:后台的服务是提取设备位置并调用LocationReceiver,它扩展了广播接收器,它将打印日志消息并通过FBSender将数据发送到firebase。

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 minutesAny 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.

提前致谢

BackgroundLocation.java
哪个在后台运行以获取位置详细信息并呼叫广播Reveiver。 LocationReveiver.java

BackgroundLocation.javaWhich 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 {

    }
}

}

这里LocationReceiver代码:

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

这里将调用FBSender将数据发送到firebase。
真正的问题来自这里。
它将仅在前三分钟发送数据然后它不会将数据发送到firebase
为了确认控制是否在那里我将日志消息放在那里即使在3之后也会完美地打印日志消息从应用程序开始的分钟

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 firebaseFor 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

这是FBSender.Java

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 ()");

}
}


推荐答案

要获取有关3分钟后数据库写入原因未完成的详细信息,请添加到你的setValue():

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

当你达到3分钟标记时,如果回调触发错误,例如权限失败,你可以调查原因。如果它根本停止触发,则可能意味着您已失去与Firebase服务器的连接。您可以使用监听器监控连接状态,如。

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.

这篇关于Android:Firebase更新问题当应用程序处于后台时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 02:07