所以有一个扩展Application的类并实现BootstrapNotifier 和RangeNotifier在后台工作。当应用程序首次打开时,它可以正常工作并很好地检测信标和信标的信息,但现在需要它在设备(平板电脑/手机)打开时以及当应用程序关闭时仍然在后台自动启动寻找信标的背景。
有一个名为postService.Post的AsyncTask,我在其中调用特定的Activitie,如下所示
@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启动Activitie。
@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);
> */
>
> }
答案 0 :(得分:1)
Asynctasks用于活动内的后台任务to prevent UI freeze。在您的情况下,您应使用Service来搜索信标。您的一项活动将在需要时启动服务,然后,当您的服务找到您的信标时,它将启动您的活动(可能是停止服务的时间)。有关服务和最佳实践的更多信息,请不要忘记可用的官方文档here。 我希望我帮助过你。如果您需要进一步的帮助,请随时评论我的回复:)
答案 1 :(得分:0)
您必须在service
中加入背景逻辑