Search code examples
androidibeacon-androidaltbeaconandroid-ibeacon

Start an app in the background after detecting beacon


So have a class that extends Application and implements BootstrapNotifier and RangeNotifier that works on the background. When the app is first open it works fine and detects well the beacons and the information of the beacon but now need it to start automaticaly in the background when the device(tablet/phone) is turn on and when the app is closed still continuing in the background searching for beacons.

Have a AsyncTask named postService.Post where I call a specific Activitie as below

    @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 = "";

        }
    }

this code is for the background where its detected the beacons and call the postService.Post to Start a Activitie when beacons are detected.

@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);
>         */
>     
>     }

Solution

  • Asynctasks are for background tasks inside activities, to prevent UI freeze. In your case, you should use a Service to search for beacons. One of your activities will start the service when needed, then, when your service find your beacon, it will launch your Activity (maybe it's the time to stop the service). For more information about Services and best practices, don't forget the official documentation available here. I hope I helped you. Feel free to comment my response if you need further help :)