How to Manage iBeacon Scanning using Mesosfer – Part 3
This tutorial is about How to Manage iBeacon Scanning using Mesosfer Part 3
Table of Contents
1. Tutorial
This tutorial was the 3rd part of How to Manage iBeacon Scanning using Mesosfer.
1.1. Define storyline cloud data
Go to your Mesosfer app -> Base -> Storyline, add this storyline below :
1 2 3 4 |
{ "title": "Attendance", "isEnabled": true } |
Within stories column, click Add Story button to add the details of storyline :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[ { "event": "ENTER", "campaign": "TEXT", "alertTitle": "Check In", "alertMessage": "You are already checked in at 7.35 o'clock, such a great morning. We hope today will be a great day for you!", "beacons": ["sGwuqbrcwS"] }, { "event": "EXIT", "campaign": "TEXT", "alertTitle": "Check Out", "alertMessage": "Your checked out time is 17.00. See you tomorrow!", "beacons": ["sGwuqbrcwS"] } ] |
With the stories above, it means that when a beacon triggered an ENTER or EXIT event it will show alert/ notification TEXT. You can also define your own storyline parameters to match your own logic.
1.2. Query for storyline
Create a method called searchForStoryline
with two parameters CBRegion
and MesosferBeacon.Event
in MainActivity
class. This method will search for Storyline data in Mesosfer cloud.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private void searchForStoryline(CBRegion region, MesosferBeacon.Event event) { MesosferStorylineDetail .getQuery() .whereEqualTo("beacons", region.getIdentifier()) .whereEqualTo("event", event.name()) .setLimit(1) .findAsync(new FindCallback<MesosferStorylineDetail>() { @Override public void done(List<MesosferStorylineDetail> list, MesosferException e) { if (e != null) { Log.e("MAIN", "Error happen when finding storyline: " + e); return; } if (list != null && !list.isEmpty()) { MesosferStorylineDetail detail = list.get(0); displayStoryline(detail); } } }); } |
1.3. Displaying alert dialog
Still in MainActivity
class, add a method called displayStoryline
with a parameter of MesosferStorylineDetail
.
1 2 3 4 5 6 7 8 9 10 11 12 |
private void displayStoryline(MesosferStorylineDetail detail) { if (detail.getCampaign() == MesosferStoryline.Campaign.TEXT) { String title = detail.getAlertTitle(); String message = detail.getAlertMessage(); new AlertDialog.Builder(this) .setTitle(title) .setMessage(message) .setNegativeButton(android.R.string.ok, null) .show(); } } |
1.4. Send statistic log
After getting storyline and show it, we need to save the statistic about what beacon’s event that was already triggered
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private void sendLog(CBRegion region, final MesosferBeacon.Event event) { String beaconId = region.getIdentifier(); MesosferBeacon beacon = MesosferBeacon.createWithObjectId(beaconId); MesosferLog.createLog() .setEvent(event) .setBeacon(beacon) .setModule(MesosferBeacon.Module.PRESENCE) .sendAsync(new SaveCallback() { @Override public void done(MesosferException e) { if (e != null) { Log.e("MAIN", "Failed to send log: " + e); return; } String state = event == MesosferBeacon.Event.ENTER ? "Check in" : "Check out"; Toast.makeText(MainActivity.this, state + " sent.", Toast.LENGTH_SHORT).show(); } }); } |
The complete MainActivity
code will be like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
package com.eyro.mesosfer.beacon; import android.os.RemoteException; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import com.eyro.cubeacon.CBMonitoringListener; import com.eyro.cubeacon.CBRegion; import com.eyro.cubeacon.CBServiceListener; import com.eyro.cubeacon.Cubeacon; import com.eyro.cubeacon.MonitoringState; import com.eyro.cubeacon.SystemRequirementManager; import com.eyro.mesosfer.FindCallback; import com.eyro.mesosfer.MesosferBeacon; import com.eyro.mesosfer.MesosferException; import com.eyro.mesosfer.MesosferLog; import com.eyro.mesosfer.MesosferStoryline; import com.eyro.mesosfer.MesosferStorylineDetail; import com.eyro.mesosfer.SaveCallback; import com.eyro.mesosfer.beacon.model.Beacon; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements CBServiceListener, CBMonitoringListener { private Cubeacon beaconManager; private List<CBRegion> regions; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // init beacon manager instance beaconManager = Cubeacon.getInstance(); // get list of parcel beacon from an activity intent List<Beacon> beaconList = getIntent().getParcelableArrayListExtra("BEACONS"); // populate list of beacon into region scanning regions = new ArrayList<>(); for (Beacon beacon : beaconList) { CBRegion region = new CBRegion(beacon.getIdentifier(), beacon.getProximityUUID(), beacon.getMajor(), beacon.getMinor()); regions.add(region); } } @Override protected void onResume() { super.onResume(); // check all requirements to comply if (SystemRequirementManager.checkAllRequirementUsingDefaultDialog(this)) { // connecting to the service scanning beaconManager.connect(this); } } @Override protected void onDestroy() { if (beaconManager != null) { beaconManager.disconnect(this); } super.onDestroy(); } @Override public void onBeaconServiceConnect() { try { // set beacon listener beaconManager.addMonitoringListener(this); // start scanning beacon when service already connected beaconManager.startMonitoringForRegions(regions); } catch (RemoteException e) { Log.e("MAIN", "Error happen while monitoring region: " + e); } } @Override public void didEnterRegion(CBRegion region) { Log.d("MAIN", "Entering region: " + region); searchForStoryline(region, MesosferBeacon.Event.ENTER); sendLog(region, MesosferBeacon.Event.ENTER); } @Override public void didExitRegion(CBRegion region) { Log.d("MAIN", "Exiting region: " + region); searchForStoryline(region, MesosferBeacon.Event.EXIT); sendLog(region, MesosferBeacon.Event.EXIT); } @Override public void didDetermineStateForRegion(MonitoringState state, CBRegion region) { switch (state) { case INSIDE: Log.d("MAIN", "Change state to entering region: " + region); break; case OUTSIDE: Log.d("MAIN", "Change state to exiting region: " + region); break; } } private void searchForStoryline(CBRegion region, MesosferBeacon.Event event) { MesosferStorylineDetail .getQuery() .whereEqualTo("beacons", region.getIdentifier()) .whereEqualTo("event", event.name()) .setLimit(1) .findAsync(new FindCallback<MesosferStorylineDetail>() { @Override public void done(List<MesosferStorylineDetail> list, MesosferException e) { if (e != null) { Log.e("MAIN", "Error happen when finding storyline: " + e); return; } if (list != null && !list.isEmpty()) { MesosferStorylineDetail detail = list.get(0); displayStoryline(detail); } } }); } private void displayStoryline(MesosferStorylineDetail detail) { if (detail.getCampaign() == MesosferStoryline.Campaign.TEXT) { String title = detail.getAlertTitle(); String message = detail.getAlertMessage(); new AlertDialog.Builder(this) .setTitle(title) .setMessage(message) .setNegativeButton(android.R.string.ok, null) .show(); } } private void sendLog(CBRegion region, final MesosferBeacon.Event event) { String beaconId = region.getIdentifier(); MesosferBeacon beacon = MesosferBeacon.createWithObjectId(beaconId); MesosferLog.createLog() .setEvent(event) .setBeacon(beacon) .setModule(MesosferBeacon.Module.PRESENCE) .sendAsync(new SaveCallback() { @Override public void done(MesosferException e) { if (e != null) { Log.e("MAIN", "Failed to send log: " + e); return; } String state = event == MesosferBeacon.Event.ENTER ? "Check in" : "Check out"; Toast.makeText(MainActivity.this, state + " sent.", Toast.LENGTH_SHORT).show(); } }); } } |
It’s done.
1.5. Demo app
1.6. Download source
You can download all the source code of this tutorial here.