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가 실행되지 않습니다.
나는 에뮬레이터 장치로 내 타블렛/스마트 폰을 개발 중입니다. 나는 걸어 다녔지 만 전혀 운이 없었습니다.
도움이 매우 감사합니다.
감사합니다.
'mCurrentLocation'은 (는)'null'입니까? 일부 로깅을하는 것이 문제를 디버깅하는 데 도움이 될 것 같습니다. – ianhanniballake
아니요, 의도 한대로 반환됩니다. 화면에 실제 위도와 경도를 표시 한 다음 지오 펜스 인수로 전달합니다. 나는 그것이 중요하지 않았기 때문에 나는 코드를 생략했다. 어떤 종류의 로깅이 필요합니까? 죄송합니다. 저는 초보자입니다.하지만 – AntCopp
5m은 매우 작은 반경입니다 (대부분의 GPS 수신기는 8-15m의 정확도로 평가됩니다). 큰 반경을 사용하여 시도해 보셨습니까? – ianhanniballake