Recentemente ho iniziato a testare Estimote Beacons e sto provando a lanciare una notifica da un servizio in background quando si entra in una regione beacon, ma sfortunatamente la mia soluzione non funziona. Non dà errori ma la notifica non viene lanciata quando viene scoperto un faro. Non so se si tratta di un errore di codice o semplicemente il modo di farlo è sbagliato. Ho letto this altra questione, ma sembra un po 'diverso dal quello che uso è un servizio invece di un'attività, ma forse la risposta è simile (contesto app correlata) ...Rilevamento regione dei beacon estimetrici da un servizio in background
Ecco il mio codice di servizio
public class BeaconsMonitoringService extends Service{
private BeaconManager beaconManager;
private String user;
@Override
public void onCreate() {
// Configure BeaconManager.
beaconManager = new BeaconManager(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Beacons monitoring service starting", Toast.LENGTH_SHORT).show();
user = intent.getStringExtra("user");
// Check if device supports Bluetooth Low Energy.
if (!beaconManager.hasBluetooth()||!beaconManager.isBluetoothEnabled()) {
Toast.makeText(this, "Device does not have Bluetooth Low Energy or it is not enabled", Toast.LENGTH_LONG).show();
this.stopSelf();
}
connectToService();
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "Beacons monitoring service done", Toast.LENGTH_SHORT).show();
}
private void connectToService() {
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
@Override
public void onServiceReady() {
notifyEnterRegion(0);
// try {
beaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1), 0);
Log.i("BEACOON ", "ANTES DE");
beaconManager.setMonitoringListener(new MonitoringListener() {
@Override
public void onEnteredRegion(Region region, List<Beacon> beacons) {
Log.i("BEACOON ", String.valueOf(beacons.get(1).getMinor()));
for (Beacon beacon: beacons){
Log.i("BEACOON ", String.valueOf(beacon.getMinor()));
if (beacon.getMinor() == 64444) {
notifyEnterRegion(6444);
} else if (beacon.getMinor() == 36328) {
notifyEnterRegion(36328);
} else if (beacon.getMinor() == 31394) {
notifyEnterRegion(31394);
}
}
}
@Override
public void onExitedRegion(Region region) {
notifyExitRegion();
}
});
}
});
}
public void notifyEnterRegion(int code) {
Toast.makeText(this, "Beacon "+code, Toast.LENGTH_SHORT).show();
Intent targetIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification noti = new Notification.Builder(this)
.setContentTitle("Bienvenido "+user+"!")
.setContentText("Sólo por estar aquí has ganado....")
.setSmallIcon(com.smt.beaconssmt.R.drawable.beacon_gray)
.setContentIntent(contentIntent)
.getNotification();
NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nManager.notify(1, noti);
}
public void notifyExitRegion(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Hasta pronto!")
.setTitle(user+", estás abandonando la zona de beacons");
builder.setPositiveButton("Ver web", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked OK button
Intent i = new Intent(BeaconsMonitoringService.this, WebViewActivity.class);
i.putExtra("web", "http://www.google.com/");
startActivity(i);
}
});
builder.setNegativeButton("Adios!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
Apprezzerò molto ogni tipo di aiuto, grazie in anticipo!
Ok, questa soluzione funziona, grazie! ma ho un dubbio a riguardo, come si "computa la prossimità"? è qualcosa nel codice SDK o ufficiale o è la tua soluzione? Quindi da questo capisco che BeaconManager.setMonitoringListener() non è utilizzabile in questo caso e dobbiamo usare setRangingListener() invece ?? – Hugo
Il codice per calcolare l'accuratezza dovrebbe essere nell'SDK. Ma sto usando un'implementazione di sdk personalizzata, quindi ho modificato la risposta per mostrarti il codice. A proposito di setMonitoringListener, non ho potuto farlo funzionare così ho finito di usare questa soluzione. – jDur
Sto integrando per la mia applicazione Xamarin, qui EnterRegion e ExitRegion chiama più volte in sequenza, non so perché? Ho letto su di esso, dovrebbe attivarsi solo quando il dispositivo rientra nell'intervallo di regione. Ma quando entra nel raggio d'azione, si innesca in sequenza fino a quando il dispositivo non si spegne. Gentile aiuto per ordinare questo –