2013-05-28 26 views
6

Sto sviluppando un'app per Android con geofence che è stata rilasciata in quest'anno.google play geofence onHandleIntent

La mia comprensione è quando gli utenti entrano (o fuori) della recinzione dovrebbe innescare onHandleIntent metodo Tuttavia, ho difficoltà ad innescare il metodo onHandleIntent

Ho controllato per 3 giorni per capirlo, ma ho Evetually non poteva.

quindi ho bisogno dell'aiuto di nessuno.

c'è il mio codice Spero davvero che qualcuno possa darmi una mano.

///// MainActivity 

    package com.example.geofence; 


    import java.util.ArrayList; 
    import java.util.List; 

    import android.app.PendingIntent; 
    import android.content.BroadcastReceiver; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.content.IntentFilter; 
    import android.os.Bundle; 
    import android.support.v4.app.FragmentActivity; 
    import android.support.v4.content.LocalBroadcastManager; 
    import android.text.TextUtils; 
    import android.util.Log; 

    import android.widget.Toast; 

    import com.google.android.gms.common.ConnectionResult; 
    import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; 
    import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; 
    import com.google.android.gms.common.GooglePlayServicesUtil; 
    import com.google.android.gms.location.Geofence; 
    import com.google.android.gms.location.LocationClient; 
    import com.google.android.gms.location.LocationClient.OnAddGeofencesResultListener; 

    import com.google.android.gms.location.LocationRequest; 
    import com.google.android.gms.location.LocationStatusCodes; 

    public class MainActivity extends FragmentActivity implements 
             ConnectionCallbacks, 
             OnConnectionFailedListener, 
             OnAddGeofencesResultListener 
             { 
    private IntentFilter mIntentFilter; 
    private LocationClient locationClient; 
    private LocationRequest locatRequest; 

    private PendingIntent intent; 
    private List<Geofence> mGeoList; 
    private Context mContext; 
    private Geofence companyLocation; 
    private GeofenceSampleReceiver mBroadcastReceiver; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mContext = this; 

     locatRequest = null; 
     mGeoList = new ArrayList<Geofence>(); 

     intent = null; 
     locationClient = new LocationClient(this,this,this); 

     mIntentFilter = new IntentFilter(); 
     mIntentFilter.addAction("com.example.geofence.ACTION_GEOFENCES_ADDED"); 
     mIntentFilter.addCategory("com.example.geofence.CATEGORY_LOCATION_SERVICES"); 
     mBroadcastReceiver = new GeofenceSampleReceiver(); 
    } 




    @Override 
    protected void onStart() { 

     companyLocation = new Geofence.Builder() 
     .setRequestId("1") 
     .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) 
     .setCircularRegion(
       49.220531, -122.986772, (float)50) 
     .setExpirationDuration(Geofence.NEVER_EXPIRE) 
     .build(); 

     mGeoList.add(companyLocation); 
     locationClient.connect(); 
     super.onStart();  

    } 



    @Override 
    public void onConnected(Bundle arg0) { 
     // TODO Auto-generated method stub 
     intent = getTransitionPendingIntent(); 

     locatRequest = LocationRequest.create(); 
      locatRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
      locatRequest.setInterval(5000); 

      try{ 
       addGeofence(); 
      }catch(UnsupportedOperationException e){ 
      Toast.makeText(this, "add_geofences_already_requested_error", 
       Toast.LENGTH_LONG).show(); 
      } 
     // locationClient.requestLocationUpdates(locatRequest, intent); 


    } 

    public void addGeofence(){ 
     locationClient.addGeofences(mGeoList,intent , this); 

    } 

    private PendingIntent getTransitionPendingIntent() { 
      // Create an explicit Intent 
      Intent localIntent = new Intent(this, 
        ReceiveTransitionsIntentService.class); 
      /* 
      * Return the PendingIntent 
      */ 
      return PendingIntent.getService(
        this, 
        0, 
        localIntent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 
    } 






    @Override 
    protected void onStop() { 

      locationClient.disconnect(); 
      super.onStop(); 

    } 

    @Override 
    public void onAddGeofencesResult(int statusCode, String[] geofenceRequestIds) { 
     // TODO Auto-generated method stub 
     Intent broadcastIntent = new Intent(); 

     if(LocationStatusCodes.SUCCESS == statusCode){ 
      Toast.makeText(this, "Success", Toast.LENGTH_SHORT).show(); 

    broadcastIntent.setAction("com.example.android.geofence.ACTION_GEOFENCES_ADDED") 
          .addCategory("com.example.android.geofence.CATEGORY_LOCATION_SERVICES") 
            .putExtra("com.example.android.geofence.EXTRA_GEOFENCE_STATUS","test"); 
     } 
     else{ 
      Toast.makeText(this, "AddGeoError", Toast.LENGTH_SHORT).show(); 
     } 

     LocalBroadcastManager.getInstance(mContext).sendBroadcast(broadcastIntent); 

    } 



    @Override 
    public void onConnectionFailed(ConnectionResult arg0) {  // TODO Auto-generated method stub 
     int code = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 
     switch(code){ 

       case ConnectionResult.SERVICE_MISSING :{ 
        Toast.makeText(this, "SERVICE_MISSING " + code + " ConnectionResult.SERVICE_MISSING " +ConnectionResult.SERVICE_MISSING, Toast.LENGTH_SHORT).show(); 
        break; 

       } 
       case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:{ 

        Toast.makeText(this, "SERVICE_VERSION_UPDATE_REQUIRED " + code + " ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED " + ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED, Toast.LENGTH_SHORT).show(); 

        break; 
       } 
       default:{ 
        Toast.makeText(this, "start " + code, Toast.LENGTH_SHORT).show(); 
       } 

      } 
    } 



    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
    } 



    @Override 
    protected void onPause() { 
     // TODO Auto-generated method stub 
     super.onPause(); 
    } 



    @Override 
    protected void onResume() { 
     // TODO Auto-generated method stub 
     LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, mIntentFilter); 
     //locationClient.connect(); 
     super.onResume(); 
    } 


    @Override 
    public void onDisconnected() { 
     // TODO Auto-generated method stub 
     locationClient = null; 
    } 

    /* 
    * Handle results returned to this Activity by other Activities started with 
    * startActivityForResult(). In particular, the method onConnectionFailed() in 
    * GeofenceRemover and GeofenceRequester may call startResolutionForResult() to 
    * start an Activity that handles Google Play services problems. The result of this 
    * call returns here, to onActivityResult. 
    * calls 
    */ 

    @Override 
    protected void onActivityResult(
       int requestCode, int resultCode, Intent data) { 
    } 




    /** 
    * Define a Broadcast receiver that receives updates from connection listeners and 
    * the geofence transition service. 
    */ 
    public class GeofenceSampleReceiver extends BroadcastReceiver { 
     /* 
     * Define the required method for broadcast receivers 
     * This method is invoked when a broadcast Intent triggers the receiver 
     */ 
     @Override 
     public void onReceive(Context context, Intent intent) { 

      // Check the action code and determine what to do 
      String action = intent.getAction(); 

      // Intent contains information about errors in adding or removing geofences 
     if (TextUtils.equals(action, "com.example.geofence.ACTION_GEOFENCES_ADDED")) { 

       handleGeofenceStatus(context, intent); 

      // Intent contains information about a geofence transition 
      } else if (TextUtils.equals(action, "com.example.geofence.ACTION_GEOFENCE_TRANSITION")) { 

       handleGeofenceTransition(context, intent); 

      // The Intent contained an invalid action 
      } else { 

       Toast.makeText(context,"error", Toast.LENGTH_LONG).show(); 
      } 
     } 

     /** 
     * If you want to display a UI message about adding or removing geofences, put it here. 
     * 
     * @param context A Context for this component 
     * @param intent The received broadcast Intent 
     */ 
     private void handleGeofenceStatus(Context context, Intent intent) { 

     } 

     /** 
     * Report geofence transitions to the UI 
     * 
     * @param context A Context for this component 
     * @param intent The Intent containing the transition 
     */ 
     private void handleGeofenceTransition(Context context, Intent intent) { 
      /* 
      * If you want to change the UI when a transition occurs, put the code 
      * here. The current design of the app uses a notification to inform the 
      * user that a transition has occurred. 
      */ 
     } 

     /** 
     * Report addition or removal errors to the UI, using a Toast 
     * 
     * @param intent A broadcast Intent sent by ReceiveTransitionsIntentService 
     */ 
     private void handleGeofenceError(Context context, Intent intent) { 

     } 
    } 


} 



