2013-05-28 32 views
6

Tôi đang phát triển ứng dụng android với geofence được phát hành trong năm nay.google play geofence onHandleIntent

hiểu biết của tôi là khi người dùng nhận được vào (hoặc rút ra khỏi) hàng rào cần kích hoạt onHandleIntent phương pháp Tuy nhiên, tôi gặp khó khăn để kích hoạt phương pháp onHandleIntent

Tôi đã kiểm tra trong 3 ngày để con nó ra nhưng tôi evetually có thể không.

vì vậy tôi cần sự giúp đỡ của bất kỳ ai.

có mã của tôi Tôi thực sự hy vọng bất kỳ ai cũng có thể giúp tôi.

///// 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

và trên Manife của tôi Tôi có dịch vụ android: export = "false" android: name = "com.example.geofence.ReceiveTransitionsIntentService" và sử dụng quyền android: name = "android.permission.ACCESS_FINE_LOCATION" – user1979727

+0

Tại sao bạn đăng toàn bộ mã Hoạt động của mình ? Đó là quá nhiều để đọc. Chỉ cần cho chúng tôi biết đoạn mã vấn đề có liên quan. –

Trả lời

0

Bán kính của bạn được đặt thành 50 có nghĩa là bạn cần đi 50 m từ vị trí của mình để kích hoạt tay cầm. Bạn đã thử sử dụng bán kính 2m chưa?

+0

Có, tôi đã có rất nhiều thử nghiệm với các loại raduis khác nhau như 2, 5, 10, 1000 mét. Nhưng nó không bao giờ chạy đúng. – user1979727

+0

Tôi đã có cùng một vấn đề và sau hai ngày nó bắt đầu hoạt động ... Quá trình chuyển đổi có vẻ mất khá nhiều thời gian để đăng ký. Một vài điều; kiểm tra xem IntentService có đang chạy hay không bằng cách nhìn vào Settings-> Apps-> Running của điện thoại. Nên có thêm một dịch vụ google ở ​​đâu đó. Thử thiết lập IntentService từ onAddedGeofence và xuất một thứ gì đó trong bộ thu phát sóng để kiểm tra mọi thứ đang kết nối đúng cách. Nếu mọi thứ đều ổn, ứng dụng của bạn có thể không được thiết lập để xử lý onPause/stop well, vì vậy hãy giữ điện thoại của bạn bật với ứng dụng mở trong 5 phút sau khi bạn rời khỏi hàng rào. – Njall

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

nên thay đổi để:

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

Trong phương pháp onCreate(), bạn nên nhanh chóng GoogleApiClient:

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

    mApiClient.connect(); 
0

Vấn đề là bạn cần một LocationRequest để giám sát geofence vị trí ...

Nếu bạn sử dụng Google ma ps cùng một lúc. Giám sát geofence của bạn sẽ hoạt động! vì bản đồ google làm LocationRequest và geofence nhìn thấy nó ...

Sau đó, nếu bạn cần tự chủ trong geofence giám sát bạn cần thực hiện một handler LocationRequest ...

Google Api LocationRequest

Ví dụ Mã

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; 
} 

Trong mã này, bạn nhận Yêu cầu vị trí sau 10 giây ... Và theo dõi địa lý mỗi vùng địa lý 10 giây ...

Các vấn đề liên quan