我正在尝试开发适用于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并没有被激活。
我使用我的平板电脑/智能手机作为模拟器设备进行开发:我试着四处走动,但根本没有运气。
非常感谢任何帮助。
感谢。
答案 0 :(得分:1)
根据ianhanniballake提供的答案,我做了更多的测试,半径在20-30-40米之间,我发现所有测试都按预期进行。正如他所说,我的问题是关于半径设置太小,GPS无法识别自己的位置。
真诚的感谢。