Skip to content

Commit

Permalink
Stopped possiblity of memory leak caused from BackgroundService, refa…
Browse files Browse the repository at this point in the history
…ctored project name, Fixed unexpected exit while requesting location permission, Removed depricated methods
  • Loading branch information
HarshPanchal18 committed Feb 18, 2024
1 parent dcc1d31 commit ab7223f
Show file tree
Hide file tree
Showing 18 changed files with 128 additions and 105 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ android {
compileSdk = 34

defaultConfig {
applicationId = "com.example.geofencing"
applicationId = "dev.harsh.tradow"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
versionName = "1.3"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
Binary file removed app/release/Tradow.apk
Binary file not shown.
Binary file added app/release/app-release.apk
Binary file not shown.
4 changes: 2 additions & 2 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.example.geofencing",
"applicationId": "dev.harsh.tradow",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"versionName": "1.3",
"outputFile": "app-release.apk"
}
],
Expand Down
14 changes: 7 additions & 7 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@
<uses-feature android:name="android.hardware.location.gps" />

<application
android:name="dev.harsh.tradow.App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:name=".App"
android:supportsRtl="true"
android:theme="@style/Theme.Geofencing"
tools:targetApi="31">
<activity
android:windowSoftInputMode="adjustResize"
android:name=".MainActivity"
android:name="dev.harsh.tradow.MainActivity"
android:exported="true"
android:screenOrientation="locked"
android:theme="@style/Theme.Geofencing">
android:theme="@style/Theme.Geofencing"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand All @@ -34,9 +34,9 @@
</activity>

<service
android:name=".service.BackgroundService"
android:foregroundServiceType="location"
android:enabled="true" />
android:name="dev.harsh.tradow.service.BackgroundService"
android:enabled="true"
android:foregroundServiceType="location" />

</application>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.geofencing
package dev.harsh.tradow

import android.app.Application
import android.app.NotificationChannel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.example.geofencing
package dev.harsh.tradow

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
Expand Down Expand Up @@ -38,28 +40,26 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.startForegroundService
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.geofencing.model.Spot
import com.example.geofencing.service.BackgroundService
import com.example.geofencing.ui.BottomRow
import com.example.geofencing.ui.BottomSheet
import com.example.geofencing.ui.Screens
import com.example.geofencing.ui.SplashScreen
import com.example.geofencing.ui.SpotItem
import com.example.geofencing.ui.theme.GeofencingTheme
import com.example.geofencing.util.SharedPreferencesHelper.PREF_NAME
import com.example.geofencing.util.SharedPreferencesHelper.loadSpots
import com.example.geofencing.util.SharedPreferencesHelper.updateSpots
import com.example.geofencing.util.showLongToast
import com.example.geofencing.util.showShortToast
import com.example.geofencing.R
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import dev.harsh.tradow.model.Spot
import dev.harsh.tradow.service.BackgroundService
import dev.harsh.tradow.ui.BottomRow
import dev.harsh.tradow.ui.BottomSheet
import dev.harsh.tradow.ui.Screens
import dev.harsh.tradow.ui.SplashScreen
import dev.harsh.tradow.ui.SpotItem
import dev.harsh.tradow.ui.theme.GeofencingTheme
import dev.harsh.tradow.util.SharedPreferencesHelper.PREF_NAME
import dev.harsh.tradow.util.SharedPreferencesHelper.loadSpots
import dev.harsh.tradow.util.SharedPreferencesHelper.updateSpots
import dev.harsh.tradow.util.showLongToast
import dev.harsh.tradow.util.showShortToast

@Suppress("DEPRECATION")
class MainActivity : ComponentActivity() {
private lateinit var sharedPref: SharedPreferences
private lateinit var spots: MutableState<Array<Spot>>
Expand Down Expand Up @@ -133,68 +133,51 @@ class MainActivity : ComponentActivity() {

}

@Deprecated("Deprecated in Java")
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>, grantResults: IntArray,
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)

if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
this.showShortToast("Monitoring started successfully!")
startForegroundService(this, Intent(this, BackgroundService::class.java))
} else {
// show an toast message asking for the permission
this.showLongToast("Do I really need to tell, why you should give me location access??")
}
}

// Move the task containing this activity to the back of the activity stack.
override fun onPause() {
super.onPause()
moveTaskToBack(true)

if (checkLocationPermission())
moveTaskToBack(true)
}

