Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 我无休止的后台服务在几个小时后自动停止。为什么?_Android_Kotlin_Service_Background Service - Fatal编程技术网

Android 我无休止的后台服务在几个小时后自动停止。为什么?

Android 我无休止的后台服务在几个小时后自动停止。为什么?,android,kotlin,service,background-service,Android,Kotlin,Service,Background Service,我的无休止的前台服务在3到4小时后自动停止,没有任何问题吗?LatLong在服务器上连续保存了3-4个小时,但随机关闭或销毁了服务,我不知道如何处理这个问题 类MyEndlessService:Service(),DatabaseListenerCallback{ private var wakeLock: PowerManager.WakeLock? = null private var isServiceStarted = false var TAG = "MyService&qu

我的无休止的前台服务在3到4小时后自动停止,没有任何问题吗?LatLong在服务器上连续保存了3-4个小时,但随机关闭或销毁了服务,我不知道如何处理这个问题

类MyEndlessService:Service(),DatabaseListenerCallback{

private var wakeLock: PowerManager.WakeLock? = null
private var isServiceStarted = false
var TAG = "MyService"
var gps_status = 1
var editor: SharedPreferences.Editor? = null
var previousBestLocation: Location? = null
var apiInterface: GetDataService? = null
private var googleApiClient: GoogleApiClient? = null
private var lastLocation: Location? = null
private var locationRequest: LocationRequest? = null
private val UPDATE_INTERVAL = 10000
private val FASTEST_INTERVAL = UPDATE_INTERVAL / 2
var locationManager: LocationManager? = null
var isFirsttime = true
var sharedPreferences: SharedPreferences? = null

override fun onBind(intent: Intent): IBinder? {
    return null
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    log("onStartCommand executed with startId: $startId")
    if (intent != null) {
        val action = intent.action
        log("using an intent with action $action")
        when (action) {
            Actions.START.name -> startService()
            Actions.STOP.name -> stopService()
            else -> log("This should never happen. No action in the received intent")
        }
    } else {
        log(
            "with a null intent. It has been probably restarted by the system."
        )
    }
    return START_STICKY
}

override fun onCreate() {
    super.onCreate()
    log("The service has been created".toUpperCase())
    val notification = createNotification()
    startForeground(1, notification)
}

override fun onDestroy() {
    super.onDestroy()
    log("The service has been destroyed".toUpperCase())
    val calendar = Calendar.getInstance()
    val mdformat = SimpleDateFormat("HH:mm:ss")
    val strDate = mdformat.format(calendar.time)
    LocalDatabaseForException(applicationContext,strDate,"Service Destroyed").execute()
    val broadcastIntent = Intent()
    broadcastIntent.action = "restartservice"
    broadcastIntent.setClass(this, Restarter::class.java)
    this.sendBroadcast(broadcastIntent)
}

override fun onTaskRemoved(rootIntent: Intent) {
    val restartServiceIntent = Intent(applicationContext, MyEndlessService::class.java).also {
        it.setPackage(packageName)
    };
    val restartServicePendingIntent: PendingIntent = PendingIntent.getService(
        this,
        1,
        restartServiceIntent,
        PendingIntent.FLAG_ONE_SHOT
    );
    applicationContext.getSystemService(Context.ALARM_SERVICE);
    val alarmService: AlarmManager = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager;
    alarmService.set(
        AlarmManager.ELAPSED_REALTIME,
        SystemClock.elapsedRealtime() + 1000,
        restartServicePendingIntent
    );
}

private fun startService() {

    val calendar = Calendar.getInstance()
    val mdformat = SimpleDateFormat("HH:mm:ss")
    val strDate = mdformat.format(calendar.time)
    LocalDatabaseForException(applicationContext,strDate,"Service Started").execute()

    if (isServiceStarted) return
    log("Starting the foreground service task")
  //  Toast.makeText(this, "Service starting its task", Toast.LENGTH_SHORT).show()
    isServiceStarted = true
    setServiceState(this, ServiceState.STARTED)

    // we need this lock so our service gets not affected by Doze Mode
    wakeLock =
        (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
            newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "EndlessService::lock").apply {
                acquire()
            }
        }
    // we're starting a loop in a coroutine
    GlobalScope.launch(Dispatchers.IO) {
        while (isServiceStarted) {
            launch(Dispatchers.IO) {
                pingFakeServer()
                handleUserTracking()
            }
            delay(1000)
        }
        log("End of the loop for the service")
    }
}

private fun stopService() {
    log("Stopping the foreground service")
  //  Toast.makeText(this, "Service stopping", Toast.LENGTH_SHORT).show()
    val calendar = Calendar.getInstance()
    val mdformat = SimpleDateFormat("HH:mm:ss")
    val strDate = mdformat.format(calendar.time)
    LocalDatabaseForException(applicationContext,strDate,"Service Stopped").execute()
    try {
        wakeLock?.let {
            if (it.isHeld) {
               // startService()
                it.release()
            }
        }
      // stopForeground(true)
     //   stopSelf()
    } catch (e: Exception) {
        log("Service stopped without being started: ${e.message}")
        val calendar = Calendar.getInstance()
        val mdformat = SimpleDateFormat("HH:mm:ss")
        val strDate = mdformat.format(calendar.time)
        LocalDatabaseForException(applicationContext,strDate,"Service stopped without being started: ${e.message}").execute()
    }
    isServiceStarted = false
    setServiceState(this, ServiceState.STARTED)
}

private fun pingFakeServer()  {
    SmartLocation.with(applicationContext).location()
        .start(object : OnLocationUpdatedListener {

            override fun onLocationUpdated(location: Location?) {
                val sharedPreferences = applicationContext.getSharedPreferences(
                    "AcessToken",
                    AppCompatActivity.MODE_MULTI_PROCESS
                )
                editor = getSharedPreferences("AcessToken", MODE_PRIVATE).edit()
                editor = getSharedPreferences("AcessToken", MODE_PRIVATE).edit()
                editor!!.putString("temp_lattitude", location!!.getLatitude().toString())
                editor!!.putString("temp_lattitude", location!!.getLatitude().toString())
                editor!!.apply()
                val att = sharedPreferences!!.getString("Attendance_ID", "")
                val userid = sharedPreferences.getInt("User_ID", 0).toString()
                if ((att != "") and (userid != "")) {
                    if (previousBestLocation != null) {
                        if (isBetterLocation(location, previousBestLocation)) {
                            previousBestLocation = location
                            onNewLocationAgainwithLocalDatabase(location)
                        }
                    } else {
                        previousBestLocation = location
                        onNewLocationAgainwithLocalDatabase(location)
                    }



                }
            }

        })

}


fun getBatteryPercentage(context: Context): Int {
    return if (Build.VERSION.SDK_INT >= 21) {
        val bm = context.getSystemService(BATTERY_SERVICE) as BatteryManager
        bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
    } else {
        val iFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
        val batteryStatus = context.registerReceiver(null, iFilter)
        val level = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1
        val scale = batteryStatus?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1
        val batteryPct = level / scale.toDouble()
        (batteryPct * 100).toInt()
    }
}


fun handleUserTracking() {
    val settings = applicationContext.getSharedPreferences("AcessToken", MODE_PRIVATE)
    val manager = getSystemService(LOCATION_SERVICE) as LocationManager
    gps_status = 1
    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        gps_status = 0
        editor = getSharedPreferences("AcessToken", MODE_PRIVATE).edit()
        editor!!.putString("temp_lattitude", "")
        editor!!.putString("temp_longitude", "")
        editor!!.apply()
    }
 
    Log.d("Gps status ", gps_status.toString())
}

