所以,你可能已经看到了我之前关于在寻宝游戏应用中添加接近警报并让它们发射的问题的文章。警报发出来了,似乎还好。然而……我使用一个int ID变量来帮助确定在触发特定的接近警报时显示什么文本。这在一定程度上起作用,但无论出于何种原因,应用程序默认使用在addProximityAlert方法中输入的最后一个ID,并且只填充最后一个ID的文本,无论邻近警报触发什么。
完整代码:
public class FCRun extends Activity implements LocationListener {
private static final long MINIMUM_DISTANCECHANGE_FOR_UPDATE = 1; // in meters
private static final long MINIMUM_TIME_BETWEEN_UPDATE = 5000; // in Milliseconds
private static final long PROX_ALERT_EXPIRATION = -1; // -1 is never expires
public static final String PROX_ALERT_INTENT = "com.kinghendo.android.frankcem.ProximityAlert";
//public static final int KEY_LOCATION_CHANGED = 0;
private LocationManager lm;
double latitude, longitude;
public String[] Screen;
private ProximityIntentReceiver proximityReceiver;
//private String[] locationList;
// setting default screen text
public TextView txtName;
public TextView txtInfo;
public TextView txtClue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fcrun);
@SuppressWarnings("unused")
Resources res = getResources();
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.first);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+PROX_ALERT_INTENT);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.first);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+PROX_ALERT_INTENT);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.first);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+PROX_ALERT_INTENT);
// Get the location Manager (code from http://examples.javacodegeeks.com/android/core/location/android-location-based-services-example/)
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATE,
MINIMUM_DISTANCECHANGE_FOR_UPDATE,
this
);
IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
proximityReceiver = new ProximityIntentReceiver(this); // registers ProximityIntentReceiver
registerReceiver(proximityReceiver, filter);
addProximityAlerts();
}
private void addProximityAlerts(){
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc == null)
Toast.makeText(this, "No location", Toast.LENGTH_SHORT).show();
else
addProximityAlert(loc.getLatitude(), loc.getLongitude(), 1, 0);
addProximityAlert (38.042015, -84.492637, 10, 27); // test Awesome
addProximityAlert (38.085705, -84.561101, 10, 26); // Test Home Location
addProximityAlert (38.152649, -84.895205, 10, 25); // Test Office Location
addProximityAlert (38.197871, -84.866924, 3, 1); // Information Center
addProximityAlert (38.196001, -84.867435, 6, 2); // Goebel
addProximityAlert (38.203191, -84.867674, 7, 3); // Chapel
addProximityAlert (38.192173, -84.870451, 6, 4); // Confederate Cemetery
addProximityAlert (38.193455, -84.868534, 2, 5); // O'Bannon
addProximityAlert (38.193815, -84.864904, 2, 6); // Henry Clay Jr
addProximityAlert (38.087388, -84.547503, 2, 7); // O'Hara
addProximityAlert (38.191642, -84.870967, 5, 8); // Daniel Boone
}
private void addProximityAlert(double latitude, double longitude, int radius, int ID) {
Log.i("TEST", "addProximityAlert "+latitude+", "+longitude+", "+radius+", " +ID+", " + PROX_ALERT_EXPIRATION);
Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("ID", ID);
PendingIntent proximityIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//lm.addProximityAlert(latitude, longitude, radius, ID, proximityIntent);
lm.addProximityAlert(latitude, longitude, radius, PROX_ALERT_EXPIRATION, proximityIntent);
}
public void onProximityAlert(int ID, boolean entering) {
Log.i("TEST", "LOC " +latitude+", "+longitude);
Log.i("TEST", "onProximityAlert ID="+ID+" entering: "+entering);
switch (ID){
case 1:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.start);
txtName.setText(Screen[0]);
Log.i("txtName", "populated"+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.start);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.start);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 2:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.goebel);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.goebel);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.goebel);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 3:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.church);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.church);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.church);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 4:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.confederate);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.confederate);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.confederate);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 5:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.obannon);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.obannon);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.obannon);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 6:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.hcj);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.hcj);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.hcj);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 7:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.ohara);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.ohara);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.ohara);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 8:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.danielboone);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.danielboone);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.danielboone);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 25:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.toffice);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.toffice);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.toffice);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 26:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.thome);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.thome);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.thome);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
case 27:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.tawesome);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.tawesome);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.tawesome);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
default:
txtName = (TextView) findViewById(R.id.txtName);
Screen = getResources().getStringArray(R.array.first);
txtName.setText(Screen[0]);
Log.i("txtName", "populated "+ID);
txtInfo = (TextView) findViewById(R.id.txtInfo);
Screen = getResources().getStringArray(R.array.first);
txtInfo.setText(Screen[1]);
Log.i("txtInfo", "populated "+ID);
txtClue = (TextView)findViewById(R.id.txtClue);
Screen = getResources().getStringArray(R.array.first);
txtClue.setText(Screen[2]);
Log.i("txtClue", "populated "+ID);
break;
}
}
@Override
public void onLocationChanged(Location location) {
//String provider = location.getProvider();
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.i("TEST", "lat: "+latitude+" lng: "+longitude+" "+PROX_ALERT_INTENT);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i("TEST", "Close Out");
lm.removeUpdates(this);
unregisterReceiver(proximityReceiver);
}
}
这是接收者代码…
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
private WeakReference<FCRun> mActivity;
long lat, lon;
public ProximityIntentReceiver(FCRun activity) {
mActivity = new WeakReference<FCRun>(activity);
}
@Override
public void onReceive(Context context, Intent intent) {
String key = LocationManager.KEY_PROXIMITY_ENTERING;
Bundle results = getResultExtras(true);
Boolean entering = intent.getBooleanExtra(key, false);
lat = intent.getLongExtra("location-lat ", lat);
lon = intent.getLongExtra("location-lon ", lon);
int ID = intent.getIntExtra("ID", 0);
Log.i("ProximityIntentReceiver", "coordinate-lat " + lat );
Log.i("ProximityIntentReceiver", "coordinate-lon " + lon );
Log.i("ProximityIntentReceiver", String.format("ID: %d entering: %s", ID, entering?"true":"false"));
FCRun a = mActivity.get();
if (a != null)
a.onProximityAlert(ID, entering);
// Vibrate for 2 seconds
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(FCRun.PROX_ALERT_INTENT), PendingIntent.FLAG_UPDATE_CURRENT);
Notification noti = new Notification.Builder(context)
.setContentTitle("Location Alert ")
.setContentText("Entering Point of Interest")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build(); // available from API level 11 and onwards
notificationManager.notify(NOTIFICATION_ID, noti);
}
}
这里的任何帮助将是非常感激的。谢谢,Hendo
这里的问题是,您试图在addProximityAlert
中拥有多个PendingIntent
实例,而您的PendingIntent
s被认为是相等的,因为它们只在额外的内容上有所不同。PendingIntent
的文档解释了这一点:
PendingIntent本身只是对一个令牌的引用,这个令牌是由系统维护的,用来描述用来检索它的原始数据。这意味着,即使它所拥有的应用程序的进程被杀死,PendingIntent本身仍然可以被其他已经给它的进程使用。如果创建应用程序稍后重新检索相同类型的PendingIntent(相同的操作,相同的Intent动作,数据,类别,组件,和相同的标志),它将收到一个PendingIntent表示相同的令牌,如果它仍然有效,因此可以调用cancel()来删除它。由于这种行为,了解两个intent在检索PendingIntent时被认为是相同的是很重要的。人们常犯的一个错误是创建多个PendingIntent对象,这些对象的intent只在它们的"额外"内容中有所不同,期望每次都得到不同的PendingIntent。这是不会发生的。Intent中用于匹配的部分与Intent. filterequals定义的部分相同。如果你在每个Intent中使用两个等价的Intent对象。你会得到相同的PendingIntent
它还提供了如何修复它的指导:
所以可能最简单的方法来修复它是使用有两种典型的方法来处理这个问题。
如果你真的需要多个不同的PendingIntent对象同时活动同时(例如用作两个同时显示的通知)与此同时),那么你就需要确保有一些东西把他们和不同的人联系起来就是不同的PendingIntents。这可能是任何的Intent属性意图。filterEquals,或提供给的不同请求代码整数getActivity(Context, int, Intent, int), getActivities(Context, int,Intent[], int), getBroadcast(Context, int, Intent, int),或者getService(Context, int, Intent, int).
ID
作为请求代码(假设它是唯一的)。例如:改变PendingIntent proximityIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent proximityIntent = PendingIntent.getBroadcast(this, ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);