@Composable
fun HomeScreen(forOpenBottomSheet: () -> Unit) {
var hasLocationPermission = false
val isLocationEnabled = checkLocationState()
val locationPermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted)
hasLocationPermission = true
else
this.showLongToast("Do I really need to tell, why you should give me location access??")
}

Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
BottomRow(
onStartClick = {
if (ContextCompat.checkSelfPermission(
this@MainActivity, Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
/* activity = */ this@MainActivity as Activity,
/* permissions = */
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
/* requestCode = */
1
)
} else {
if (hasLocationPermission) {
when {
spots.value.isEmpty() -> forOpenBottomSheet()

spots.value.any { it.isSelected } -> {
val manager =
getSystemService(LOCATION_SERVICE) as LocationManager
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER))
this.showShortToast("Please turn on location to get started")
//startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))

val backgroundServiceIntent =
Intent(
this@MainActivity,
BackgroundService::class.java
)
startService(backgroundServiceIntent)
//[email protected]("Service Started Successfully!")
if (isLocationEnabled) {
val backgroundServiceIntent =
Intent(this@MainActivity, BackgroundService::class.java)
startService(backgroundServiceIntent)
} else {
this.showShortToast("Please turn on location to get started")
}
}

else ->
this@MainActivity.showShortToast("Kindly choose a site to monitor!")

else -> this@MainActivity.showShortToast("Kindly choose a site to monitor!")
}
} else {
locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
},
onStopClick = {
Expand Down Expand Up @@ -269,4 +252,20 @@ class MainActivity : ComponentActivity() {
}
}
}

private fun checkLocationPermission(): Boolean {
// Check if the location permission is granted
return ContextCompat.checkSelfPermission(
this, Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
}

private fun checkLocationState(): Boolean {
val manager = getSystemService(LOCATION_SERVICE) as LocationManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
manager.isLocationEnabled
} else {
manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.geofencing.model
package dev.harsh.tradow.model

data class Spot(
val title: String = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@file:Suppress("DEPRECATION")

package com.example.geofencing.service
package dev.harsh.tradow.service

import android.Manifest
import android.app.Notification
Expand All @@ -14,21 +14,22 @@ import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.example.geofencing.App.Companion.CHANNEL_ID
import com.example.geofencing.MainActivity
import com.example.geofencing.R
import com.example.geofencing.util.LATITUDE
import com.example.geofencing.util.LONGITUDE
import com.example.geofencing.util.SharedPreferencesHelper
import com.example.geofencing.util.SharedPreferencesHelper.PREF_NAME
import com.example.geofencing.util.showShortToast
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import dev.harsh.tradow.App.Companion.CHANNEL_ID
import dev.harsh.tradow.MainActivity
import dev.harsh.tradow.util.LATITUDE
import dev.harsh.tradow.util.LONGITUDE
import dev.harsh.tradow.util.SharedPreferencesHelper
import dev.harsh.tradow.util.SharedPreferencesHelper.PREF_NAME
import dev.harsh.tradow.util.showShortToast
import kotlin.math.abs
import kotlin.math.atan2
import kotlin.math.cos
Expand Down Expand Up @@ -139,6 +140,7 @@ class BackgroundService : Service(), GoogleApiClient.ConnectionCallbacks,
val latDistance = Math.toRadians(abs(lat2 - lat1))
val lonDistance = Math.toRadians(abs(lon2 - lon1))

// Ref: https://www.movable-type.co.uk/scripts/latlong.html
val a = (sin(latDistance / 2) * sin(latDistance / 2)
+ (cos(Math.toRadians(lat1)) * cos(Math.toRadians(lat2))
* sin(lonDistance / 2) * sin(lonDistance / 2)))
Expand Down Expand Up @@ -184,10 +186,15 @@ class BackgroundService : Service(), GoogleApiClient.ConnectionCallbacks,
.setContentIntent(pendingIntent)
.build()
} else {
TODO("VERSION.SDK_INT < O")
NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Tradow monitoring is active")
.setContentText("Tap to return")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build()
}

startForeground(1, notification)
startForeground(/* id = */ 1, /* notification = */ notification)

// connect the google client
if (this.googleApiClient != null)
Expand All @@ -202,6 +209,9 @@ class BackgroundService : Service(), GoogleApiClient.ConnectionCallbacks,
if (googleApiClient?.isConnected == true)
googleApiClient?.disconnect()

stopForeground(/* removeNotification = */ true)
stopLocationUpdates()

audioManager.ringerMode = AudioManager.RINGER_MODE_NORMAL

//this.showShortToast("Service is stopping...")
Expand All @@ -215,6 +225,21 @@ class BackgroundService : Service(), GoogleApiClient.ConnectionCallbacks,
}
}

private fun stopLocationUpdates() {
try {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
LocationServices.getFusedLocationProviderClient(this)
.removeLocationUpdates(locationCallback)
}
} catch (e: Exception) {
Log.e("Location updates", e.message.toString())
}
}

override fun onConnectionSuspended(p0: Int) {}

override fun onConnectionFailed(connectionResult: ConnectionResult) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.geofencing.ui
package dev.harsh.tradow.ui

object Screens {
const val Splash = "Splash"
Expand Down
Loading

0 comments on commit ab7223f

Please sign in to comment.