fun hitApitoUpdate(gpsstatus: Int?) {
    val settings = applicationContext.getSharedPreferences("AcessToken", MODE_PRIVATE)
    val lattitude = settings.getString("temp_lattitude", "")
    val longitude = settings.getString("temp_longitude", "")
    val userID = settings.getInt("User_ID", 0).toString()
    val access_token = settings.getString("Access_Token", "")
    val battery_per = getBatteryPercentage(this)
    apiInterface = APIClient.getClient().create(GetDataService::class.java)
    val call = apiInterface!!.updateGpsStatus(
        "Bearer $access_token",
        gpsstatus,
        userID,
        lattitude,
        longitude,
        battery_per
    )
    call.enqueue(object : Callback<GpaStatusPojo> {
        override fun onResponse(call: Call<GpaStatusPojo>, response: Response<GpaStatusPojo>) {
            try {
                // Toast.makeText(applicationContext,""+response.body()!!.message,Toast.LENGTH_SHORT).show()
                Log.d("Gps status ", response.body()!!.message)
            } catch (e: java.lang.Exception) {
                val dfgdsdsdsfds = ""
                Log.d("Gps sttaus 22 :", e.toString())
            }
        }

        override fun onFailure(call: Call<GpaStatusPojo>, t: Throwable) {
            Log.d("Gps sttaus 33 :", t.toString())
        }
    })
}




