そのため、Application を拡張し、バックグラウンドで動作する BootstrapNotifier と RangeNotifier を実装するクラスを作成します。アプリを最初に開いたときは正常に動作し、ビーコンとビーコンの情報を適切に検出しますが、デバイス (タブレット/電話) の電源を入れたときにバックグラウンドで自動的に起動する必要があり、アプリを閉じても継続します。バックグラウンドでビーコンを検索します。
以下のように特定のActivitieを呼び出すpostService.Postという名前のAsyncTaskを用意します
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//to return a url(test example was a youtube url from db->https://www.youtube.com
if(jsonStr==null){
}
else{
//Log.d("URL",resultStr);
/*
Log.d("description",description);
Log.d("title",title);
Log.d("image",image);
*/
Context context_onPosExecute = c;//getApplicationContext();
Intent intent = new Intent(context_onPosExecute, Service.class);
//intent.putExtra("json", resultStr.toString());
//intent.putExtra("url", resultStr);
intent.putExtra("description", description);
intent.putExtra("title", title);
intent.putExtra("image", image);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(intent);
//resultStr = "";
}
}
このコードは、ビーコンを検出したバックグラウンド用であり、ビーコンが検出されたときに postService.Post を呼び出してアクティビティを開始します。
@Override
> public void onCreate() {
> super.onCreate();
>
> //Movetasktoback(true);
>
> //turn on/enable the bluetooth
> if(MainActivity.mBluetoothAdapter == null) {
> MainActivity.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
> }
> if (!MainActivity.mBluetoothAdapter.isEnabled()) {
> MainActivity.mBluetoothAdapter.enable();
> }
>
>
> // Simply constructing this class and holding a reference to it in your custom Application class
> // enables auto battery saving of about 60%
> //private BackgroundPowerSaver backgroundPowerSaver;//to able battery saving
> //backgroundPowerSaver = new BackgroundPowerSaver(this);
> beaconManager = BeaconManager.getInstanceForApplication(this);
> Region region = new Region(".Background", Identifier.parse(UUID),null,null);//
> Identifier.parse(UUID),Identifier.parse("1") ,Identifier.parse("1"));
> //beaconManager.setDebug(true);
> try{
> // set the duration of the scan to be 1.1 seconds
> beaconManager.setBackgroundScanPeriod(1100l);
> // set the time between each scan to be 1 hour (3600 seconds)//50000l
> //60 seconds change after seing if more time still catchs the beacon to improve battery saving
> beaconManager.setBackgroundBetweenScanPeriod(60000l);//3600000l
> beaconManager.updateScanPeriods();
>
> } catch (RemoteException e) {
> //Log.e(TAG, "Cannot talk to service");
> }
> //beaconManager.getBetweenScanPeriod();
> // wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
> regionBootstrap = new RegionBootstrap(this, region);
>
>
> //beaconManager.setMonitorNotifier(this);
> //beaconManager.setBackgroundMode(true);
> beaconManager.getBeaconParsers().add(new BeaconParser()
> .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
> beaconManager.setRangeNotifier(this);
>
>
> }
>
> public class Background extends Application implements BootstrapNotifier,RangeNotifier
>
> @Override
> public void didEnterRegion(Region region) {
> //Log.d(TAG, "Got a didEnterRegion call uuid->"+region.getId1());
>
> try {
> Log.d(TAG,"calling startRangingBeaconsInRegion");
> beaconManager.startRangingBeaconsInRegion(region);
> }
> catch (RemoteException e) {
> Log.d(TAG, "Can't start ranging");
> }
>
> // This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next
> time the app is launched)
> // if you want the Activity to launch every single time beacons come into view, remove this call.
> //regionBootstrap.disable();
> /*
> Intent intent = new Intent(this, MainActivity.class);
> // IMPORTANT: in the AndroidManifest.xml definition of this activity, you must set android:launchMode="singleInstance" or you will
> get two instances
> // created when a user launches the activity manually and it gets launched from here.
> //get the information about the beacon detected that is the UUID(getId1()), MAJOR(getId2()) and MINOR(getId3())
> //and send that to the main activity that will do the request of the backoffice(and see if for the beacon detected there is any in
> the db
> // and if there is will get the url camp that will call s service)
> //intent.putExtra("uuid",region.getId1().toString());
> //intent.putExtra("major",region.getId2().toString());
> //intent.putExtra("minor",region.getId3().toString());
> intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
> this.startActivity(intent);
> */
> }
>
> @Override
> public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
> Log.d(TAG, "entered the range beacons");
> if (beacons.size() > 0) {
> for(Beacon beacon: beacons){
> Log.d(TAG, "Beacon detected with id1: " + beacon.getId1() + " id2:" + beacon.getId2() + " id3: " +
> beacon.getId3() + " distance: " + beacon.getDistance());
> String uuid = beacon.getId1().toString();
> String major = beacon.getId2().toString();
> String minor = beacon.getId3().toString();
>
> //call a service in backoffice to retrive the url associated to this 3 ids
> //url for the request of the service http://localhost/mobishout-admin/services/?q={%22Beacon_getUrl%22:{%22uuid%22:%22EBEFD08370A247C89837E7B5634DF524%22,%22major%22:%221%22,%22minor%22:%221%22}}
> PostService postService = new PostService();
> //pass uuid without the - between and case because of the format that will be insert in the db is different of the obtain of
> the beacon
> uuid = uuid.replace("-","").toUpperCase();
> //String url = "{\"uuid\":\""+uuid+"\",\"major\":\""+major+"\",\"minor\":\""+minor+"\"}";//String
> url =
> "{\"uuid\":\"EBEFD08370A247C89837E7B5634DF524\",\"major\":\"1\",\"minor\":\"1\"}";
> postService.Post(null,"Beacon_getUrl",null,this,uuid,major,minor);
>
> //coment this to stop calling the Activity associated to the beacon detected
> //to work only once and stop searching if its still in the beaconRegion since it fired once already
> try {
> beaconManager.stopRangingBeaconsInRegion(region);
> }catch(RemoteException e){
>
> }
>
> }
> }
>
>
>
> //afther collecting information with the database that is the url associated to this ids
> /*
> Intent intent = new Intent(this, MainActivity.class);
> intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
> this.startActivity(intent);
> */
>
> }