Reputation: 6328
I'm using android-beacon-library (altbeacon) to detect beacons around, foreground and background. I used the example shown in Samples. I succeed making it detect one of my beacon, but it doesn't really work well. Sometimes it detects and opens up new activity, and sometimes it doesn't.
Not sure if it was my coding error or something else. As to my understanding, by implementing BeaconManager
initialization in Application
class, it will automatically scans the beacon once the app is turned on. So, I didn't initialize anything in my Activity
class, I just let it scan on Application level.
I've specified my beacon in the Application class via BeaconManager, like so:
public class BeaconReferenceApplication extends Application implements BootstrapNotifier, RangeNotifier {
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "App started up");
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
BeaconManager.setDebug(true);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(600000l);
beaconManager.setRangeNotifier(this);
// Constants is a class containing one of my beacon UUID, major and minor
Region region = new Region("com.bledemo.com.boostrapRegion", Identifier.parse(Constants.BT_UUID),
Identifier.fromInt(Constants.BT_MAJOR), Identifier.fromInt(Constants.BT_MINOR));
regionBootstrap = new RegionBootstrap(this, region);
backgroundPowerSaver = new BackgroundPowerSaver(this);
mInstance = this; // Volley networking instance
}
// fires up Activity once a specified beacon is detected
@Override
public void didEnterRegion(Region region) {
Log.d(TAG, "Got a didEnterRegion call");
regionBootstrap.disable();
Intent intent = new Intent(this, MainActivity.class);
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);
}
}
In MainActivity,
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get intent extras, etc
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, fragment)
.commit();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
private static final String TAG = PlaceholderFragment.class.getSimpleName();
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
tvRegion = (TextView) rootView.findViewById(R.id.tvRegion);
uuid = getArguments().getString("uuid");
major = getArguments().getString("major");
minor = getArguments().getString("minor");
appController = BeaconReferenceApplication.getInstance();
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
if (uuid != null && !uuid.isEmpty()) {
Log.d(TAG, "uuid not null");
tvRegion.setText("Beacon found= " + uuid
+ "\nLast found " + dateFormat.format(date)
+ "\nSet on 30 mins interval"
+ "\nRequest to API initiated"
);
initBeaconAction(uuid); // init notification
} else {
tvRegion.setText("Beacon not found"
+ "\nLast found " + dateFormat.format(date)
+ "\nSet on 30 mins interval"
);
}
}
}
}
In Manifest,
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".BeaconReferenceApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:launchMode="singleInstance" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
As for the error, here is my full logcat debug. As you can see, there is a lot of Cannot contact service to set scan periods
. I'm assuming it doesn't do the set scan period correctly.
How can I make it scan when I turn on the app, and also scan it in background when the app is closed?
Upvotes: 0
Views: 2024
Reputation: 65025
The way the code is set up, it will only launch the activity the first time it sees a beacon. This is because the regionBootstrap.disable();
line of code essentially stops beacon detections.
If you take out the line regionBootstrap.disable();
then it will send an intent to launch the activity each time it starts seeing a beacon matching your region. Because you have the activity marked as singleInstance
in the manifest, this will re-launch the same activity if it had already been launched.
Upvotes: 1