private fun onNewLocationAgainwithLocalDatabase(location: Location) {
    val calendar = Calendar.getInstance()
    val mdformat = SimpleDateFormat("HH:mm:ss")
    val strDate = mdformat.format(calendar.time)
    LocalDatabaseInsert(location, strDate, applicationContext).execute()
    InsertLocationData(location, false, strDate, applicationContext).execute()
    getLocationList()
}


private fun getLocationList() {
    GetLocationData(applicationContext, this).execute()
}

override fun processData(locationData: MutableList<LocationParam>?) {
    hitApitoBulkEnter(locationData!!)
}

private fun hitApitoBulkEnter(location: List<LocationParam>) {
    if (!Utils.isNetworkConnected(this)) {
        Toast.makeText(
            this,
            "No internet connection available. Please check your internet connection.",
            Toast.LENGTH_SHORT
        ).show()
        startActivity(Intent(this, InternetSettingCheck::class.java))
        return
    }
   

     // send location to the server 
  
}


private fun readWebPageBulkTest(location: String, mTemp: List<LocationParam>) {
    if (!Utils.isNetworkConnected(this)) {
        Toast.makeText(
            this,
            "No internet connection available. Please check your internet connection.",
            Toast.LENGTH_SHORT
        ).show()
        startActivity(Intent(this, InternetSettingCheck::class.java))
        return
    }
    val settings = applicationContext.getSharedPreferences("AcessToken", MODE_PRIVATE)
    val access_token = settings.getString("Access_Token", "")
    val user_id = settings.getInt("User_ID", 0).toString()
    var attendance_id = settings.getString("Attendance_ID", "")
    apiInterface = APIClient.getClient().create(GetDataService::class.java)
    if (attendance_id == "") {
        attendance_id = "0"
    }
    if (user_id != "") {
        val call: Call<NewLocationPojo> = apiInterface!!.updateLatLongforUserIDBulk(
            "Bearer $access_token",
            location
        )
        Log.e("JsonLocation  :", location)
        call.enqueue(object : Callback<NewLocationPojo> {
            override fun onResponse(
                call: Call<NewLocationPojo>,
                response: Response<NewLocationPojo>
            ) {
                try {
                    if (response.body()!!.status == "success") {
                        Log.e("Api response :", response.body()!!.status)
                        Toast.makeText(
                            this@MyEndlessService,
                            "" + response.body()!!.status.toString(),
                            Toast.LENGTH_SHORT
                        ).show()
                        updatelatlong(location, mTemp)
                    } else {
                        Toast.makeText(
                            this@MyEndlessService,
                            "" + response.body()!!.status.toString(),
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                } catch (e: java.lang.Exception) {
                    Toast.makeText(this@MyEndlessService, "" + e.toString(), Toast.LENGTH_SHORT)
                        .show()
                    Log.e("ServerSam :", e.toString())
                }
            }

            override fun onFailure(call: Call<NewLocationPojo>, t: Throwable) {
                Log.e("ServerSam :", t.toString())
                log("The service has been destroyed".toUpperCase())
                val calendar = Calendar.getInstance()
                val mdformat = SimpleDateFormat("HH:mm:ss")
                val strDate = mdformat.format(calendar.time)
                LocalDatabaseForException(applicationContext,strDate,"Api Error :"+t.toString() ).execute()
            }
        })
    }

}

private fun getPostFinal() {

    class GetTasks : AsyncTask<Void?, Void?, List<LocationParam>>() {

        override fun onPostExecute(tasks: List<LocationParam>) {
            super.onPostExecute(tasks)
            DeleteLocationData(applicationContext).execute()
            GetLocationData22().execute()
            // testDataAfterDeleteion();
        }

        override fun doInBackground(vararg params: Void?): List<LocationParam> {
            val taskList = DatabaseClient
                .getInstance(applicationContext)
                .appDatabase
                .locationDao()
                .all
            Log.e("Database after updation", taskList.toString())
            return taskList
        }
    }

    val gt = GetTasks()
    gt.execute()
}


internal class GetLocationData22 : AsyncTask<Void?, Void?, List<LocationParam>>() {
    var mContext: Context? = null


    override fun onPostExecute(tasks: List<LocationParam>) {
        super.onPostExecute(tasks)
    }

    override fun doInBackground(vararg params: Void?): List<LocationParam> {
        val taskList = DatabaseClient.getInstance(mContext)
            .appDatabase
            .locationDao()
            .all
        Log.d("GetAfterDeleteion :", taskList.toString())
        return taskList
    }
}


protected fun isBetterLocation(location: Location, currentBestLocation: Location?): Boolean {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true
    }

    // Check whether the new location fix is newer or older
    val timeDelta = location.time - currentBestLocation.time
    val isSignificantlyNewer = timeDelta > MyService66.TWO_MINUTES
    val isSignificantlyOlder = timeDelta < -MyService66.TWO_MINUTES
    val isNewer = timeDelta > 0

    // If it's been more than two minutes since the current location, use the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return true
        // If the new location is more than two minutes older, it must be worse
    } else if (isSignificantlyOlder) {
        return false
    }

    // Check whether the new location fix is more or less accurate
    val accuracyDelta = (location.accuracy - currentBestLocation.accuracy).toInt()
    val isLessAccurate = accuracyDelta > 0
    val isMoreAccurate = accuracyDelta < 0
    val isSignificantlyLessAccurate = accuracyDelta > 200
    // Check if the old and new location are from the same provider
    val isFromSameProvider: Boolean =
        isSameProvider(location.provider, currentBestLocation.provider)
    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) {
        return true
    } else if (isNewer && !isLessAccurate) {
        return true
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
        return true
    }
    return false
}


