问题
I would like to have push notifications when my app is open but is in background. For now I have changed the Estimote Demo, and my app gives me a notification when my app is in foreground which is not much of use. I post here my code of NotifyDemoActivity class which is called as soon as I open the app
public class NotifyDemoActivity extends Activity {
private static final String TAG = NotifyDemoActivity.class.getSimpleName();
private static final int NOTIFICATION_ID = 123;
private BeaconManager beaconManager;
private NotificationManager notificationManager;
private Region region;
private long[] mVibratePattern = { 0, 200, 200, 300 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notify_demo);
getActionBar().setDisplayHomeAsUpEnabled(true);
beacon.getMinor());
region = new Region("rid", null, null, null);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
beaconManager = new BeaconManager(this);
beaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1), 0);
beaconManager.setMonitoringListener(new MonitoringListener() {
@Override
public void onEnteredRegion(Region region, List<Beacon> beacons) {
postNotification("Entered region");
}
@Override
public void onExitedRegion(Region region) {
postNotification("Exited region");
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
notificationManager.cancel(NOTIFICATION_ID);
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
@Override
public void onServiceReady() {
try {
beaconManager.startMonitoring(region);
} catch (RemoteException e) {
Log.d(TAG, "Error while starting monitoring");
}
}
});
}
@Override
protected void onDestroy() {
notificationManager.cancel(NOTIFICATION_ID);
beaconManager.disconnect();
super.onDestroy();
}
private void postNotification(String msg) {
Intent notifyIntent = new Intent(NotifyDemoActivity.this, NotifyDemoActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivities(
NotifyDemoActivity.this,
0,
new Intent[]{notifyIntent},
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(NotifyDemoActivity.this)
.setSmallIcon(R.drawable.beacon_gray)
.setContentTitle("Notify Demo")
.setContentText(msg)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setVibrate(mVibratePattern)
.build();
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_LIGHTS;
notificationManager.notify(NOTIFICATION_ID, notification);
TextView statusTextView = (TextView) findViewById(R.id.status);
statusTextView.setText(msg);
}
}
回答1:
You should hold BeaconManager
in your application class not in the activity.
Activity will be stopped, destroyed and BeaconManager
will stop monitoring. Application on the other hand will still hold reference and will continue to monitor.
When a beacon is being found while monitoring your application class can post a notification. It trigger some activity when user decides to tap on it.
回答2:
You should create service.
In your code you should do some changes.
After
beaconManager = new BeaconManager(this);
you should start "beacon service"
if (!beaconManager.isBluetoothEnabled()) {
stopSelf();
}
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
@Override
public void onServiceReady() {
try {
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS_REGION);
} catch (RemoteException e) {
Log.e("error", "Cannot start ranging", e);
}
}
});
Also check if Bluetooth is active on you device.
In procedure beaconManager.setMonitoringListener(new MonitoringListener() add commands to create Notifications.
来源:https://stackoverflow.com/questions/23892384/estimote-ibeacon-monitoring-in-background-android