2017-08-30 6 views
0

Geofence ne fonctionne pas dans Kotlin, même si le même code fonctionne en Java. Je suis débutant à Kotlin donc pas en mesure de comprendre le problème. En fait, je fais appel MainGeofence.kt classe de service d'une activité MainActivity suivante est le codeGeofence ne fonctionne pas dans Kotlin

MainGeofence.kt

public class MainGeofence : IntentService("MyService"), LocationListener { 

    internal var mGeofencePendingIntent: PendingIntent? = null 
    private var mGeofenceList: ArrayList<Geofence>? = null 
    private var mGoogleApiClient: GoogleApiClient? = null 
    val TAG = "Activity" 
    internal lateinit var mLocationRequest: LocationRequest 
    internal var currentLatitude = <<lat value 
    internal var currentLongitude = <<long value 

    override fun onCreate() { 
     super.onCreate() 
    } 

    override fun onHandleIntent(p0: Intent?) { 
     mGeofenceList = ArrayList<Geofence>() 

     if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) 
       == ConnectionResult.SUCCESS) { 
      initGoogleAPIClient() 

      createGeofences(currentLatitude, currentLongitude) 
     } else { 
      Log.e(TAG, "Your Device doesn't support Google Play Services.") 
     } 

     mLocationRequest = LocationRequest.create() 
       .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
       .setInterval(1 * 1000) 
       .setFastestInterval(1 * 1000) 
    } 

    public fun initGoogleAPIClient(): Unit { 
     mGoogleApiClient = GoogleApiClient.Builder(this) 
       .addApi(API) 
       .addConnectionCallbacks(connectionAddListener) 
       .addOnConnectionFailedListener(connectionFailedListener) 
       .build() 
     mGoogleApiClient?.connect() 
    } 

    private val connectionAddListener = object : GoogleApiClient.ConnectionCallbacks { 
     @SuppressLint("MissingPermission") 
     override fun onConnected(bundle: Bundle?) { 
      Log.i(TAG, "onConnected") 

      @SuppressLint("MissingPermission") 
      val location = FusedLocationApi.getLastLocation(mGoogleApiClient) 

      if (location == null) { 
       FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, [email protected]) 
      } else { 
       //If everything went fine lets get latitude and longitude 
       currentLatitude = location.latitude 
       currentLongitude = location.longitude 

       Log.i(TAG, currentLatitude.toString() + " WORKS " + currentLongitude) 

       //createGeofences(currentLatitude, currentLongitude); 
       //registerGeofences(mGeofenceList); 
      } 

      try { 
       GeofencingApi.addGeofences(
         mGoogleApiClient, 
         getGeofencingRequest(), 
         getGeofencePendingIntent() 
       ).setResultCallback(ResultCallback<Status> { status -> 
        if (status.isSuccess) { 
         Log.i(TAG, "Saving Geofence") 

        } else { 
         Log.e(TAG, "Registering geofence failed: " + status.statusMessage + 
           " : " + status.statusCode) 
        } 
       }) 

      } catch (securityException: SecurityException) { 
       // Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission. 
       Log.e(TAG, "Error") 
      } 

     } 

     override fun onConnectionSuspended(i: Int) { 

      Log.e(TAG, "onConnectionSuspended") 

     } 
    } 

    /** 
    * Create a Geofence list 
    */ 
    fun createGeofences(latitude: Double, longitude: Double) { 
     val id = UUID.randomUUID().toString() 
     println("latnlon " + latitude + " " + longitude) 
     val fence = Geofence.Builder() 
       .setRequestId(id) 
       .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT) 
       .setCircularRegion(latitude, longitude, 50f) 
       .setExpirationDuration(Geofence.NEVER_EXPIRE) 
       .build() 
     mGeofenceList?.add(fence) 
    } 

    private fun getGeofencingRequest(): GeofencingRequest { 
     val builder = GeofencingRequest.Builder() 
     builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER) 
     builder.addGeofences(mGeofenceList) 
     return builder.build() 
    } 

    private fun getGeofencePendingIntent(): PendingIntent { 
     // Reuse the PendingIntent if we already have it. 
     if (mGeofencePendingIntent != null) { 
      return mGeofencePendingIntent!! 
     } 
     val intent = Intent(this, GeofenceIntentService::class.java) 
     // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when 
     // calling addGeofences() and removeGeofences(). 
     return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) 
    } 

    private val connectionFailedListener = GoogleApiClient.OnConnectionFailedListener { Log.e(TAG, "onConnectionFailed") } 

    override fun onLocationChanged(location: Location?) { 

     if (location != null) { 
      currentLatitude = location.latitude 
      currentLongitude = location.longitude 
      Log.i(TAG, "onLocationChanged") 
     } 
    } 

} 

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 
     dummyBtn = findViewById(R.id.dummyBtn) 
     dummyTv = findViewById(R.id.dummyTv) 

     dummyBtn.setOnClickListener(View.OnClickListener { 
      //   startLocationUpdates() 
      startService(Intent(this, MainGeofence::class.java)) 
       ... 
     }) 
       .... 
    } 

