From 5810368f8287aeca260b0f1ac299af3434190306 Mon Sep 17 00:00:00 2001 From: Gopal Matcha Date: Sun, 18 Sep 2022 18:02:24 +0530 Subject: [PATCH 1/6] initial commit - gopal --- README.md | Bin 82 -> 84 bytes app/build.gradle | 3 + app/src/main/AndroidManifest.xml | 14 +- app/src/main/java/com/ar/application/Fence.kt | 7 + .../com/ar/application/GeofenceReceiver.kt | 54 ++++ .../java/com/ar/application/Geofencing.kt | 281 +++++++++++++++++- .../main/res/drawable/ic_fence_detected.xml | 5 + app/src/main/res/values/strings.xml | 1 + build.gradle | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 10 files changed, 353 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/com/ar/application/Fence.kt create mode 100644 app/src/main/java/com/ar/application/GeofenceReceiver.kt create mode 100644 app/src/main/res/drawable/ic_fence_detected.xml diff --git a/README.md b/README.md index a5bcd75f0906f0e9737f8a69b4c24116f1ca1cec..f1cf1806447d2b82a4ae3bf1545410f2fc10f2b0 100644 GIT binary patch delta 11 ScmWFvVg3J4nL%M9vp)bCN(0XT delta 9 QcmWFuV*dZnY9gyY0277-#sB~S diff --git a/app/build.gradle b/app/build.gradle index 85ca93e..bf52d70 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,6 +34,7 @@ android { buildFeatures { viewBinding true } + namespace 'com.ar.application' } dependencies { @@ -43,7 +44,9 @@ dependencies { implementation 'com.google.android.material:material:1.6.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'com.google.android.gms:play-services-maps:18.1.0' + implementation 'com.google.android.gms:play-services-location:20.0.0' implementation 'com.google.firebase:firebase-messaging-ktx:23.0.8' + implementation 'com.google.firebase:firebase-database-ktx:20.0.6' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f39a1b2..dd83df8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,12 +1,13 @@ + xmlns:tools="http://schemas.android.com/tools"> - - - - + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/ar/application/Fence.kt b/app/src/main/java/com/ar/application/Fence.kt new file mode 100644 index 0000000..eb11fdc --- /dev/null +++ b/app/src/main/java/com/ar/application/Fence.kt @@ -0,0 +1,7 @@ +package com.ar.application + +data class Fence( + var key: String = "", + var lat: Double = 0.0, + var lng: Double = 0.0, +) \ No newline at end of file diff --git a/app/src/main/java/com/ar/application/GeofenceReceiver.kt b/app/src/main/java/com/ar/application/GeofenceReceiver.kt new file mode 100644 index 0000000..3834420 --- /dev/null +++ b/app/src/main/java/com/ar/application/GeofenceReceiver.kt @@ -0,0 +1,54 @@ +package com.ar.application + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import com.ar.application.Geofencing.Companion.showNotification +import com.google.android.gms.location.Geofence +import com.google.android.gms.location.GeofencingEvent +import com.google.firebase.database.DataSnapshot +import com.google.firebase.database.DatabaseError +import com.google.firebase.database.ValueEventListener +import com.google.firebase.database.ktx.database +import com.google.firebase.database.ktx.getValue +import com.google.firebase.ktx.Firebase + +class GeofenceReceiver: BroadcastReceiver() { + lateinit var key: String + lateinit var message: String + override fun onReceive(p0: Context?, p1: Intent?) { + if (p0 != null) { + val geofencingEvent = p1?.let { GeofencingEvent.fromIntent(it) } + val geofenceTransition = geofencingEvent?.geofenceTransition + + if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER + || geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) { + if (p1 != null) { + key = p1.getStringExtra("key")!! + message = p1.getStringExtra("message")!! + } + + // retrieving data from database + val database = Firebase.database + val reference = database.getReference("fences") + val fenceListener = object : ValueEventListener { + override fun onDataChange(snapshot: DataSnapshot) { + val fence = snapshot.getValue() + if (fence != null) { + showNotification( + p0.applicationContext, + message + ) + } + } + + override fun onCancelled(error: DatabaseError) { + println("Fence: onCancelled: ${error.details}") + } + } + val child = reference.child(key) + child.addValueEventListener(fenceListener) + } + } + } +} diff --git a/app/src/main/java/com/ar/application/Geofencing.kt b/app/src/main/java/com/ar/application/Geofencing.kt index 35bca36..8880b31 100644 --- a/app/src/main/java/com/ar/application/Geofencing.kt +++ b/app/src/main/java/com/ar/application/Geofencing.kt @@ -1,21 +1,53 @@ package com.ar.application +import android.Manifest +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Color +import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast +import androidx.core.app.ActivityCompat +import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat -import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment +import com.ar.application.databinding.ActivityGeofencingBinding +import com.google.android.gms.location.FusedLocationProviderClient +import com.google.android.gms.location.Geofence +import com.google.android.gms.location.GeofencingClient +import com.google.android.gms.location.GeofencingRequest +import com.google.android.gms.location.LocationServices +import com.google.android.gms.maps.CameraUpdateFactory +import com.google.android.gms.maps.model.CircleOptions import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions -import com.ar.application.databinding.ActivityGeofencingBinding +import com.google.firebase.database.ktx.database +import com.google.firebase.ktx.Firebase +import kotlin.random.Random -class Geofencing : AppCompatActivity(), OnMapReadyCallback { +const val LOCATION_REQUEST_CODE = 123 +const val GEOFENCE_REQUEST_CODE = 456 // only for android version >= 10 +const val CAMERA_ZOOM_LEVEL = 12f +const val GEOFENCE_RADIUS = 500 // change later +const val GEOFENCE_ID = "REMINDER_GEOFENCE_ID" +const val GEOFENCE_EXPIRATION = 10 * 24 * 60 * 60 * 1000 // 10 days, change later +const val GEOFENCE_DWELL_DELAY = 10 * 1000 // 10 secs, change later - private lateinit var mMap: GoogleMap +private val TAG = Geofencing::class.java.simpleName + +class Geofencing : AppCompatActivity(), OnMapReadyCallback { + private lateinit var map: GoogleMap private lateinit var binding: ActivityGeofencingBinding + private lateinit var fusedLocationClient: FusedLocationProviderClient + private lateinit var geofencingClient: GeofencingClient override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -28,7 +60,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { .findFragmentById(R.id.mapGeofence) as SupportMapFragment mapFragment.getMapAsync(this) - + fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) } /** @@ -41,11 +73,240 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { * installed Google Play services and returned to the app. */ override fun onMapReady(googleMap: GoogleMap) { - mMap = googleMap + map = googleMap + map.uiSettings.isZoomControlsEnabled = true + + if (!areLocationPermsGranted()) { + askForLocationPerms() + } + else { + if (ActivityCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_COARSE_LOCATION + ) != PackageManager.PERMISSION_GRANTED) { + askForLocationPerms() + } + map.isMyLocationEnabled = true + + // getting last known location data + fusedLocationClient.lastLocation.addOnSuccessListener { + if (it != null) { + with (map) { + val latLng = LatLng(it.latitude, it.longitude) + addMarker(MarkerOptions().position(latLng)) + moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, CAMERA_ZOOM_LEVEL)) + } + } + else { + with (map) { + addMarker(MarkerOptions().position(LatLng(17.429, 78.455))) + moveCamera(CameraUpdateFactory.newLatLngZoom( + LatLng(17.429, 78.455), CAMERA_ZOOM_LEVEL) + // Panjagutta coordinates + ) + } + TODO("Manually setting the last known location for testing," + + "but that doesn't make sense." + + "So, think of something else.") + } + } + } + createFence(map) + } + + private fun areLocationPermsGranted(): Boolean { // checks if location permissions have been granted + return ContextCompat.checkSelfPermission( + applicationContext, + Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED || + ContextCompat.checkSelfPermission( + applicationContext, + Manifest.permission.ACCESS_COARSE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + } + + private fun askForLocationPerms() { // requests for location permissions + val permissions = mutableListOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + ) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + permissions.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION) + } + + ActivityCompat.requestPermissions( + this, + permissions.toTypedArray(), + LOCATION_REQUEST_CODE, + ) + } + + private fun askForBackgroundLocationPerm() { // requests for only background location + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + ActivityCompat.requestPermissions( + this, + arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), + GEOFENCE_REQUEST_CODE + ) + } + } + + private fun createFence(map: GoogleMap) { // creates the physical, viewable fence; not the actual geofence + map.setOnMapLongClickListener { + map.addMarker( + MarkerOptions().position(it) + )?.showInfoWindow() + map.addCircle( + CircleOptions().center(it) + .strokeColor(Color.argb(1, 0, 0, 0)) + .fillColor(Color.argb(1, 183, 183, 183)) + .radius(GEOFENCE_RADIUS.toDouble()) + ) + map.moveCamera(CameraUpdateFactory.newLatLngZoom( + LatLng(it.latitude, it.longitude), + CAMERA_ZOOM_LEVEL) + ) + + // pushing data (lat & lng of the centre of the fence) to firebase + val database = Firebase.database + val reference = database.getReference("fences") + val key = reference.push().key + if (key != null) { + val fence = Fence(key, it.latitude, it.longitude) + reference.child(key).setValue(fence) + } + createGeofence(it, key!!, geofencingClient) + TODO("Have to communicate with Abhiram and figure out how we're going to" + + "dynamically get coords from the database and create fences accordingly." + + "For now tho, implemented creation of fences when long pressed" + + "on a particular location.") + } + } + + private fun createGeofence(location: LatLng, key: String, geofencingClient: GeofencingClient) { + val geofence = Geofence.Builder() + .setRequestId(GEOFENCE_ID) + .setCircularRegion(location.latitude, location.longitude, GEOFENCE_RADIUS.toFloat()) + .setExpirationDuration(GEOFENCE_EXPIRATION.toLong()) + // defines the lifetime of the geofence + .setTransitionTypes( + Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_DWELL + ) + // transitions of the user when actions are to be triggered + .setLoiteringDelay(GEOFENCE_DWELL_DELAY) + // min duration of user in geofence for action to be triggered + .build() + + val geofenceRequest = GeofencingRequest.Builder() + .setInitialTrigger(Geofence.GEOFENCE_TRANSITION_ENTER) + .addGeofence(geofence) + .build() + + val intent = Intent(this, GeofenceReceiver::class.java) + .putExtra("key", key) + .putExtra("message", "Geofence detected!") + + val pendingIntent = PendingIntent.getBroadcast( + applicationContext, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT + ) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + if (ContextCompat.checkSelfPermission( + applicationContext, + Manifest.permission.ACCESS_BACKGROUND_LOCATION + ) != PackageManager.PERMISSION_GRANTED) { + askForBackgroundLocationPerm() + } + else { + geofencingClient.addGeofences(geofenceRequest, pendingIntent) + } + } + else { + geofencingClient.addGeofences(geofenceRequest, pendingIntent) + } + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (requestCode == GEOFENCE_REQUEST_CODE) { + if (permissions.isNotEmpty() && grantResults[0] != PackageManager.PERMISSION_GRANTED) { + Toast.makeText( + this, + "Please grant background location permission!", + Toast.LENGTH_LONG + ) + .show() + askForBackgroundLocationPerm() + } + } + else if (requestCode == LOCATION_REQUEST_CODE) { + if (permissions.isNotEmpty() && + (grantResults[0] == PackageManager.PERMISSION_GRANTED + || grantResults[1] == PackageManager.PERMISSION_GRANTED)) { + if (ActivityCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_COARSE_LOCATION + ) != PackageManager.PERMISSION_GRANTED) { + askForLocationPerms() + } + map.isMyLocationEnabled = true + onMapReady(map) + } + else { + Toast.makeText( + this, + "Please grant location permissions!", + Toast.LENGTH_LONG + ) + .show() + askForLocationPerms() + } + } + } + + companion object { + fun showNotification(context: Context, message: String) { + val channelID = "FENCE_NOTIFICATION_CHANNEL" + var notifID = 420 + notifID += Random(notifID).nextInt(1, 69) + + val notifBuilder = NotificationCompat.Builder(context.applicationContext, channelID) + .setSmallIcon(R.drawable.ic_fence_detected) + .setContentTitle(context.getString(R.string.app_name)) + .setContentText(message) + .setStyle( + NotificationCompat.BigTextStyle().bigText(message) + ) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + + val notifManager = context.getSystemService(Context.NOTIFICATION_SERVICE) + as NotificationManager + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = NotificationChannel( + channelID, + context.getString(R.string.app_name), + NotificationManager.IMPORTANCE_DEFAULT + ).apply { description = context.getString(R.string.app_name) } - // Add a marker in Sydney and move the camera - val sydney = LatLng(-34.0, 151.0) - mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney")) - mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)) + notifManager.createNotificationChannel(channel) + } + notifManager.notify(notifID, notifBuilder.build()) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_fence_detected.xml b/app/src/main/res/drawable/ic_fence_detected.xml new file mode 100644 index 0000000..11fdbe5 --- /dev/null +++ b/app/src/main/res/drawable/ic_fence_detected.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cd40ee5..16a2a29 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,4 +6,5 @@ Go to Trace Route Page Go to Geo-fencing SOS + MapsActivity \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7ce7085..6581c07 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,11 @@ buildscript { dependencies { - classpath 'com.google.gms:google-services:4.3.13' + classpath 'com.google.gms:google-services:4.3.14' } }// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '7.2.2' apply false - id 'com.android.library' version '7.2.2' apply false + id 'com.android.application' version '7.3.0' apply false + id 'com.android.library' version '7.3.0' apply false id 'org.jetbrains.kotlin.android' version '1.7.10' apply false id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2df3794..aea147c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Sep 09 10:29:15 IST 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME From 771ca21ba508b38716bf9d94eb3945dd7554e98b Mon Sep 17 00:00:00 2001 From: Gopal Matcha Date: Mon, 19 Sep 2022 22:01:38 +0530 Subject: [PATCH 2/6] almost no changes --- app/src/main/java/com/ar/application/Geofencing.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/ar/application/Geofencing.kt b/app/src/main/java/com/ar/application/Geofencing.kt index 8880b31..b40e30f 100644 --- a/app/src/main/java/com/ar/application/Geofencing.kt +++ b/app/src/main/java/com/ar/application/Geofencing.kt @@ -61,6 +61,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { mapFragment.getMapAsync(this) fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) + geofencingClient = LocationServices.getGeofencingClient(this) } /** @@ -120,11 +121,11 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { private fun areLocationPermsGranted(): Boolean { // checks if location permissions have been granted return ContextCompat.checkSelfPermission( - applicationContext, + this, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission( - applicationContext, + this, Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED } @@ -132,7 +133,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { private fun askForLocationPerms() { // requests for location permissions val permissions = mutableListOf( Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION ) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { permissions.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION) @@ -141,7 +142,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { ActivityCompat.requestPermissions( this, permissions.toTypedArray(), - LOCATION_REQUEST_CODE, + LOCATION_REQUEST_CODE ) } From e7fe491732bdb6186de54e620e9457f78508d667 Mon Sep 17 00:00:00 2001 From: Gopal Matcha Date: Tue, 20 Sep 2022 22:15:57 +0530 Subject: [PATCH 3/6] wait --- app/src/main/java/com/ar/application/Geofencing.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/ar/application/Geofencing.kt b/app/src/main/java/com/ar/application/Geofencing.kt index b40e30f..f8c3f78 100644 --- a/app/src/main/java/com/ar/application/Geofencing.kt +++ b/app/src/main/java/com/ar/application/Geofencing.kt @@ -12,6 +12,7 @@ import android.os.Build import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast +import androidx.annotation.RequiresPermission import androidx.core.app.ActivityCompat import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat @@ -41,8 +42,6 @@ const val GEOFENCE_ID = "REMINDER_GEOFENCE_ID" const val GEOFENCE_EXPIRATION = 10 * 24 * 60 * 60 * 1000 // 10 days, change later const val GEOFENCE_DWELL_DELAY = 10 * 1000 // 10 secs, change later -private val TAG = Geofencing::class.java.simpleName - class Geofencing : AppCompatActivity(), OnMapReadyCallback { private lateinit var map: GoogleMap private lateinit var binding: ActivityGeofencingBinding @@ -73,6 +72,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { * it inside the SupportMapFragment. This method will only be triggered once the user has * installed Google Play services and returned to the app. */ + @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) override fun onMapReady(googleMap: GoogleMap) { map = googleMap map.uiSettings.isZoomControlsEnabled = true @@ -156,6 +156,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { } } + @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) private fun createFence(map: GoogleMap) { // creates the physical, viewable fence; not the actual geofence map.setOnMapLongClickListener { map.addMarker( @@ -188,6 +189,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { } } + @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) private fun createGeofence(location: LatLng, key: String, geofencingClient: GeofencingClient) { val geofence = Geofence.Builder() .setRequestId(GEOFENCE_ID) @@ -215,7 +217,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { applicationContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -234,6 +236,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { } } + @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, @@ -245,7 +248,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { Toast.makeText( this, "Please grant background location permission!", - Toast.LENGTH_LONG + Toast.LENGTH_SHORT ) .show() askForBackgroundLocationPerm() @@ -272,7 +275,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { Toast.makeText( this, "Please grant location permissions!", - Toast.LENGTH_LONG + Toast.LENGTH_SHORT ) .show() askForLocationPerms() From dd1bfca91e815ea5a76b4a7e5be272bf369bb65e Mon Sep 17 00:00:00 2001 From: Dhruv Saxena Date: Wed, 21 Sep 2022 10:45:49 +0530 Subject: [PATCH 4/6] Geofence Debug --- .idea/deploymentTargetDropDown.xml | 4 +- app/src/main/AndroidManifest.xml | 2 +- .../java/com/ar/application/Geofencing.kt | 86 ++++++++++++------- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 488604f..956d6fd 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -7,11 +7,11 @@ - + - + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dd83df8..bf56e08 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,7 +33,7 @@ --> + android:value="AIzaSyBesYoZOX1GYDg1n5JySelTKaTPafyfm1w" /> = 10 -const val CAMERA_ZOOM_LEVEL = 12f -const val GEOFENCE_RADIUS = 500 // change later -const val GEOFENCE_ID = "REMINDER_GEOFENCE_ID" -const val GEOFENCE_EXPIRATION = 10 * 24 * 60 * 60 * 1000 // 10 days, change later -const val GEOFENCE_DWELL_DELAY = 10 * 1000 // 10 secs, change later - class Geofencing : AppCompatActivity(), OnMapReadyCallback { + + private val LOCATION_REQUEST_CODE = 123 + private val GEOFENCE_REQUEST_CODE = 456 // only for android version >= 10 + private val CAMERA_ZOOM_LEVEL = 12f + private val GEOFENCE_RADIUS = 500 // change later + private val GEOFENCE_ID = "REMINDER_GEOFENCE_ID" + private val GEOFENCE_EXPIRATION = 10 * 24 * 60 * 60 * 1000 // 10 days, change later + private val GEOFENCE_DWELL_DELAY = 10 * 1000 // 10 secs, change later + private val TAG: String = Geofencing::class.java.simpleName + private lateinit var map: GoogleMap private lateinit var binding: ActivityGeofencingBinding private lateinit var fusedLocationClient: FusedLocationProviderClient @@ -72,7 +74,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { * it inside the SupportMapFragment. This method will only be triggered once the user has * installed Google Play services and returned to the app. */ - @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) + //@RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) override fun onMapReady(googleMap: GoogleMap) { map = googleMap map.uiSettings.isZoomControlsEnabled = true @@ -89,9 +91,9 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { this, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) { - askForLocationPerms() +// askForLocationPerms() } - map.isMyLocationEnabled = true + this.map.isMyLocationEnabled = true // getting last known location data fusedLocationClient.lastLocation.addOnSuccessListener { @@ -116,7 +118,8 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { } } } - createFence(map) + setLongClick(map) + setPoiClick(map) } private fun areLocationPermsGranted(): Boolean { // checks if location permissions have been granted @@ -156,36 +159,55 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { } } - @RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION) - private fun createFence(map: GoogleMap) { // creates the physical, viewable fence; not the actual geofence - map.setOnMapLongClickListener { + private fun setPoiClick(map: GoogleMap) { + map.setOnPoiClickListener { poi -> map.addMarker( - MarkerOptions().position(it) + MarkerOptions() + .position(poi.latLng) + .title(poi.name) + )?.showInfoWindow() + + //scheduleJob() + } + } + + private fun setLongClick(map: GoogleMap) { + map.setOnMapLongClickListener { latlng -> + + map.addMarker( + MarkerOptions().position(latlng) + .title("Current location") )?.showInfoWindow() map.addCircle( - CircleOptions().center(it) - .strokeColor(Color.argb(1, 0, 0, 0)) - .fillColor(Color.argb(1, 183, 183, 183)) + CircleOptions() + .center(latlng) + .strokeColor(Color.argb(50, 70, 70, 70)) + .fillColor(Color.argb(70, 150, 150, 150)) .radius(GEOFENCE_RADIUS.toDouble()) ) - map.moveCamera(CameraUpdateFactory.newLatLngZoom( - LatLng(it.latitude, it.longitude), - CAMERA_ZOOM_LEVEL) - ) + map.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, CAMERA_ZOOM_LEVEL)) - // pushing data (lat & lng of the centre of the fence) to firebase val database = Firebase.database - val reference = database.getReference("fences") + val reference = database.getReference("reminders") val key = reference.push().key if (key != null) { - val fence = Fence(key, it.latitude, it.longitude) - reference.child(key).setValue(fence) + val reminder = Fence(key, latlng.latitude, latlng.longitude) + reference.child(key).setValue(reminder) + } + if (ActivityCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED + ) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. } - createGeofence(it, key!!, geofencingClient) - TODO("Have to communicate with Abhiram and figure out how we're going to" + - "dynamically get coords from the database and create fences accordingly." + - "For now tho, implemented creation of fences when long pressed" + - "on a particular location.") + createGeofence(latlng, key!!, geofencingClient) } } From eae85cbb4b742c26e18c2c6072d6ec550c85968f Mon Sep 17 00:00:00 2001 From: Gopal Matcha Date: Wed, 21 Sep 2022 11:14:16 +0530 Subject: [PATCH 5/6] inceased zoom level, ref change --- app/src/main/java/com/ar/application/Geofencing.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/ar/application/Geofencing.kt b/app/src/main/java/com/ar/application/Geofencing.kt index 6576662..600c8c9 100644 --- a/app/src/main/java/com/ar/application/Geofencing.kt +++ b/app/src/main/java/com/ar/application/Geofencing.kt @@ -38,7 +38,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { private val LOCATION_REQUEST_CODE = 123 private val GEOFENCE_REQUEST_CODE = 456 // only for android version >= 10 - private val CAMERA_ZOOM_LEVEL = 12f + private val CAMERA_ZOOM_LEVEL = 18f private val GEOFENCE_RADIUS = 500 // change later private val GEOFENCE_ID = "REMINDER_GEOFENCE_ID" private val GEOFENCE_EXPIRATION = 10 * 24 * 60 * 60 * 1000 // 10 days, change later @@ -173,7 +173,6 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { private fun setLongClick(map: GoogleMap) { map.setOnMapLongClickListener { latlng -> - map.addMarker( MarkerOptions().position(latlng) .title("Current location") @@ -188,7 +187,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { map.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, CAMERA_ZOOM_LEVEL)) val database = Firebase.database - val reference = database.getReference("reminders") + val reference = database.getReference("fences") val key = reference.push().key if (key != null) { val reminder = Fence(key, latlng.latitude, latlng.longitude) From a4b47f4ec05f870ae919eb65e050a4b853281936 Mon Sep 17 00:00:00 2001 From: Gopal Matcha Date: Wed, 21 Sep 2022 11:16:47 +0530 Subject: [PATCH 6/6] nothing --- app/src/main/java/com/ar/application/Geofencing.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/ar/application/Geofencing.kt b/app/src/main/java/com/ar/application/Geofencing.kt index 600c8c9..3e6d3fc 100644 --- a/app/src/main/java/com/ar/application/Geofencing.kt +++ b/app/src/main/java/com/ar/application/Geofencing.kt @@ -175,7 +175,7 @@ class Geofencing : AppCompatActivity(), OnMapReadyCallback { map.setOnMapLongClickListener { latlng -> map.addMarker( MarkerOptions().position(latlng) - .title("Current location") + .title("Geofence centre") )?.showInfoWindow() map.addCircle( CircleOptions()