Auto launch an activity when beacon comes in a cer

2019-06-14 12:48发布

问题:

I want my application to auto launch an activity when beacon comes within a certain distance (in my case it is 1 meter)

My activity gets launched when i plug in or plug off the charger and when i boot the device but it didn't get auto launch when i closed the application and beacon is in 1 meter.

what i want is if beacon is in 1 meter then activity should launch by itself.

I am using android beacon library and following the same steps mentioned on https://altbeacon.github.io/android-beacon-library/samples.html

My manifest file code is

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.altbeacon.beaconreference"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="21" />
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>

    <application 
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" 
        android:name="org.altbeacon.beaconreference.MyApplicationName">

    <activity
            android:launchMode="singleInstance"  
            android:name="org.altbeacon.beaconreference.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
        <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

My application class code is :

import java.util.Collection;
import android.app.Application;
import android.content.Intent;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.BootstrapNotifier;
import org.altbeacon.beacon.startup.RegionBootstrap;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;

public class MyApplicationName extends Application implements BootstrapNotifier, RangeNotifier {
    private static final String TAG = ".MyApplicationName";
    private RegionBootstrap regionBootstrap;
    private BeaconManager  mBeaconManager;
    private Region region;
    private Region mAllBeaconsRegion;
    private BackgroundPowerSaver mBackgroundPowerSaver;
    private RegionBootstrap mRegionBootstrap;
    @Override
    public void onCreate() {

        mAllBeaconsRegion = new Region("all beacons", null, null, null);
        mBeaconManager = BeaconManager.getInstanceForApplication(this);
        mBackgroundPowerSaver = new BackgroundPowerSaver(this);     
        mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion);

        // By default the AndroidBeaconLibrary will only find AltBeacons.  If you wish to make it
        // find a different type of beacon, you must specify the byte layout for that beacon's
        // advertisement with a line like below.  The example shows how to find a beacon with the
        // same byte layout as AltBeacon but with a beaconTypeCode of 0xaabb
        //        
        Log.d(TAG, " region.  starting ranging");

        mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        mBeaconManager.setBackgroundScanPeriod(11000l);

    }

    @Override
    public void didDetermineStateForRegion(int arg0, Region arg1) {
        // Don't care
    }

    @Override
    public void didEnterRegion(Region arg0) {

        mRegionBootstrap.disable();
        // 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.  
        try {

            mBeaconManager.startRangingBeaconsInRegion(new Region("all beacons", null, null, null));
            mBeaconManager.setRangeNotifier(this);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Log.d(TAG, "Got a didEnterRegion call");

    }

    @Override
    public void didExitRegion(Region arg0) {
        // Don't care
    }

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        // TODO Auto-generated method stub
        if (beacons.size() > 0) {

            for (Beacon beacon: beacons) {              

                if(beacon.getDistance()<1)
                {
                    Log.d(TAG, "within 1 minute call");
                    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.
                      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                      this.startActivity(intent);               
                }       

            }

        }
    }        
}

My Main activity class is:

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);     
        setContentView(R.layout.activity_main);    
    }

}

回答1:

The behavior of the Android Beacon Library after an app is closed is different depending on how it was closed. Beacon scanning keep going at background rates (once every 5 minutes on Android 4.x) if you use the back button. If you kill it with the task switcher, it will resume scanning as soon vas possible (on power connected/disconnected or reboot).

Full details here: http://altbeacon.github.io/android-beacon-library/resume-after-terminate.html

Your code looks OK to do what you want within the parameters of what is described above. It is possible that you are simply seeing a five minute delay on detections when the app is in the background. Scanning once every five minutes in the background is done to save battery, but is configurable. On Android 5.x this delay is not present if you go from no beacons being visible to beacons being visible.

See here for details: http://altbeacon.github.io/android-beacon-library/battery_manager.html