2015-07-21 67 views
0

所以,你可能已經看到我以前的帖子關於在清道夫尋寶應用程序中添加接近警報的問題,並讓他們開火。警報正在發射,似乎很好。但是,我使用一個int ID變量來幫助確定在觸發特定接近警報時顯示的文本。這在某種程度上有效,但無論出於何種原因,應用默認爲在addProximityAlert方法中輸入的最後一個ID,並且只填充該最後一個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

回答

0

這裏的問題是,你想擁有的多個實例PendingIntentaddProximityAlert和你PendingIntent s被認爲相等,因爲它們只在額外的內容有所不同。所述documentation for PendingIntent解釋這樣的:

甲的PendingIntent本身是簡單地通過描述用於檢索它的原始數據的系統所維護的令牌的引用。這意味着,即使其擁有的應用程序的進程被終止,PendingIntent本身仍然可以從其他被賦予的進程中使用。如果稍後創建的應用程序重新獲取相同類型的PendingIntent(相同的操作,相同的Intent操作,數據,類別和組件,以及相同的標誌),它將會收到一個表示相同標記的PendingIntent(如果該標記仍然有效)因此調用cancel()將其刪除。

由於這種行爲,重要的是要知道何時兩個Intents被認爲是相同的,用於檢索PendingIntent。人們犯的一個常見錯誤是創建多個PenttentIntent對象,其Intents只在其「額外」內容中有所不同,期望每次都得到不同的PendingIntent。這不會發生。用於匹配的Intent部分與Intent.filterEquals定義的部分相同。如果您使用兩個與Intent.filterEquals等效的Intent對象,那麼您將爲它們獲得相同的PendingIntent。

它還提供了有關如何解決問題的指導:

有兩種典型的方式來解決這個問題。

如果確實需要多個不同的PendingIntent在 對象處於活動狀態的時間(如兩個通知,它們都在同一時間顯示 使用),那麼你將需要確保有一些 是不同的關於他們將它們與不同的 PendingIntents關聯起來。這可以是由 Intent.filterEquals或提供給 的不同請求代碼整數所考慮的Intent屬性中的任意一個屬性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); 
+0

這工作六角......好居多。 4個GPS點將他們的鄰近區域發射出去,並顯示正確的文字。另外6人給了我一個警報通知,並沒有顯示文字,或根本沒有給我通知。我要重新訪問我的GPS點和半徑',看看是否有幫助。不知道如果沒有幫助,還有什麼可以做的。感謝Hex,感謝您的洞察力和親切的幫助。 –

+0

太棒了,很高興它有幫助。如果您覺得有用,請注意並/或接受答案。我發現您的一些接近警報的半徑很小,所以這可能是爲什麼有些警報不會觸發,因爲如果GPS沒有足夠的衛星鎖定,GPS的準確性可能不夠好在你的點的半徑內。 – HexAndBugs