2016-10-09 3 views
0

Ich möchte, dass meine Anwendung nach Beacons im Hintergrund sucht. Wenn sie mit meinen Beacons übereinstimmen, wird ein Dialog geöffnet. So habe ich diese KlasseAltBeacon: So finden Sie eine Liste von Beacons mit RegionBootstrap und RangeNotifier

import android.app.Application; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.app.TaskStackBuilder; 
import android.content.Context; 
import android.content.Intent; 
import android.os.RemoteException; 
import android.support.v4.app.NotificationCompat; 
import android.util.Log; 

import org.altbeacon.beacon.Beacon; 
import org.altbeacon.beacon.BeaconConsumer; 
import org.altbeacon.beacon.BeaconManager; 
import org.altbeacon.beacon.BeaconParser; 
import org.altbeacon.beacon.RangeNotifier; 
import org.altbeacon.beacon.Region; 
import org.altbeacon.beacon.powersave.BackgroundPowerSaver; 
import org.altbeacon.beacon.startup.RegionBootstrap; 
import org.altbeacon.beacon.startup.BootstrapNotifier; 

import java.util.Collection; 


/** 
* Created by GIS on 28/09/2016. 
*/ 

public class App extends Application implements BootstrapNotifier,RangeNotifier { 
    private static final String TAG = "BeaconReferenceApp"; 
    private RegionBootstrap regionBootstrap; 
    private BackgroundPowerSaver backgroundPowerSaver; 
    private boolean haveDetectedBeaconsSinceBoot = false; 
    private MainActivity main=null; 
    private BeaconManager mBeaconManager; 


    public void onCreate() { 
     super.onCreate(); 

     TypefaceUtil.overrideFont(getApplicationContext(), "DEFAULT", "fonts/ir.ttf"); 
     TypefaceUtil.overrideFont(getApplicationContext(), "MONOSPACE", "fonts/ir.ttf"); 
     TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/ir.ttf"); 
     TypefaceUtil.overrideFont(getApplicationContext(), "SANS_SERIF", "fonts/ir.ttf"); 

//  startService(new Intent(this, TestBestzBeaconService.class)); 


     mBeaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this); 

     // 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. To find the proper 
     // layout expression for other beacon types, do a web search for "setBeaconLayout" 
     // including the quotes. 
     // 
     //beaconManager.getBeaconParsers().clear(); 
     //beaconManager.getBeaconParsers().add(new BeaconParser(). 
     //  setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")); 

