Skip to content

Commit 44abd61

Browse files
added location update example
1 parent fa26f3f commit 44abd61

40 files changed

Lines changed: 1035 additions & 0 deletions

UpdateLiveLocation/.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/caches
5+
/.idea/libraries
6+
/.idea/modules.xml
7+
/.idea/workspace.xml
8+
/.idea/navEditor.xml
9+
/.idea/assetWizardSettings.xml
10+
.DS_Store
11+
/build
12+
/captures
13+
.externalNativeBuild
14+
.cxx
15+
local.properties

UpdateLiveLocation/app/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
plugins {
2+
id 'com.android.application'
3+
id 'kotlin-android'
4+
}
5+
6+
android {
7+
compileSdkVersion 30
8+
buildToolsVersion "30.0.2"
9+
10+
defaultConfig {
11+
applicationId "com.velmurugan.updatelivelocation"
12+
minSdkVersion 24
13+
targetSdkVersion 30
14+
versionCode 1
15+
versionName "1.0"
16+
17+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
18+
}
19+
20+
buildTypes {
21+
release {
22+
minifyEnabled false
23+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
24+
}
25+
}
26+
compileOptions {
27+
sourceCompatibility JavaVersion.VERSION_1_8
28+
targetCompatibility JavaVersion.VERSION_1_8
29+
}
30+
kotlinOptions {
31+
jvmTarget = '1.8'
32+
}
33+
}
34+
35+
dependencies {
36+
37+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
38+
implementation 'androidx.core:core-ktx:1.3.2'
39+
implementation 'androidx.appcompat:appcompat:1.2.0'
40+
implementation 'com.google.android.material:material:1.3.0'
41+
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
42+
testImplementation 'junit:junit:4.+'
43+
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
44+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
45+
// Networking
46+
implementation "com.squareup.retrofit2:retrofit:2.9.0"
47+
implementation "com.squareup.okhttp3:okhttp:4.7.2"
48+
implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"
49+
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
50+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.velmurugan.updatelivelocation
2+
3+
import androidx.test.platform.app.InstrumentationRegistry
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import org.junit.Test
6+
import org.junit.runner.RunWith
7+
import org.junit.Assert.*
8+
9+
/**
10+
* Instrumented test, which will execute on an Android device.
11+
*
12+
* See [testing documentation](http://d.android.com/tools/testing).
13+
*/
14+
@RunWith(AndroidJUnit4::class)
15+
class ExampleInstrumentedTest {
16+
@Test
17+
fun useAppContext() {
18+
// Context of the app under test.
19+
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
20+
assertEquals("com.velmurugan.updatelivelocation", appContext.packageName)
21+
}
22+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.velmurugan.updatelivelocation">
4+
5+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
6+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
7+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
8+
<uses-permission android:name="android.permission.INTERNET"/>
9+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
10+
11+
<application
12+
android:allowBackup="true"
13+
android:icon="@mipmap/ic_launcher"
14+
android:label="@string/app_name"
15+
android:roundIcon="@mipmap/ic_launcher_round"
16+
android:supportsRtl="true"
17+
android:usesCleartextTraffic="true"
18+
android:theme="@style/Theme.UpdateLiveLocation">
19+
<activity android:name=".MainActivity">
20+
<intent-filter>
21+
<action android:name="android.intent.action.MAIN" />
22+
23+
<category android:name="android.intent.category.LAUNCHER" />
24+
</intent-filter>
25+
</activity>
26+
27+
<receiver
28+
android:name=".BootDeviceReceivers"
29+
android:enabled="true"
30+
android:exported="true">
31+
<intent-filter>
32+
<action android:name="android.intent.action.BOOT_COMPLETED"/>
33+
</intent-filter>
34+
</receiver>
35+
36+
<service
37+
android:name=".LocationService"
38+
android:enabled="true"
39+
android:exported="true" />
40+
</application>
41+
42+
</manifest>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.velmurugan.updatelivelocation
2+
3+
import android.content.Context
4+
import okhttp3.OkHttpClient
5+
import okhttp3.logging.HttpLoggingInterceptor
6+
import retrofit2.Call
7+
import retrofit2.Response
8+
import retrofit2.Retrofit
9+
import retrofit2.converter.gson.GsonConverterFactory
10+
import retrofit2.http.GET
11+
import retrofit2.http.Part
12+
import retrofit2.http.Path
13+
14+
interface ApiClient {
15+
16+
@GET("updateLocation.json")
17+
fun updateLocation() : Call<LocationResponse>
18+
19+
companion object {
20+
21+
var retrofit: Retrofit? = null
22+
val logging = HttpLoggingInterceptor().apply {
23+
this.level = HttpLoggingInterceptor.Level.BODY
24+
}
25+
fun getInstance(context: Context) : Retrofit {
26+
if (retrofit == null) {
27+
retrofit = Retrofit.Builder()
28+
.baseUrl("https://howtodoandroid.com/apis/")
29+
.client(OkHttpClient.Builder().addInterceptor(logging).build())
30+
.addConverterFactory(GsonConverterFactory.create())
31+
.build()
32+
}
33+
return retrofit!!
34+
}
35+
}
36+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.velmurugan.updatelivelocation
2+
3+
import android.os.Handler
4+
import android.os.Looper
5+
import java.util.concurrent.Executor
6+
import java.util.concurrent.Executors
7+
8+
class AppExecutors private constructor(
9+
private val diskIO: Executor,
10+
private val networkIO: Executor,
11+
private val mainThread: Executor
12+
) {
13+
fun diskIO(): Executor {
14+
return diskIO
15+
}
16+
17+
fun mainThread(): Executor {
18+
return mainThread
19+
}
20+
21+
fun networkIO(): Executor {
22+
return networkIO
23+
}
24+
25+
private class MainThreadExecutor : Executor {
26+
private val mainThreadHandler = Handler(Looper.getMainLooper())
27+
override fun execute(command: Runnable) {
28+
mainThreadHandler.post(command)
29+
}
30+
}
31+
32+
companion object {
33+
// For Singleton instantiation
34+
private val LOCK = Any()
35+
private var sInstance: AppExecutors? = null
36+
val instance: AppExecutors?
37+
get() {
38+
if (sInstance == null) {
39+
synchronized(LOCK) {
40+
sInstance = AppExecutors(
41+
Executors.newSingleThreadExecutor(),
42+
Executors.newFixedThreadPool(3),
43+
MainThreadExecutor()
44+
)
45+
}
46+
}
47+
return sInstance
48+
}
49+
}
50+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.velmurugan.updatelivelocation
2+
3+
import android.content.BroadcastReceiver
4+
import android.content.Context
5+
import android.content.Intent
6+
import androidx.core.content.ContextCompat
7+
8+
class BootDeviceReceivers : BroadcastReceiver() {
9+
10+
override fun onReceive(context: Context?, intent: Intent?) {
11+
context?.let {
12+
ContextCompat.startForegroundService(it, Intent(it, LocationService::class.java))
13+
}
14+
}
15+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.velmurugan.updatelivelocation
2+
3+
import android.Manifest
4+
import android.annotation.SuppressLint
5+
import android.content.Context
6+
import android.content.pm.PackageManager
7+
import android.location.Location
8+
import android.location.LocationListener
9+
import android.location.LocationManager
10+
import android.os.Bundle
11+
import androidx.core.app.ActivityCompat
12+
13+
class LocationHelper {
14+
var LOCATION_REFRESH_TIME = 3000 // 3 seconds. The Minimum Time to get location update
15+
var LOCATION_REFRESH_DISTANCE =
16+
0 // 0 meters. The Minimum Distance to be changed to get location update
17+
18+
@SuppressLint("MissingPermission")
19+
fun startListeningUserLocation(context: Context, myListener: MyLocationListener) {
20+
val mLocationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
21+
val locationListener: LocationListener = object : LocationListener {
22+
override fun onLocationChanged(location: Location) {
23+
myListener.onLocationChanged(location) // calling listener to inform that updated location is available
24+
}
25+
26+
override fun onProviderEnabled(provider: String) {}
27+
override fun onProviderDisabled(provider: String) {}
28+
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
29+
}
30+
mLocationManager.requestLocationUpdates(
31+
LocationManager.GPS_PROVIDER,
32+
LOCATION_REFRESH_TIME.toLong(),
33+
LOCATION_REFRESH_DISTANCE.toFloat(),
34+
locationListener
35+
)
36+
}
37+
}
38+
39+
interface MyLocationListener {
40+
fun onLocationChanged(location: Location?)
41+
}

0 commit comments

Comments
 (0)