接收器:
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();
}
}
创建ProximityAlerts:
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);
的onPause:
@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);
有什么想法吗?如果需要,我可以发布更多代码:)
答案 0 :(得分:1)
实际上我的问题出在BroadcastReceivers上。
我正在摧毁他们,但不是很正确,所以有时候他们会加倍,或者加倍,或者加入。
谢谢,但我自己解决了这个问题:)
答案 1 :(得分:1)
每次申请恢复时,您都在注册接收器。
public enum DatabaseState
{
Empty = 0,
Learning = 1,
Updating = 2,
Stable = 3,
Exiting = 4
};
public class NetworkDB
{
public Dictionary<string, NetworkDevice> database;
private Queue<Action<NetworkDevice>> jobs;
private string _community;
private string _ipaddress;
private Object _statelock = new Object();
private DatabaseState _state = DatabaseState.Empty;
private readonly int workers = 4;
private Object _threadswaitinglock = new Object();
private int _threadswaiting = 0;
public Dictionary<string, NetworkDevice> Database { get => database; set => database = value; }
public NetworkDB(string community, string ipaddress)
{
_community = community;
_ipaddress = ipaddress;
database = new Dictionary<string, NetworkDevice>();
jobs = new Queue<Action<NetworkDevice>>();
}
public void Start()
{
NetworkDevice nd = SNMP.GetDeviceInfo(new IpAddress(_ipaddress), _community);
if (nd.Status > NetworkDeviceStatus.Unknown)
{
database.Add(nd.Id, nd);
_state = DatabaseState.Learning;
nd.Update(this); // The first job is done by the main thread
for (int i = 0; i < workers; i++)
{
Thread t = new Thread(JobRemove);
t.Start();
}
lock (_statelock)
{
if (_state == DatabaseState.Learning)
{
Monitor.Wait(_statelock);
}
}
lock (_statelock)
{
if (_state == DatabaseState.Updating)
{
Monitor.Wait(_statelock);
}
}
foreach (KeyValuePair<string, NetworkDevice> n in database)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(n.Value.Name + ".txt")
{
file.WriteLine(n);
}
}
}
}
public void JobInsert(Action<NetworkDevice> func, NetworkDevice nd)
{
lock (jobs)
{
jobs.Enqueue(item);
if (jobs.Count == 1)
{
// wake up any blocked dequeue
Monitor.Pulse(jobs);
}
}
}
public void JobRemove()
{
Action<NetworkDevice> item;
lock (jobs)
{
while (jobs.Count == 0)
{
lock (_threadswaitinglock)
{
_threadswaiting += 1;
if (_threadswaiting == workers)
Monitor.Pulse(_statelock);
}
Monitor.Wait(jobs);
}
lock (_threadswaitinglock)
{
_threadswaiting -= 1;
}
item = jobs.Dequeue();
item.Invoke();
}
}
public bool NetworkDeviceExists(NetworkDevice nd)
{
try
{
Monitor.Enter(database);
if (database.ContainsKey(nd.Id))
{
return true;
}
else
{
database.Add(nd.Id, nd);
Action<NetworkDevice> action = new Action<NetworkDevice>(UpdateDeviceInfo);
jobs.Enqueue(action);
return false;
}
}
finally
{
Monitor.Exit(database);
}
}
//Job1 - Learning -> Update device info
public void UpdateDeviceInfo(NetworkDevice nd)
{
nd.Update(this);
try
{
Monitor.Enter(database);
nd.Status = NetworkDeviceStatus.Self;
}
finally
{
Monitor.Exit(database);
}
}
//Job2 - Updating -> After Learning, create links between neighbours
private void UpdateLinks()
{
}
}
因此,每次触发每个接近警报(@Override
protected void onResume() {
super.onResume();
...
registerReceiver(br, mIntentFilter);
}
)时,将触发多个接收器实例(每次恢复活动时一个)。想象一下,你有一个来电者和一群克隆的接收者,所有人都同时回答。
创建PendingIntent
很好,只要每次暂停应用程序{@ 1}}时删除/销毁邻近警报。
否则,在主/导航活动中创建一次。在这种情况下,即使应用程序处于后台(可能[报警应用]或可能不[显示更改,例如]是所需行为),接收器仍将继续触发。