     mBeaconManager.getBeaconParsers().clear(); 
     mBeaconManager.getBeaconParsers().add(new BeaconParser(). 
       setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24")); 
     mBeaconManager.getBeaconParsers().add(new BeaconParser(). 
       setBeaconLayout("x,s:0-1=feaa,m:2-2=20,d:3-3,d:4-5,d:6-7,d:8-11,d:12-15")); 
     mBeaconManager.getBeaconParsers().add(new BeaconParser(). 
       setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19")); 
     mBeaconManager.getBeaconParsers().add(new BeaconParser(). 
       setBeaconLayout("s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20v")); 
     mBeaconManager.getBeaconParsers().add(new BeaconParser(). 
       setBeaconLayout("s:0-1=fed8,m:2-2=00,p:3-3:-41,i:4-21v")); 
     Log.d(TAG, "setting up background monitoring for beacons and power saving"); 
     // wake up the app when a beacon is seen 
     Region region = new Region("backgroundRegion", 
       null, null, null); 
     regionBootstrap = new RegionBootstrap(this, region); 

     // simply constructing this class and holding a reference to it in your custom Application 
     // class will automatically cause the BeaconLibrary to save battery whenever the application 
     // is not visible. This reduces bluetooth power usage by about 60% 
     backgroundPowerSaver = new BackgroundPowerSaver(this); 

     // If you wish to test beacon detection in the Android Emulator, you can use code like this: 
     // BeaconManager.setBeaconSimulator(new TimedBeaconSimulator()); 
    // ((TimedBeaconSimulator) BeaconManager.getBeaconSimulator()).createTimedSimulatedBeacons(); 

    } 

    @Override 
    public void didEnterRegion(Region arg0) { 
     // In this example, this class sends a notification to the user whenever a Beacon 
     // matching a Region (defined above) are first seen. 
     try { 
      mBeaconManager.startRangingBeaconsInRegion(arg0); 
     } 
     catch (RemoteException e) { 
      Log.d(TAG, "Can't start ranging"+e.getMessage()); 
     } 
     Log.d(TAG, "did enter region."); 
     if (!haveDetectedBeaconsSinceBoot) { 
      Log.d(TAG, "auto launching MainActivity"); 

      // The very first time since boot that we detect an beacon, we launch the 
      // MainActivity 
      Intent intent = new Intent(this, MainActivity.class); 
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      // Important: make sure to add android:launchMode="singleInstance" in the manifest 
      // to keep multiple copies of this activity from getting created if the user has 
      // already manually launched the app. 
      this.startActivity(intent); 
      haveDetectedBeaconsSinceBoot = true; 
     } else { 
      if (main != null) { 
       // If the Monitoring Activity is visible, we log info about the beacons we have 
       // seen on its display 
       Log.d(TAG, "I see a beacon again"); 
      } else { 
       // If we have already seen beacons before, but the monitoring activity is not in 
       // the foreground, we send a notification to the user on subsequent detections. 
       Log.d(TAG, "Sending notification."); 
       sendNotification(); 
      } 
     } 


    } 

    @Override 
    public void didExitRegion(Region region) { 

      Log.d(TAG, "I no longer see a beacon."); 

    } 

    @Override 
    public void didDetermineStateForRegion(int state, Region region) { 
     Log.d(TAG, "I have just switched from seeing/not seeing beacons: " + state); 
    } 

    private void sendNotification() { 
     NotificationCompat.Builder builder = 
       new NotificationCompat.Builder(this) 
         .setContentTitle("Beacon Reference Application") 
         .setContentText("An beacon is nearby.") 
         .setSmallIcon(R.drawable.ic_launcher); 

     TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 
     stackBuilder.addNextIntent(new Intent(this, MainActivity.class)); 
     PendingIntent resultPendingIntent = 
       stackBuilder.getPendingIntent(
         0, 
         PendingIntent.FLAG_UPDATE_CURRENT 
       ); 
     builder.setContentIntent(resultPendingIntent); 
     NotificationManager notificationManager = 
       (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); 
     notificationManager.notify(1, builder.build()); 
    } 

    public void setMonitoringActivity(MainActivity activity) { 
     this.main = activity; 
    } 



    @Override 
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { 
     Log.d(TAG, "didRangeBeaconsInRegion"); 
     if (beacons.size() > 0) { 
      Beacon firstBeacon = beacons.iterator().next(); 
      Log.d(TAG, "Beacon ranged: UUID: " 
        + firstBeacon.getId1().toString() + " Major: " 
        + firstBeacon.getId2().toString() + " Minor: " 
        + firstBeacon.getId3().toString()); 

      // Do something with the result 

      // Stop ranging 
      try { 
       mBeaconManager.stopRangingBeaconsInRegion(region); 
      } catch (RemoteException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    // @Override 
    public void onBeaconServiceConnect() { 
     Log.d(TAG, "onBeaconServiceConnect()"); 
    } 
} 

In oben Klasse BootstrapNotifier gut funktioniert. Aber RangeNotifier nicht. BootstrapNotifier sagt, dass es eine Bake in der Nähe gibt, aber es gibt mir keine Liste von Beacons, also habe ich gezwungen, RangeNotifier zu verwenden, aber es funktioniert nicht. Können Sie mir bitte helfen, eine Lösung dafür zu finden? Dank sehr viel

Antwort

1

Achten Sie darauf, den Bereich Anmelder wie folgt festgelegt:

(Wenn Sie Library, Version haben 2.9+)

beaconManager.addRangeNotifier(this);

(Wenn Sie Library, Version pre-2.9)

beaconManager.setRangeNotifier(this);

+0

Vielen Dank, den ich tue, einen Dienst oder eine Anwendung Klasse erstellen müssen, ist genug und es sucht nach Beacons im Hintergrund –

+0

Keine Notwendigkeit für einen Dienst - die Android Beacon Library hat bereits eine, die das Scannen im Hintergrund macht. Die Anwendungsklasse ist ein praktischer Mechanismus in Android, um diesen Dienst beim Start des Scanvorgangs mit Ihrem Anwendungscode zu verknüpfen. – davidgyoung

+0

danke für deine vollständige antwort, –

Verwandte Themen