后台

时间:2018-04-03 21:28:16

标签: android firebase firebase-realtime-database kotlin

我必须在某段时间内将firebase数据库保存到当前位置,这不仅在我的应用程序正在运行时,而且在关闭时也是如此。现在我使用firebase作业调度程序来完成它。

    class App : Application(){
    private val TAG = App::class.java.simpleName
    override fun onCreate() {
        Log.i("App", "App onCreate")
        super.onCreate()
        var mAuthListener = FirebaseAuth.AuthStateListener { firebaseAuth ->
            val user = firebaseAuth.currentUser
            if (user != null) {
                Log.i(TAG,"user log in")

                try {
                    val dispatcher2 = FirebaseJobDispatcher(GooglePlayDriver(applicationContext))
                    val myLocationJob = dispatcher2.newJobBuilder()
                            .setService(LocationJobService::class.java) // the JobService that will be called
                            .setTag("my-location-job")
                            .setLifetime(Lifetime.UNTIL_NEXT_BOOT)
                            // start between windowStart in sec and windowEnd in seconds from now
                            .setTrigger(Trigger.executionWindow(0, 60))
                            .setRecurring(true)//to reschedule job
                            .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
                            .setReplaceCurrent(true)
                            .build()

                    dispatcher2.mustSchedule(myLocationJob)
                    Log.i(TAG,"onCreate() started dispatcher " + dispatcher2.toString())

                } catch (scheduleFailedException: FirebaseJobDispatcher.ScheduleFailedException) {
                    Log.i(TAG, "scheduleFailedException " + scheduleFailedException)
                }

            }else{
                Log.i(TAG,"user not log in")
            }
        }
        FirebaseApp.initializeApp(applicationContext)
        FirebaseAuth.getInstance().addAuthStateListener(mAuthListener)

    }
}

我的服务类应该在期间运行:

class LocationJobService : JobService(),
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
com.google.android.gms.location.LocationListener{
    var job : JobParameters? = null
    override fun onStartJob(job: JobParameters?): Boolean {
        Log.i(TAG,"onStartJob()")
        this.job = job
        var thread = object : Thread(){
            override fun run() {
                buildGoogleApiClient()
                Log.i(TAG,"run()")
            }
        }
        thread.start()
        return true
    }
    override fun onStopJob(job: JobParameters?): Boolean {
        Log.i("TAG", "onStopJob");
        return true;
    }

    private val TAG = LocationJobService::class.java.simpleName

    var mLocationRequest: LocationRequest? = null
    var mGoogleApiClient: GoogleApiClient? = null
    var mLastLocation: Location? = null


    var mRequestLocationUpdatesPendingIntent : PendingIntent? = null
    fun buildGoogleApiClient() {
        synchronized(this) {
            Log.i(TAG, "buildGoogleApiClient")
            mGoogleApiClient = GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build()
            mGoogleApiClient!!.connect()
        }
    }

    private fun createLocationRequest() {
        Log.i(TAG, "createLocationRequest")
        mLocationRequest = LocationRequest()
        mLocationRequest!!.interval = 100
        mLocationRequest!!.fastestInterval = 100
        mLocationRequest!!.smallestDisplacement = 1F
        mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
    override fun onConnected(p0: Bundle?) {
        Log.i(TAG, "onConnected")
        createLocationRequest()
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return
        }
        Log.i(TAG, "start request locationOfUserWhoChangeIt updates ")
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this)
        // request locationOfUserWhoChangeIt updates
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                mLocationRequest,
                mRequestLocationUpdatesPendingIntent)

    }

    override fun onConnectionSuspended(p0: Int) {
        Log.i(TAG, "onConnectionSuspended")
        mGoogleApiClient!!.connect()
    }
    override fun onConnectionFailed(p0: ConnectionResult) {
        Log.i(TAG, "onConnectionFailed: google maps" + p0.errorMessage)
    }

    override fun onLocationChanged(location: Location?) {
        if (FirebaseAuth.getInstance().currentUser != null) {
            Log.i(TAG, "onLocationChanged")
            mLastLocation = location!!
            addCurrentUserLocationToFirebase(mLastLocation!!)
        }
    }

    private fun addCurrentUserLocationToFirebase(lastLocation: Location) {
        var locations = FirebaseDatabase.getInstance().getReference("Locations")
        var currentUser = FirebaseAuth.getInstance().currentUser
        if (currentUser != null) {//prevent if user click logout to not update locationOfUserWhoChangeIt
            Log.i(TAG, "addCurrentUserMarkerAndRemoveOld() current user: " + currentUser!!.uid + " location " + lastLocation.toString() )

            val scoresRef = locations.child(currentUser!!.uid)
            scoresRef.keepSynced(true)
            val connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected")
            connectedRef.addValueEventListener(object : ValueEventListener {
                override fun onDataChange(snapshot: DataSnapshot) {
                    val connected = snapshot.getValue(Boolean::class.java)!!
                    if (connected) {
                        Log.i(TAG,"connected")
                        locations.child(currentUser!!.uid)
                                .setValue(TrackingModel(currentUser.uid,
                                        currentUser!!.email!!,
                                        lastLocation.latitude.toString(),
                                        lastLocation.longitude.toString()), object : DatabaseReference.CompletionListener {
                                    override fun onComplete(error: DatabaseError?, reference: DatabaseReference?) {
                                        Log.i(TAG,"onComplete()")
                                        if(error == null){
                                            Log.i(TAG,"onComplete() position saved to firebase database")
                                            Log.i(TAG,"okey stop service")
                                            mGoogleApiClient!!.disconnect()
                                            jobFinished(job!!, false) //it must be called here, since I return true
                                        }else{
                                            Log.i(TAG,"there is problem to add data to database")
                                        }
                                    }
                                })
                    } else {
                        Log.i(TAG,"not connected")
                    }
                }
                override fun onCancelled(error: DatabaseError) {
                    System.err.println("Listener was cancelled")
                }
            })
        }
    }

    override fun onDestroy() {
        Log.i(TAG,"destroy")
        super.onDestroy()
    }

}

我有一个大问题。当我在手机中关闭应用程序时(我向左滑动我的应用程序)。我没有连接到我的firebase数据库。在我的连接监听器中,我得到了not connected。因此,CompletionListener永远不会在我无法连接时运行。当我们关闭应用程序时,我读取了firebase连接已关闭。那么当我的应用程序没有运行时,如何连接到我的firebase数据库以添加我当前的位置?

我知道我可以运行前台服务但在某些设备中它也可以被系统杀死。所以我想在一段时间内安排我的服务,但我不知道如何连接到我的firebase数据库。

0 个答案:

没有答案