接近警报有效,但 ID 选择无效
Proximity Alerts Work, but ID selection isn't
所以,您可能已经看过我之前关于在寻宝游戏应用程序中添加接近警报并让它们触发的问题的帖子。警报正在响起,似乎一切正常。然而...我正在使用一个 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);
}
}
如有任何帮助,我们将不胜感激。
谢谢,
亨多
这里的问题是您试图在 addProximityAlert
中有多个 PendingIntent
实例,并且您的 PendingIntent
被认为是相等的,因为它们仅在 extras 的内容上不同. documentation for PendingIntent
对此进行了解释:
A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.
Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.
它还提供了有关如何修复它的指导:
There are two typical ways to deal with this.
If you truly need multiple distinct PendingIntent objects active at
the same time (such as to use as two notifications that are both shown
at the same time), then you will need to ensure there is something
that is different about them to associate them with different
PendingIntents. This may be any of the Intent attributes considered by
Intent.filterEquals, or different request code integers supplied to
getActivity(Context, int, Intent, int), getActivities(Context, int,
Intent[], int), getBroadcast(Context, int, Intent, int), or
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);
所以,您可能已经看过我之前关于在寻宝游戏应用程序中添加接近警报并让它们触发的问题的帖子。警报正在响起,似乎一切正常。然而...我正在使用一个 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);
}
}
如有任何帮助,我们将不胜感激。 谢谢, 亨多
这里的问题是您试图在 addProximityAlert
中有多个 PendingIntent
实例,并且您的 PendingIntent
被认为是相等的,因为它们仅在 extras 的内容上不同. documentation for PendingIntent
对此进行了解释:
A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.
Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as per Intent.filterEquals, then you will get the same PendingIntent for both of them.
它还提供了有关如何修复它的指导:
There are two typical ways to deal with this.
If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent.filterEquals, or different request code integers supplied to getActivity(Context, int, Intent, int), getActivities(Context, int, Intent[], int), getBroadcast(Context, int, Intent, int), or 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);