et GeofenceIntentService.kt

public class GeofenceIntentService : IntentService("GeofenceIntentService") { 

    private final var TAG: String = "Geofence" 

    override fun onHandleIntent(intent: Intent?) { 
     Log.i(TAG, "onHandleIntent") 
     val geofencingEvent = fromIntent(intent) 
     if (geofencingEvent.hasError()) { 
      Log.e(TAG, "Goefencing Error " + geofencingEvent.errorCode) 
      return 
     } 
     //Create AudioManager object to change phone profile 
     var am: AudioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager 
     // Get the transition type. 
     val geofenceTransition = geofencingEvent.geofenceTransition 
     Log.i(TAG, "geofenceTransition = " + geofenceTransition + " Enter : " + 
       Geofence.GEOFENCE_TRANSITION_ENTER + "Exit : " + Geofence.GEOFENCE_TRANSITION_EXIT) 
     when (geofenceTransition) { 

      Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_DWELL -> { 
       showNotification("Entered", "Entered the Location") 
       am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE) //put ringer to vibration 
      } 
      Geofence.GEOFENCE_TRANSITION_EXIT -> { 
       showNotification("Exited", "Exited the Location") 
       am.setRingerMode(AudioManager.RINGER_MODE_NORMAL) //put ringer to normal 
      } 
      else -> { 
       println("oh cow's eye! something bad happened!") 
       Log.e(TAG, "Error ") 
      } 
     } 

    } 

    fun showNotification(text: String, bigText: String) { 

     // 1. Create a NotificationManager 
     val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager 

     // 2. Create a PendingIntent for AllGeofencesActivity 
     val intent = Intent(this, MainActivity::class.java) 
     intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) 
     val pendingNotificationIntent = PendingIntent.getActivity(this, 0, 
       intent, PendingIntent.FLAG_UPDATE_CURRENT) 

     // 3. Create and send a notification 
     val notification = NotificationCompat.Builder(this) 
       .setSmallIcon(R.mipmap.ic_launcher) 
       .setContentTitle("Title") 
       .setContentText(text) 
       .setContentIntent(pendingNotificationIntent) 
       .setStyle(NotificationCompat.BigTextStyle().bigText(bigText)) 
       .setPriority(NotificationCompat.PRIORITY_HIGH) 
       .setAutoCancel(true) 
       .build() 
     notificationManager.notify(0, notification) 
    } 

} 

Les points de Geofence se déclenchent rarement et cela aussi seulement Exit. Mais le code fonctionne parfaitement en Java. Est-ce un problème de langage ou de mise en œuvre? L'aide est grandement appréciée!

Répondre

0

Je pense que votre problème est la clause WHEN dans onHandleIntent

Vous avez essentiellement

when (x) { 
     A or B -> { ... } 
     C -> { ... } 
     else -> { ... } 
} 

Je pense que Geofence.GEOFENCE_TRANSITION_ENTER etc sont Int types si vous finissent appeler « ou au niveau du bit » sur leur utilisation infix fun or(other: Int): Int (source) .

Je pense que ce que vous voulez vraiment est:

when (x) { 
     A, B -> { ... } 
     C -> { ... } 
     else -> { ... } 
} 
+0

a marché! Bien que je l'ai essayé, mais je ne pouvais pas le tester correctement. –