Предупреждение о приближении срабатывает дважды?

Получатель:

public class ProximityAlert extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        int id = intent.getIntExtra("id", -1);
        String title = intent.getStringExtra("Title");

        Intent showDialog = new Intent(context, ShowMapDialog.class);
        showDialog.putExtra("id", id);
        showDialog.putExtra("Title", title);
        context.startActivity(showDialog);
    }

}

ShowMapDialog.java:

public class ShowMapDialog extends Activity {

PowerManager.WakeLock wakeLock;
AlertDialog alertbox;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);

    Bundle extras = getIntent().getExtras();

    Prefs sp = new Prefs();

    int lastplaceid = sp.getLastPlaceID(getApplicationContext());
    boolean nopopup = sp.getNoPopup(getApplicationContext());

    final int id = extras.getInt("id");
    String Title = extras.getString("Title");

    Log.d("id+title",id+"+"+Title);

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Place of Interest");

    if(id != lastplaceid && !nopopup) {
        wakeLock.acquire();

        sp.setLastPlaceID(getApplicationContext(), id);

        Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        int dot = 200;
        int dash = 500;
        int long_gap = 1000;
        long[] pattern = {0, dash, dot, dash, long_gap};
        v.vibrate(pattern, -1);

        alertbox = new AlertDialog.Builder(ShowMapDialog.this).create();
        alertbox.setTitle(getString(R.string.dialogTitle));
        alertbox.setMessage(getString(R.string.dialogShowPlaceText1)+Title+getString(R.string.dialogShowPlaceText2));
        alertbox.setButton(getString(R.string.dialogShowPlaceYes), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent showPlace = new Intent(getApplicationContext(),Showplace.class);
                showPlace.putExtra("id", id);
                startActivity(showPlace);
            }
        });
        alertbox.setButton2(getString(R.string.dialogShowPlaceNo), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        });
        alertbox.show();
    } else if(id != lastplaceid && nopopup){
        wakeLock.acquire();
        sp.setLastPlaceID(getApplicationContext(), id);
        Intent showPlace = new Intent(getApplicationContext(),Showplace.class);
        showPlace.putExtra("id", id);
        startActivity(showPlace);
    } else {
        finish();
    }
}

@Override
public void onPause(){
    super.onPause();
    wakeLock.release();
    alertbox.dismiss();
    finish();
}

}

Создание оповещений о близости:

    private void setProximityAlert(String Title, double lat, double lon, float radius, final int id, int requestCode){
        // Expiration is x Minutes (x mins * 60secs * 1000milliSecs)
        long expiration = -1;

        Intent intent = new Intent(PROXIMITY_INTENT_ACTION);
        intent.putExtra("id", id);
        intent.putExtra("Title", Title);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        mlocManager.addProximityAlert(lat, lon, radius, expiration, pendingIntent);
    }

    public void placeMarkersPoints(){
        this.dh = new DataHelper(ShowMap.this);
        List<Pontos> list = this.dh.selectAll();
        markerPlaces = new OverlayPlaces(getResources().getDrawable(R.drawable.marker_places), mapView);
        for(Pontos p : list){
             markerPlaces.addPoint(new GeoPoint(p.getLat(),p.getLng()),p.getName().toString(),Integer.toString(p.getId()));
             setProximityAlert(p.getName().toString(), p.getLat(), p.getLng(), p.getRadius(), p.getId(), p.getId());
        }
        mapView.getOverlays().add(markerPlaces);
        mapView.invalidate();
    }

Я регистрирую приемник на onCreate следующим образом:

    br = new ProximityAlert();
    mIntentFilter = new IntentFilter(PROXIMITY_INTENT_ACTION);

при паузе:

@Override
public void onPause() {
    super.onPause();
    mlocManager.removeUpdates(this);
    unregisterReceiver(br);
}

onResume:

@Override
protected void onResume() {
    super.onResume();
    mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, this);
    registerReceiver(br, mIntentFilter);
}

Когда я просматриваю второй ProximityAlert, этот код повторяется дважды: Log.d("id+title",id+"+"+Title);

Есть идеи? Если нужно, я могу опубликовать больше кода :)


person silentw    schedule 02.05.2012    source источник
comment
Почему бы просто не отладить его? Где вы на самом деле застряли?   -  person nitind    schedule 03.05.2012
comment
хм... Я на самом деле не знаю, что отлаживать, чтобы посмотреть, где это вызывается...   -  person silentw    schedule 03.05.2012
comment
@nitind взгляните на комментарий выше, пожалуйста...   -  person silentw    schedule 07.05.2012


Ответы (2)


На самом деле моя проблема была с BroadcastReceivers.

Я их уничтожал, но не совсем правильно, поэтому иногда они двоились, или троились, или ж/д.

Спасибо, но я решил это сам :)

person silentw    schedule 08.05.2012

Вы регистрируете приемник каждый раз, когда приложение возобновляет работу.

@Override
protected void onResume() {
    super.onResume();
    ...
    registerReceiver(br, mIntentFilter); 
}

Следовательно, каждый раз, когда срабатывает каждое оповещение о приближении (PendingIntent), будет запускаться несколько экземпляров приемника (по одному при каждом возобновлении активности). Представьте, что у вас есть один звонящий и целая вселенная клонированных получателей, которые ВСЕ отвечают одновременно.

Создание onResume прекрасно, если оповещения о близости удаляются/уничтожаются каждый раз, когда приложение приостанавливается onPause().

В противном случае создайте его один раз в своей основной/навигационной деятельности. В этом случае приемник будет продолжать срабатывать, даже когда приложение находится в фоновом режиме (что может быть [приложение будильника], а может и не [отображать изменения, например] желаемым поведением).

person tony gil    schedule 19.08.2017