2015-01-09 2 views
0

Geofence에 들어가거나 나가거나 들어가기 위해 간신히 알려야하는 Android 용 Geofence App을 개발하려고합니다. 모든 질문과 대답에도 불구하고 나는 여전히 내 문제를 파악할 수 없다.Geofence Android : PendingIntent가 IntentService를 트리거하지 않습니다.

내 PendinIntent 및/또는 IntentService에 문제가 있다고 생각합니다. 여기까지 내가 한 것.

MainActivity.java는

package it.coppola.geofencedetecttest1; 

import android.app.Dialog; 
import android.app.PendingIntent; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.support.v4.app.DialogFragment; 
import android.support.v4.content.LocalBroadcastManager; 
import android.support.v7.app.ActionBarActivity; 
import android.text.TextUtils; 
import android.util.Log; 
import android.view.View; 
import android.widget.TextView; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
import com.google.android.gms.location.Geofence; 
import com.google.android.gms.location.GeofencingRequest; 
import com.google.android.gms.location.LocationServices; 




public class MainActivity extends ActionBarActivity implements 
ConnectionCallbacks,OnConnectionFailedListener{ 
    private GoogleApiClient mGoogleApiClient; 
    private GeofenceSampleReceiver mGeofenceReceiver; 
    private IntentFilter filter; 
    private Location mCurrentLocation; 
    private PendingIntent mPendingIntent; 





    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mGoogleApiClient=new GoogleApiClient.Builder(this) 
      .addApi(LocationServices.API) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .build(); 
     filter=new IntentFilter(); 
     filter.addAction("it.coppola.geofencedetecttest1.ACTION_GEOFENCES_ERROR"); 
     filter.addAction("it.coppola.geofencedetecttest1.ACTION_GEOFENCES_SUCCESS"); 
     mGeofenceReceiver=new GeofenceSampleReceiver(); 
     LocalBroadcastManager.getInstance(this).registerReceiver(mGeofenceReceiver, filter); 


    } 



    @Override 
    protected void onResume(){ 
     super.onResume(); 
     LocalBroadcastManager.getInstance(this).registerReceiver(mGeofenceReceiver, filter); 

    } 

    @Override 
    protected void onPause(){ 
     super.onPause(); 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(mGeofenceReceiver); 

    } 

    @Override 
    protected void onStop(){ 
     super.onStop(); 

     LocalBroadcastManager.getInstance(this).unregisterReceiver(mGeofenceReceiver); 

    } 

    @Override 
    protected void onDestroy(){ 
     super.onDestroy(); 


    } 

    public void onConnectToLocation(View v){ 
//stuff that happens when i press a button. Here is mGoogleApiClient.connect() 

    } 
    public void onConnected(Bundle connectionHint){ 


     mCurrentLocation= LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 

     if (mCurrentLocation != null){ 

      TextView lan=(TextView)findViewById(R.id.txtLan); 
      lan.setText(String.valueOf(mCurrentLocation.getLatitude())); 
      TextView lon=(TextView)findViewById(R.id.txtLong); 
      lon.setText(String.valueOf(mCurrentLocation.getLongitude())); 



      Geofence mGeofence1=new Geofence.Builder() 
      .setRequestId("Geofence1") 
      .setCircularRegion(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(), 5) 
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER|Geofence.GEOFENCE_TRANSITION_EXIT|Geofence.GEOFENCE_TRANSITION_DWELL) 
      .setExpirationDuration(Geofence.NEVER_EXPIRE) 
      .setLoiteringDelay(1000) 
      .build(); 

      mPendingIntent=requestPendingIntent(); 


      GeofencingRequest mGeofenceRequest=new GeofencingRequest.Builder() 
      .addGeofence(mGeofence1) 
      .build(); 


      LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, mGeofenceRequest, mPendingIntent); 
     } 
     else { 

     } 


    } 



    /** 
    * 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(); 
      Log.d("miotag","ho ricevuto questo intent: "+action); 
      if (TextUtils.equals(action, "it.coppola.geofencedetecttest1.ACTION_GEOFENCES_ERROR")){ 
       Log.d("miotag","ho ricevuto un errore dal Location Service"); 
      } 
      else if (TextUtils.equals(action, "it.coppola.geofencedetecttest1.ACTION_GEOFENCES_SUCCESS")){ 
       Log.d("miotag","intent ricevuto: OK"); 
      } 

     } 
    } 

    private PendingIntent requestPendingIntent(){ 

     if (null != mPendingIntent){ 

      return mPendingIntent; 
     } else { 


      Intent intent=new Intent(this, GeofenceReceiverSample.class); 
      return PendingIntent.getService(
        this, 
        0, 
        intent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 

     } 
    } 

    public void stopIt(View v){ 

     LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient, mPendingIntent); 
     Log.d("miotag","geofence rimossa"); 
     mGoogleApiClient.disconnect(); 
    } 

} 

내가 관심없는 코드의 일부 라인을 생략했습니다.

여기에 몇 가지 변화에 난 그냥 enter link description here에서이 IntentService를 붙여 넣은 내 IntentService

package it.coppola.geofencedetecttest1; 

import java.util.List; 

import android.app.IntentService; 
import android.app.Notification; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.support.v4.app.NotificationCompat; 

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

public class GeofenceReceiverSample extends IntentService{ 

public GeofenceReceiverSample(){ 
     super("GeofenceReceiverSample"); 
    } 

    @Override 
     protected void onHandleIntent(Intent intent) { 
     GeofencingEvent geoEvent=GeofencingEvent.fromIntent(intent); 
     if (geoEvent.hasError()) { 
       //todo error process 
      } else { 
       int transitionType = geoEvent.getGeofenceTransition(); 
       if (transitionType == Geofence.GEOFENCE_TRANSITION_ENTER || 
         transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) { 
        List<Geofence> triggerList = geoEvent.getTriggeringGeofences(); 

        for (Geofence geofence : triggerList) { 
         generateNotification(geofence.getRequestId(), "address you defined"); 
        } 
       } 
      } 
     } 

     private void generateNotification(String locationId, String address) { 
      long when = System.currentTimeMillis(); 
      Intent notifyIntent = new Intent(this, MainActivity.class); 
      notifyIntent.putExtra("id", locationId); 
      notifyIntent.putExtra("address", address); 
      notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 

      PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

      NotificationCompat.Builder builder = 
        new NotificationCompat.Builder(this) 
          .setSmallIcon(R.drawable.ic_launcher) 
          .setContentTitle(locationId) 
          .setContentText(address) 
          .setContentIntent(pendingIntent) 
          .setAutoCancel(true) 
          .setDefaults(Notification.DEFAULT_SOUND) 
          .setWhen(when); 

      NotificationManager notificationManager = 
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
      notificationManager.notify((int) when, builder.build()); 
     } 
    } 

이다. 지금 IntentService와 해당 처리기에 중점을두고 싶습니다. 지금은 알림 후 IntentService에서 방송 수신자를 요청하지 않습니다. 난 정말 이유를 모르겠지만, 시간의 몇 가지 앱이 실제로 작동 : 내 MainActivity에서이

내 AndroidManifest를

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="it.coppola.geofencedetecttest1" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="11" 
     android:targetSdkVersion="21" /> 
    <uses-permission android:name="android.permission.INTERNET"/> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    <!-- 
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> 
    --> 
    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="it.coppola.geofencedetecttest1.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    <service android:name=".GeofenceReceiverSample" 
     android:exported="false">  
    </service> 

     <receiver android:name="it.coppola.geofencedetecttest1.GeofenceSampleReceiver" 
     android:exported="false"> 
     <intent-filter > 
      <action android:name="it.coppola.geofencedetecttest1.ACTION_RECEIVE_GEOFENCE"/> 
     </intent-filter> 
    </receiver> 


     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 

    </application> 

</manifest> 

몇 메모를 선언 된 브로드 캐스트 리시버 클래스없는 이유입니다 : 내 IntentService가 Google Play 서비스 의도에서 실행되었으며 이전 버전의 코드가 실행됩니다. 이상하게도 코드에서 변경없이 동일한 앱을 다시 시작하면 IntentService가 실행되지 않습니다.

나는 에뮬레이터 장치로 내 타블렛/스마트 폰을 개발 중입니다. 나는 걸어 다녔지 만 전혀 운이 없었습니다.

도움이 매우 감사합니다.

감사합니다.

+0

'mCurrentLocation'은 (는)'null'입니까? 일부 로깅을하는 것이 문제를 디버깅하는 데 도움이 될 것 같습니다. – ianhanniballake

+0

아니요, 의도 한대로 반환됩니다. 화면에 실제 위도와 경도를 표시 한 다음 지오 펜스 인수로 전달합니다. 나는 그것이 중요하지 않았기 때문에 나는 코드를 생략했다. 어떤 종류의 로깅이 필요합니까? 죄송합니다. 저는 초보자입니다.하지만 – AntCopp

+0

5m은 매우 작은 반경입니다 (대부분의 GPS 수신기는 8-15m의 정확도로 평가됩니다). 큰 반경을 사용하여 시도해 보셨습니까? – ianhanniballake

답변

1

대답은 ianhanniballake으로, 반경이 20-30-40 미터 사이 인 더 많은 테스트를 수행했으며, 의도 한대로 작동한다는 것을 알았습니다. 그가 말했듯이, 내 문제는 GPS가 자신의 위치를 ​​인식하기에는 너무 작은 반경 설정에 관한 것이 었습니다.

감사합니다.

+0

이 [질문] (http://stackoverflow.com/questions/32937515/geofence-not-triggering) 좀 봐 주시겠습니까? –

관련 문제