I just started with Java and Android coding. I wrote an application for a scientific study in my university. The app is for a local exhibition of a museum. I have different locations in my town, each location with its own exhibit.
Now I made an activity for each of the locations, so the user can see some useful information of the sample. Now I want to combine the app with iBeacons, I bought 6 beacons from Estimote. I want the app to give the user a notification with some text like: "You are in front of object XY. Tap to see more information." After tapping on the notification the user should open the specific activity which I created. I also want the app to search for beacons in the background, so if the user comes close to a location, he/she gets automatically a notification after a few seconds.
Now I want the app to work in background. At the moment the user only gets notifications when the app is in foreground. I took the example of Estimote and modified it a little bit.
I already read in another thread that I have to hold the BeaconManager in application class. But how should I exactly do it. When I try to copy the beacon related code into a new class which I start with
public void BeaconMain extends Application{
but then I get lots of errors and I cannot fix them. Could you help me with this please? Here's my code so far:
public class MainActivity extends ActionBarActivity
{
private static final int NOTIFICATION_ID = 123;
private BeaconManager beaconManager;
private NotificationManager notificationManager;
private Region mariendom;
private Region andreasplatz;
private boolean entered = false;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Beacon beacon = getIntent().getParcelableExtra("extrasBeacon");
andreasplatz = new Region("andreasplatz", "B9407F30-F5F8-466E-AFF9-25556B57FE6D", 31134, 3);
mariendom = new Region("mariendom", "B9407F30-F5F8-466E-AFF9-25556B57FE6D", 31134, 2);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
beaconManager = new BeaconManager(this);
beaconManager.setBackgroundScanPeriod(500, 1000);
beaconManager.setMonitoringListener(new BeaconManager.MonitoringListener()
{
@Override
public void onEnteredRegion(Region region, List<Beacon> beacons)
{
if(region.getMinor().equals(2)){
postNotification("Sie sind am Mariendom");
Log.d("Estiomote", "Entered region");
}
else if(region.getMinor().equals(3)){
postNotification2("Sie sind am Andreasplatz");
Log.d("Estiomote", "Entered region");
}
}
@Override
public void onExitedRegion(Region region)
{
/*entered = false;
postNotification("Sie haben den Mariendom verlassen");
Log.d("Estiomote", "Exited region");*/
}
@Override
protected void onResume()
{
super.onResume();
notificationManager.cancel(NOTIFICATION_ID);
beaconManager.connect(new BeaconManager.ServiceReadyCallback()
{
@Override
public void onServiceReady()
{
try {
Log.d("Estiomote", "Start monitoring");
beaconManager.startMonitoring(andreasplatz);
beaconManager.startMonitoring(mariendom);
} catch (RemoteException e)
{
Log.d("Estiomote", "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("com.example.walter.him.mariendom");
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivities(
MainActivity.this,
0,
new Intent[]{notifyIntent},
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(MainActivity.this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("HiM - Hildesheim im Mittelalter")
.setContentText(msg)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build();
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults |= Notification.DEFAULT_LIGHTS;
notificationManager.notify(NOTIFICATION_ID, notification);
}
private void postNotification2(String msg)
{
//Intent notifyIntent = new Intent(MainActivity.this, MainActivity.class);
Intent notifyIntent = new Intent("com.example.walter.him.andreasplatz");
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivities(
MainActivity.this,
0,
new Intent[]{notifyIntent},
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(MainActivity.this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("HiM - Hildesheim im Mittelalter")
.setContentText(msg)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build();
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_LIGHTS;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notificationManager.notify(NOTIFICATION_ID, notification);
}
}
I'd suggest you start from scratch with learning how to put the BeaconManager into the Application class, rather than copy-pasting code that was in Activity into the Application, as there are some differences between these two approaches.
The best place is to start with the tutorial to gather some fundamental concepts and general understanding:
http://developer.estimote.com/android/tutorial/part-1-setting-up/
And there's also a Notification example you can generate via Estimote Cloud:
https://cloud.estimote.com/#/apps/add/notification
Once you learn how to integrate the BeaconManager into the Application class, it should be pretty straightforward to modify the onEntered/Exited callbacks to spawn different activities based on which beacon you've entered the range of.
That's the order I'd suggest to follow.
Full disclosure: I work as Developer Advocate at Estimote.