0

所以有一个扩展 Application 并实现在后台工作的 BootstrapNotifier 和 RangeNotifier 的类。当应用程序第一次打开时,它工作正常并且可以很好地检测信标和信标的信息,但现在需要它在设备(平板电脑/手机)打开时在后台自动启动并且当应用程序关闭时仍然继续后台搜索信标。

有一个名为 postService.Post 的 AsyncTask,我在其中调用特定的 Activity,如下所示

    @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 以启动 Activity。

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

2 回答 2

1

Asynctasks 用于活动内的后台任务,以防止 UI 冻结。在您的情况下,您应该使用服务来搜索信标。您的一项活动将在需要时启动服务,然后,当您的服务找到您的信标时,它将启动您的活动(也许是时候停止服务了)。有关服务和最佳实践的更多信息,请不要忘记此处提供的官方文档。我希望我对你有所帮助。如果您需要进一步的帮助,请随时评论我的回复:)

于 2015-04-27T12:50:51.227 回答
0

您必须在服务中包含您的后台逻辑

于 2015-04-27T12:48:16.137 回答