Last active
January 10, 2020 04:50
-
-
Save nicemak/201e84af9c36abf30221e67e9915ba70 to your computer and use it in GitHub Desktop.
Location Monitoring Service Files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.BroadcastReceiver | |
import android.content.Context | |
import android.content.Intent | |
import android.os.Build | |
class BroadCastReceiver : BroadcastReceiver() { | |
override fun onReceive(context: Context, intent: Intent) | |
{ | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) | |
context.startForegroundService(Intent(context,LocationMonitoringService::class.java)) | |
else | |
context.startService(Intent(context, LocationMonitoringService::class.java)) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.Manifest | |
import android.app.* | |
import android.content.Context | |
import android.content.Intent | |
import android.content.pm.PackageManager | |
import android.graphics.Color | |
import android.os.Build | |
import android.os.Bundle | |
import android.os.IBinder | |
import androidx.core.app.ActivityCompat | |
import androidx.core.app.NotificationCompat | |
import androidx.localbroadcastmanager.content.LocalBroadcastManager | |
import com.google.android.gms.common.ConnectionResult | |
import com.google.android.gms.common.api.GoogleApiClient | |
import com.google.android.gms.location.LocationRequest | |
import com.google.android.gms.location.LocationServices | |
class LocationMonitoringService : Service(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { | |
private var mLocationClient: GoogleApiClient? = null | |
private var mLocationRequest = LocationRequest() | |
var context: Context? = null | |
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int | |
{ | |
super.onStartCommand(intent, flags, startId) | |
println("onStartCommand") | |
mLocationClient = GoogleApiClient.Builder(this) | |
.addConnectionCallbacks(this) | |
.addOnConnectionFailedListener(this) | |
.addApi(LocationServices.API) | |
.build() | |
mLocationRequest.interval = LOCATION_INTERVAL | |
mLocationRequest.fastestInterval = FASTEST_LOCATION_INTERVAL | |
//mLocationRequest.setSmallestDisplacement(DISTANCE_IN_METERS); | |
//PRIORITY_BALANCED_POWER_ACCURACY, PRIORITY_LOW_POWER, PRIORITY_NO_POWER are the other priority modes | |
mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY //by default | |
mLocationClient!!.connect() | |
//Make it stick to the notification panel so it is less prone to get cancelled by the Operating System. | |
return START_STICKY | |
} | |
override fun onCreate() | |
{ | |
super.onCreate() | |
context = this | |
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) | |
startMyOwnForeground() | |
else | |
startForeground(1, Notification()) | |
println("onCreate") | |
} | |
private fun startMyOwnForeground() { | |
println("startMyOwnForeground called ") | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) | |
{ | |
val channelId = getString(R.string.app_name) | |
val channelName = "Background Service" | |
val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH) | |
chan.lightColor = Color.BLUE | |
chan.lockscreenVisibility = Notification.VISIBILITY_PUBLIC // VISIBILITY_PRIVATE | |
val manager = | |
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) | |
manager.createNotificationChannel(chan) | |
val notificationBuilder: NotificationCompat.Builder = | |
NotificationCompat.Builder(this, channelId) | |
val notification: Notification = notificationBuilder.setOngoing(true) | |
.setContentTitle("App is running in background") | |
.setSmallIcon(R.drawable.ikonnect_logo) // the status icon | |
.setPriority(NotificationManager.IMPORTANCE_HIGH) | |
.setCategory(Notification.CATEGORY_PROGRESS) //CATEGORY_SERVICE | |
.setOngoing(true) | |
.build() | |
startForeground(2, notification) | |
} | |
} | |
override fun onBind(intent: Intent?): IBinder? = null | |
override fun onConnected(dataBundle: Bundle?) { | |
val intent = Intent() | |
intent.action = LOCATION_PARAM | |
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED | |
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) | |
{ | |
println("Error On onConnected() Permission not granted") | |
//Permission not granted by user so cancel the further execution. | |
intent.putExtra(LATITUDE, getStringValue(LATITUDE)) | |
intent.putExtra(LONGITUDE, getStringValue(LONGITUDE)) | |
LocalBroadcastManager.getInstance(context!!).sendBroadcast(intent) | |
return | |
} | |
if (mLocationClient!!.isConnected) | |
{ | |
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest) | |
{ location -> | |
if (location != null) | |
{ | |
println("${location.latitude}, ${location.longitude}") | |
//System.out.println("" + location.getLatitude() + ", " + location.getLongitude() + ", Accuracy: " + location.getAccuracy()); | |
//Save locations | |
saveString(LATITUDE, "${location.latitude}") | |
saveString(LONGITUDE, "${location.longitude}") | |
intent.putExtra(LATITUDE, location.latitude) | |
intent.putExtra(LONGITUDE, location.longitude) | |
LocalBroadcastManager.getInstance(context!!).sendBroadcast(intent) | |
} | |
} | |
} | |
else | |
{ | |
println("Not Connected to Google API") | |
mLocationClient!!.connect() | |
} | |
println("Connected to Google API") | |
} | |
override fun onConnectionSuspended(p0: Int) { | |
println("Connection Suspended") | |
} | |
override fun onConnectionFailed(p0: ConnectionResult) { | |
println("Connection Failed") | |
} | |
override fun onDestroy() { | |
super.onDestroy() | |
if (mLocationClient != null) mLocationClient!!.disconnect() | |
val broadcastIntent = Intent() | |
broadcastIntent.action = "RestartService" | |
broadcastIntent.setClass(this, BroadCastReceiver::class.java) | |
/*if (keep_me_on) { | |
println("service ondestroy try") | |
this.sendBroadcast(broadcastIntent) | |
}*/ | |
println("Service Destroyed") | |
} | |
/*override fun onTaskRemoved(rootIntent: Intent?) { | |
*//*try { | |
println("onTskRemoved try") | |
if (networkConsume.getBoolean(AppConstants.SHIFT_ACTIVE, context)) { | |
if (!isMyServiceRunning(this.javaClass)) { | |
val restartServiceIntent = | |
Intent(applicationContext, this.javaClass) | |
restartServiceIntent.setPackage(packageName) | |
val restartServicePendingIntent = PendingIntent.getService( | |
applicationContext, | |
1, | |
restartServiceIntent, | |
PendingIntent.FLAG_ONE_SHOT | |
) | |
val alarmService = | |
applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager | |
alarmService[AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000] = | |
restartServicePendingIntent | |
} | |
} | |
} catch (e: java.lang.Exception) { | |
println("Service onTaskRemoved Exception : $e") | |
}*//* | |
super.onTaskRemoved(rootIntent) | |
}*/ | |
private fun isMyServiceRunning(serviceClass: Class<*>): Boolean { | |
try { | |
val manager = | |
getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager | |
for (service in manager.getRunningServices(Int.MAX_VALUE)) | |
{ | |
if (serviceClass.name == service.service.className) { | |
println("Service is running: " + service.service.className) | |
return true | |
} | |
} | |
} catch (e: Exception) { | |
println("isMyServiceRunning Exception: $e") | |
} | |
println("Service is not running") | |
return false | |
} | |
companion object { | |
private const val LOCATION_INTERVAL: Long = 30000 | |
private const val FASTEST_LOCATION_INTERVAL: Long = 15000 | |
private const val DISTANCE_IN_METERS = 10f | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In Manifest Under Application Tag: | |
<service | |
android:name=".backgroundservice.LocationMonitoringService" | |
android:enabled="true" | |
android:exported="true" | |
android:icon="@drawable/ikonnect_logo" | |
android:stopWithTask="false" /> | |
<receiver | |
android:name=".backgroundservice.BroadCastReceiver" | |
android:enabled="true" | |
android:exported="true" | |
android:label="RestartServiceWhenStopped"> | |
<intent-filter> | |
<action android:name="RestartService" /> | |
</intent-filter> | |
</receiver> | |
=========================================================================================================================== | |
In MainActivity: | |
// Service | |
var mServiceIntent: Intent? = null | |
var mLocationService: LocationMonitoringService? = null | |
=========================================================================================================================== | |
onCreate:: | |
mLocationService = LocationMonitoringService() | |
mServiceIntent = Intent(context, LocationMonitoringService::class.java) | |
LocalBroadcastManager.getInstance(context).registerReceiver(broadcastReceiver, IntentFilter(LOCATION_PARAM)) | |
startLocationService() | |
=========================================================================================================================== | |
private fun isMyServiceRunning(serviceClass: Class<*>): Boolean { | |
try { | |
val manager = | |
getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager | |
for (service in manager.getRunningServices(Int.MAX_VALUE)) { | |
if (serviceClass.name == service.service.className) { | |
println("Service is running: " + service.service.className) | |
return true | |
} | |
} | |
} catch (e: Exception) { | |
println("isMyServiceRunning Exception: $e") | |
} | |
println("Service is not running") | |
return false | |
} | |
=========================================================================================================================== | |
private fun startLocationService() { | |
try | |
{ | |
println("isServiceRunning: ${getBooleanValue(SP_SERVICE)}") | |
if (!isMyServiceRunning(mLocationService!!::class.java)) | |
{ | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | |
println("Service Start for oreo or above") | |
ContextCompat.startForegroundService(context, mServiceIntent!!) | |
} else { | |
println("Service Start normally") | |
startService(mServiceIntent) | |
} | |
} | |
} catch (e: Exception) { | |
println("Exception while starting service $e") | |
} | |
} | |
=========================================================================================================================== | |
onDestroy:: | |
try | |
{ | |
// Unregister Broadcast Receiver | |
LocalBroadcastManager.getInstance(context).unregisterReceiver(broadcastReceiver) | |
// Stop Service | |
stopService(mServiceIntent) | |
} | |
catch (e: Exception) | |
{ | |
println("onDestroy Exception: $e") | |
} | |
=========================================================================================================================== | |
private var broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() | |
{ | |
override fun onReceive(context: Context, intent: Intent) | |
{ | |
val status = getStringValue(SP_ACTIVITY_STATUS) | |
if (intent.hasExtra(LATITUDE) && intent.hasExtra(LONGITUDE) && status == "RESUME") | |
{ | |
val currentLocation = Location("") | |
currentLocation.latitude = intent.getDoubleExtra(LATITUDE, 0.0) | |
currentLocation.longitude = intent.getDoubleExtra(LONGITUDE, 0.0) | |
if (getAddressFromLatLong(currentLocation).isNotEmpty()) | |
tv_location.text = getAddressFromLatLong(currentLocation)[0].getAddressLine(0).toString() | |
else | |
tv_location.text = "Unknown Location" | |
} | |
} | |
} | |
=========================================================================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment