원본출처: 티스토리 바로가기
지오펜싱 트리거 되는 위치의 명칭 표시
지오펜스 앱을 수정하면서 또 하나를 찾았습니다. 구현해 보고 싶었던 것은 지오펜싱에서 찾은 위치에 대한 알림을 구현할 때 현재 내가 도착한 위치가 어떤 것 때문에 표시가 되고 있는지 알고 싶다는 것입니다. 물론 잘 아시는 분들은 이미 찾으셨을리라고 생각이 되지만, 이제 구현을 해 가고 있는 분들을 위해서 기억을 남겨 두고자 합니다.
import android.annotation.SuppressLint import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Build import android.os.Bundle import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.billcoreatech.ontheway801.MainComposeActivity import com.billcoreatech.ontheway801.R import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent class GeofenceBroadcastReceiver : BroadcastReceiver() { companion object { var TAG = "GeofenceBroadcastReceiver" internal const val ACTION_GEOFENCE_EVENT = "action.ACTION_GEOFENCE_EVENT" } override fun onReceive(context: Context, intent: Intent) { if (intent.action == ACTION_GEOFENCE_EVENT) { Log.e(TAG, "onReceive ...") val geofencingEvent = GeofencingEvent.fromIntent(intent) // Test that the reported transition was of interest. if (geofencingEvent != null) { if (geofencingEvent.hasError()) { val errorMessage = GeofenceStatusCodes.getStatusCodeString(geofencingEvent.errorCode) Log.e("GeofenceBR", errorMessage) return } // 트리거된 위치에 대한 정보를 취득해 보기 위해서... var geofenceList = geofencingEvent.triggeringGeofences var whereString = " " if (geofenceList != null) { for (geofence in geofenceList) { Log.e(TAG, "requestId = ${geofence.requestId}") whereString += "${geofence.requestId} " } } when(val geofenceTransition = geofencingEvent.geofenceTransition) { Geofence.GEOFENCE_TRANSITION_DWELL -> { if (context != null) { sendNotification(context, context.getString(R.string.DWell) + "[${whereString}]") } Log.e(TAG, context.getString(R.string.DWell)) } Geofence.GEOFENCE_TRANSITION_ENTER -> { if (context != null) { sendNotification(context, context.getString(R.string.Enter) + "[${whereString}]") } Log.e(TAG, "Entered") } Geofence.GEOFENCE_TRANSITION_EXIT -> { if (context != null) { sendNotification(context, context.getString(R.string.Exit) + "[${whereString}]") } Log.e(TAG, "Exit") } else -> { if (context != null) { sendNotification(context, "Geofence ${geofenceTransition.hashCode()}") } Log.e(TAG, "geofenceTransition = ${geofenceTransition.hashCode()}") } } } else { Log.e(TAG, "geofencingEvent is null...") } } } @SuppressLint("MissingPermission") private fun sendNotification(context : Context, messageBody: String) { val intent = Intent(context, MainComposeActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) val extras = Bundle() extras.putString("MSGRCV", messageBody) intent.putExtras(extras) val pendingIntent = PendingIntent.getActivity( context, 0 /* Request code */, intent, PendingIntent.FLAG_MUTABLE ) val channelId: String = context.getString(R.string.default_notification_channel_id) val channelName: CharSequence = context.getString(R.string.default_notification_channel_name) val importance = NotificationManager.IMPORTANCE_DEFAULT val notificationChannel = NotificationChannel(channelId, channelName, importance) notificationChannel.enableLights(true) notificationChannel.lightColor = Color.RED notificationChannel.enableVibration(true) notificationChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) val wearNotifyManager = NotificationManagerCompat.from(context) val wearNotifyBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_locationnote_foreground) .setContentTitle(context.getString(R.string.app_name)) .setContentText(messageBody) .setAutoCancel(true) .setContentIntent(pendingIntent) .setVibrate(longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)) .setDefaults(-1) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { wearNotifyManager.createNotificationChannel(notificationChannel) } wearNotifyManager.notify(0, wearNotifyBuilder.build()) } }
코드가 구현된 예제 화면
위에 기술된 전체 소스의 내용과 같이 트리거 되는 위치에 대한 정보를 취해서 그곳에 대한 알림을 전달하는 방식으로 내가 지정한 위치에 도달하였을 때 명칭을 표시하는 방법을 구현해 보게 됩니다.

트리거 명칭 전달 방법
참 저렇게 trigger 되게 하는 부분은 다음과 같이 적용했습니다. 아래처럼 geofenceList.add을 하게 되는 경우 builder을 설정하면서 setRequestId에 넣는 값을 표시하고자 하는 장소의 명칭을 넣었습니다. 그러면 위에 기술된 코드에서는 getRequestId로 값을 가져와 현재 표시되는 위치의 명칭을 보여주는 기능을 구현할 수 있습니다.
private fun doAddGeoFence(documents: ResponseBean.Documents) { geofenceList.clear() geofenceList.add(Geofence.Builder() // Set the request ID of the geofence. This is a string to identify this // geofence. .setRequestId(documents.placeName) // Set the circular region of this geofence. .setCircularRegion( documents.posY, documents.posX, sp.getFloat("aroundArea", 300f) ) // Set the expiration duration of the geofence. This geofence gets automatically // removed after this period of time. .setExpirationDuration(sp.getFloat("geofenceTime", 1.0f).toLong() * 60 * 60 * 1000) // Set the transition types of interest. Alerts are only generated for these // transition. We track entry and exit transitions in this sample. .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT) // Create the geofence. .build()) geofencingClient.addGeofences(getGeofencingRequest(), geofencePendingIntent).run { addOnSuccessListener { Log.e(TAG, "addOnSuccessListener") showSnackbar(this@MainComposeActivity, R.string.add_geofences, R.string.geofences_added, View.OnClickListener { var dbHandler = DBHandler.open(this@MainComposeActivity) var geoBean = GeoDataBean( 0, documents.placeName, documents.posY, documents.posX, documents.addressName, "Y" ) dbHandler.insert(geoBean) dbHandler.close() } ) } addOnFailureListener { // Failed to add geofences // ... Log.e(TAG, "addOnFailureListener ${it.message}") } } }
이상으로 구현 예시는 정리를 마치도록 하겠습니다. 이렇게 구현 되는 앱은 다 정리가 되면 playstore에 게시할 예정입니다.
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
댓글
댓글 쓰기