///// ReceiveTransitionsIntentService 

    package com.example.geofence; 

    import java.util.List; 

    import android.app.IntentService; 
    import android.app.NotificationManager; 
    import android.app.PendingIntent; 
    import android.content.Context; 
    import android.content.Intent; 
    import android.support.v4.app.NotificationCompat; 
    import android.support.v4.app.TaskStackBuilder; 
    import android.util.Log; 
    import android.widget.Toast; 

    import com.google.android.gms.location.Geofence; 
    import com.google.android.gms.location.LocationClient; 

    public class ReceiveTransitionsIntentService extends IntentService { 

    /** 
    * Sets an identifier for the service 
    */ 
    private Context mContext; 
    public ReceiveTransitionsIntentService(Context c) { 

     super("ReceiveTransitionsIntentService"); 
     mContext =c; 
    } 

    /** 
    * Handles incoming intents 
    *@param intent The Intent sent by Location Services. This 
    * Intent is provided 
    * to Location Services (inside a PendingIntent) when you call 
    * addGeofences() 
    */ 
    @Override 
    protected void onHandleIntent(Intent intent) { 
     // First check for errors 

     //Toast.makeText(mContext, "onHandleIntent", Toast.LENGTH_LONG).show(); 
     if (LocationClient.hasError(intent)) { 
      // Get the error code with a static method 
      int errorCode = LocationClient.getErrorCode(intent); 
      // Log the error 
      Log.e("ReceiveTransitionsIntentService", 
        "Location Services error: " + 
        Integer.toString(errorCode)); 
      /* 
      * You can also send the error code to an Activity or 
      * Fragment with a broadcast Intent 
      */ 
     /* 
     * If there's no error, get the transition type and the IDs 
     * of the geofence or geofences that triggered the transition 
     */ 
     } else { 


       int transitionType = LocationClient.getGeofenceTransition(intent); 
      if(transitionType == Geofence.GEOFENCE_TRANSITION_ENTER || 
        transitionType == Geofence.GEOFENCE_TRANSITION_EXIT){ 
       List<Geofence> geofences = LocationClient.getTriggeringGeofences(intent); 
       String[] geofenceIds = new String [geofences.size()]; 
       for(int i = 0; i <geofences.size(); i++){ 
        geofenceIds[i] = geofences.get(i).getRequestId(); 
       } 
       String ids = "1"; 
       String transition = ((transitionType == Geofence.GEOFENCE_TRANSITION_ENTER) ?"you are in":"you are out"); 
       Toast.makeText(mContext, transition, Toast.LENGTH_LONG).show(); 

       sendNotification(transition,ids); 
       //FOR THE NOTIFICATION. 

       //NotificationManager mNotificationManager = 
        //  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

      } 




     } 
    } 




    private void sendNotification(String transitionType, String ids) { 

     // Create an explicit content Intent that starts the main Activity 
     Intent notificationIntent = 
       new Intent(getApplicationContext(),MainActivity.class); 

     // Construct a task stack 
     TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 

     // Adds the main Activity to the task stack as the parent 
     stackBuilder.addParentStack(MainActivity.class); 

     // Push the content Intent onto the stack 
     stackBuilder.addNextIntent(notificationIntent); 

     // Get a PendingIntent containing the entire back stack 
     PendingIntent notificationPendingIntent = 
       stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

     // Get a notification builder that's compatible with platform versions >= 4 
     NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 

     // Set the notification contents 
     builder.setSmallIcon(R.drawable.ic_notification) 
       .setContentTitle(
         transitionType+ " geofence_transition_notification_title " +ids) 
       .setContentIntent(notificationPendingIntent); 

     // Get an instance of the Notification manager 
     NotificationManager mNotificationManager = 
      (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 

     // Issue the notification 
     mNotificationManager.notify(0, builder.build()); 
    } 



} 
+0

e sul mio Manife st ho -service android: exported = "false" android: name = "com.example.geofence.ReceiveTransitionsIntentService" e uses-permission android: name = "android.permission.ACCESS_FINE_LOCATION" – user1979727

+0

Perché hai pubblicato l'intero codice attività ? È troppo da leggere. Indicaci semplicemente il frammento di problema pertinente. –

risposta

0

Il raggio è impostato su 50 il che significa che è necessario percorrere 50 metri dalla posizione per attivare la maniglia. Hai provato a utilizzare un raggio di 2 metri?

+0

Sì, ho avuto così tante prove con raduis diversi come 2, 5, 10, 1000 metri. Ma non funziona mai correttamente. – user1979727

+0

Ho avuto lo stesso problema e dopo due giorni ha iniziato a funzionare ... Le transizioni sembrano richiedere molto tempo per registrarsi. Alcune cose; controlla che IntentService sia in esecuzione guardando le Impostazioni del telefono-> App-> In esecuzione. Dovrebbe esserci un servizio google in più da qualche parte. Provare a configurare IntentService da onAddedGeofence ed emettere qualcosa nel ricevitore broadcast per verificare che tutto stia collegandosi correttamente. Se tutto va bene, la tua app potrebbe non essere configurata per gestire onPause/stop, quindi tieni il telefono acceso con l'app aperta per 5 minuti dopo aver lasciato una recinzione. – Njall

-1
return PendingIntent.getService(
        this, 
        0, 
        localIntent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 

dovrebbe cambiare a:

return PendingIntent.getBroadcast(
        this, 
        0, 
        localIntent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 
0

nel metodo onCreate(), è necessario creare un'istanza della GoogleApiClient:

mApiClient = new GoogleApiClient.Builder(this) 
      .addApi(LocationServices.API) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .build(); 

    mApiClient.connect(); 
0

il problema è avete bisogno di un LocationRequest al monitoraggio geofence posizione ...

Se si utilizza google ma ps allo stesso tempo. Il tuo monitoraggio geofisico funzionerà! perché google maps fanno LocationRequest e geofence lo vedono ...

Quindi se avete bisogno di essere autonomi nel geofence monitoraggio è necessario fare un gestore LocationRequest ...

Google Api LocationRequest

Esempio Codice

FusedLocationProviderClient fusedLocationProviderClient = new FusedLocationProviderClient(activity); 
    fusedLocationProviderClient.requestLocationUpdates(getLocationRequest(), getPendingIntent()); 


private LocationRequest getLocationRequest() { 
    LocationRequest mLocationRequest = new LocationRequest(); 

    mLocationRequest.setInterval(10000); 
    mLocationRequest.setFastestInterval(5000); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    return mLocationRequest; 
} 

private PendingIntent getPendingIntent() { 
    // Reuse the PendingIntent if we already have it. 
    Log.e(TAG, "Creating Monitoring Geofence..."); 
    if (mGeofencePendingIntent != null) { 
     return mGeofencePendingIntent; 
    } 

    Intent intent = new Intent(activity, LocationService.class); 
    // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when 
    // calling addGeofencesTask() and removeGeofences(). 
    mGeofencePendingIntent = PendingIntent.getService(activity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    return mGeofencePendingIntent; 
} 

In questo codice si fa una richiesta di posizione a 10 secondi ... E il monitoraggio geofisico ogni 10 secondi zona geo ...

Problemi correlati