Я занимаюсь разработкой приложения для сканирования маяков, используя библиотеку altbeacon
в Android.На переднем плане это обнаружение правильно.Но в фоновом режиме, используя regiobootstrap
, он не обнаруживает.didenterrgion
и didexitregion
не звонит.Только didDetermineStateForRegion
звонит с состоянием 0. Мне нужно запустить действие, когда маяк обнаружен в фоновом режиме.Пожалуйста, помогите мне.
public class MyApplication extends Application implements BootstrapNotifier {
private static final String TAG = ".MyApplicationName";
private RegionBootstrap regionBootstrap;
private Identifier identifier;
@Override
public void onCreate() {
Log.d(TAG, "App started up");
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
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"));
identifier = Identifier.parse("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"); //beacon 1
beaconManager.setBackgroundBetweenScanPeriod(5001);
beaconManager.setBackgroundScanPeriod(5001);
// Изменения, внесенные сейчас
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Scanning for Beacons");
Intent intent = new Intent(this, SplashActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("My Notification Channel ID",
"My Notification Name", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("My Notification Channel Description");
NotificationManager notificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
builder.setChannelId(channel.getId());
}
beaconManager.enableForegroundServiceScanning(builder.build(), 456);
beaconManager.setEnableScheduledScanJobs(false);
Region region = new Region("com.example.myapp.boostrapRegion", identifier, null, null);
regionBootstrap = new RegionBootstrap(this, region);
super.onCreate();
}
@Override
public void didEnterRegion(Region region) {
/*regionBootstrap.disable();*/
Log.i(TAG, "didenterregion");
Toast.makeText(this, "entered", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, SplashActivity.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);
}
@Override
public void didExitRegion(Region region) {
Log.i(TAG, "didexitregion!");
Toast.makeText(this, "exit", Toast.LENGTH_SHORT).show();
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
Log.i(TAG, " diddeterminateregion!" +i);
Toast.makeText(this, ""+i, Toast.LENGTH_SHORT).show();
}
}
Вот мой фрагмент сканирования переднего плана:
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d("scannerfragment","oncraeteview");
view= inflater.inflate(R.layout.fragment_scanning, container, false);
beaconManager = BeaconManager.getInstanceForApplication(getActivity());
bt_scan_again=view.findViewById(R.id.bt_scan_again);
bt_scan_again.setOnClickListener(this);
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.setForegroundScanPeriod(5001);
beaconManager.setForegroundBetweenScanPeriod(5001);
identifier = Identifier.parse("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"); //beacon 1
region = new Region("myMonitoringUniqueId", identifier, null, null);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.bt_scan_again:
beaconManager.bind(this);
}
}
@Override
public void onBeaconServiceConnect() {
beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) {
Log.i(TAG, "I just saw an beacon for the first time!");
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void didExitRegion(Region region) {
Log.i(TAG, "I no longer see an beacon");
try {
beaconManager.stopRangingBeaconsInRegion(region);
lay_no_offer.setVisibility(View.VISIBLE);
lay_having_offer.setVisibility(View.GONE);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void didDetermineStateForRegion(int state, Region region) {
Log.i(TAG, "I have just switched from seeing/not seeing beacons: "+state);
if(state==1){
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}else if(state==0){
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", identifier, null, null));
} catch (RemoteException e) { }
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
Collections.sort((List<Beacon>) beacons, new Comparator<Beacon>()
{
@Override
public int compare(Beacon o1, Beacon o2) {
return Double.compare(o2.getDistance(),( o1.getDistance()));
}
});
mac1=((List<Beacon>) beacons).get(0).getBluetoothAddress();
call_offers_api(mac1);
}
@Override
public void onDestroyView() {
super.onDestroyView();
beaconManager.unbind(this);
Log.i(TAG, "unbineed");
Log.d("scannerfragment","ondestroyview");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("scannerfragment","ondestroy");
}
}