/**
 * Checks whether two providers are the same
 */
private fun isSameProvider(provider1: String?, provider2: String?): Boolean {
    return if (provider1 == null) {
        provider2 == null
    } else provider1 == provider2
}

private fun createNotification(): Notification {
    val notificationChannelId = "ENDLESS SERVICE CHANNEL"

    // depending on the Android API that we're dealing with we will have
    // to use a specific method to create the notification
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channel = NotificationChannel(
            notificationChannelId,
            "Endless Service notifications channel",
            NotificationManager.IMPORTANCE_HIGH
        ).let {
            it.description = "Endless Service channel"
            it.enableLights(true)
            it.lightColor = Color.RED
            it.enableVibration(true)
            it.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
            it
        }
        notificationManager.createNotificationChannel(channel)
    }

    val pendingIntent: PendingIntent = Intent(this, MainActivityFinal2::class.java).let { notificationIntent ->
        PendingIntent.getActivity(this, 0, notificationIntent, 0)
    }

    val builder: Notification.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) Notification.Builder(
        this,
        notificationChannelId
    ) else Notification.Builder(this)

    return builder
        .setContentTitle("Sapphire location on")
       // .setContentText("This is your favorite endless service working")
        .setContentIntent(pendingIntent)
        .setSmallIcon(R.mipmap.app_icon)
     //   .setTicker("Ticker text")
        .setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility
        .build()
}
private var wakeLock:PowerManager.wakeLock?=null
私有变量isServiceStarted=false
var TAG=“MyService”
变量gps_状态=1
变量编辑器:SharedReferences.editor?=null
var previousBestLocation:位置?=null
APIVAR接口:GetDataService?=null
私有变量googleApiClient:googleApiClient?=null
私有变量lastLocation:位置?=null
私有变量locationRequest:locationRequest?=null
专用val更新间隔=10000
私有值最快\u间隔=更新\u间隔/2
var locationManager:locationManager?=null
var isFirsttime=true
var sharedPreferences:sharedPreferences?=null
覆盖有趣的onBind(意图:意图):IBinder{
返回空
}
覆盖启动命令(intent:intent?,标志:Int,startId:Int):Int{
日志(“使用startId执行的onStartCommand:$startId”)
if(intent!=null){
val action=intent.action
日志(“将意图与操作$action一起使用”)
何时(行动){
Actions.START.name->startService()
Actions.STOP.name->stopService()
else->log(“这永远不会发生。在接收到的意图中没有操作”)
}
}否则{
日志(
“具有空意图。它可能已被系统重新启动。”
)
}
返回起始点
}
重写fun onCreate(){
super.onCreate()
日志(“服务已创建”.toUpperCase())
val notification=createNotification()
startForeground(1,通知)
}
重写onDestroy(){
super.ondestory()
日志(“服务已被销毁”。toUpperCase())
val calendar=calendar.getInstance()
val mdformat=SimpleDataFormat(“HH:mm:ss”)
val strDate=mdformat.format(calendar.time)
LocalDatabaseForException(applicationContext,strDate,“服务已销毁”).execute()
val broadcastIntent=Intent()
broadcastIntent.action=“重新启动服务”
broadcastIntent.setClass(这是Restarter::class.java)
this.sendBroadcast(broadcastIntent)
}
重写onTaskRemoved(rootIntent:Intent){
val restartServiceIntent=Intent(applicationContext,MyEndlessService::class.java){
it.setPackage(packageName)
};
val restartservicependingent:pendingent=pendingent.getService(
这
1.
restartServiceIntent,
悬垂的帐篷,旗帜,一枪
);
applicationContext.getSystemService(Context.ALARM\u服务);
val alarmService:AlarmManager=applicationContext.getSystemService(Context.ALARM\u服务)作为AlarmManager;
alarmService.set(
AlarmManager.u实时,
SystemClock.elapsedRealtime()+1000,
restartServicePendingIntent酒店
);
}
私人娱乐startService(){
val calendar=calendar.getInstance()
val mdformat=SimpleDataFormat(“HH:mm:ss”)
val strDate=mdformat.format(calendar.time)
LocalDatabaseForException(applicationContext,strDate,“服务已启动”).execute()
如果(isServiceStarted)返回
日志(“启动前台服务任务”)
//Toast.makeText(这个“服务开始它的任务”,Toast.LENGTH\u SHORT.show())
isServiceStarted=true
setServiceState(此,ServiceState.STARTED)
//我们需要这个锁,这样我们的服务就不会受到打盹模式的影响
韦克洛克=
(作为PowerManager的getSystemService(Context.POWER\u服务)。运行{
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,“EndlessService::LOCK”)。应用{
获得
}
}
//我们要在一个协同程序中启动一个循环
GlobalScope.launch(Dispatchers.IO){
while(iServiceStarted){
发射(Dispatchers.IO){
pingFakeServer()
handleUserTracking()
}
延迟(1000)
}
日志(“服务的循环结束”)
}
}
私人娱乐服务{
日志(“停止前台服务”)
//Toast.makeText(这是“服务停止”,Toast.LENGTH\u SHORT.show())
val calendar=calendar.getInstance()
val mdformat=SimpleDataFormat(“HH:mm:ss”)
val strDate=mdformat.format(calendar.time)
LocalDatabaseForException(applicationContext,strDate,“服务已停止”).execute()
试一试{
韦克洛克?,让我来{
如果(it.isHeld){
//startService()
it.release()
}
}
//停止前景(真)
//stopSelf()
}捕获(e:例外){
日志(“服务已停止而未启动:${e.message}”)
val calendar=calendar.getInstance()
val mdformat=SimpleDataFormat(“HH:mm:ss”)
val strDate=mdformat.format(calendar.time)
LocalDatabaseForException(applicationContext,strDate,“服务停止而未启动:${e.message}”).execute()
}
isServiceStarted=false
setServiceState(此,ServiceState.STARTED)
}
私人娱乐pingFakeServer(){
SmartLocation.with(applicationContext.location())
.start(对象:OnLocationUpdatedListener{
覆盖乐趣onLocationUpdated(位置:位置?){
val SharedReferences=applicationContext.GetSharedReferences(
“AcessToken”,
AppCompatActivity.MODE_多进程
)
editor=getSharedReferences(“AcessToken”,MODE\u PRIVATE).edit()
editor=getSharedReferences(“AcessToken”,MODE\u PRIVATE).edit()
编辑器!!.putString(“temp\u latitude”,location!!.getLatitude().toString())
编辑器!!.putString(“temp\u latitude”,location!!.getLatitude().toString())
编辑器!!.apply()