Geofence Android:PendingIntent不会触发IntentService

时间:2015-01-09 18:13:02

标签: android android-geofence

我正在尝试开发适用于Android的Geofence应用程序,在进入/退出/停留/进入Geofence时几乎不需要通知我。 尽管所有问题和答案都是红色的,但我还是无法弄清楚我的问题。

我认为我的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();
    }

}

我省略了一些不感兴趣的代码。

这是我的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());
        }
     }

我刚从enter link description here粘贴了这个IntentService,几乎没有变化。 现在,我想专注于IntentService及其处理程序:所以目前我还没有要求在通知后从IntentService触发广播接收器。这就是为什么在我的MainActivity中没有声明任何BroadcastReceiver类

我的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并没有被激活。

我使用我的平板电脑/智能手机作为模拟器设备进行开发:我试着四处走动,但根本没有运气。

非常感谢任何帮助。

感谢。

1 个答案:

答案 0 :(得分:1)

根据ianhanniballake提供的答案,我做了更多的测试,半径在20-30-40米之间,我发现所有测试都按预期进行。正如他所说,我的问题是关于半径设置太小,GPS无法识别自己的位置。

真诚的感谢。