2014-07-09 6 views
10

मैंने हाल ही में एस्टिमोट बीकन का परीक्षण शुरू किया है, और मैं बीकन क्षेत्र में प्रवेश करते समय पृष्ठभूमि सेवा से अधिसूचना लॉन्च करने की कोशिश कर रहा हूं, लेकिन दुर्भाग्य से मेरा समाधान काम नहीं करता है। यह त्रुटियां नहीं देता है लेकिन एक बीकन की खोज होने पर अधिसूचना लॉन्च नहीं की जा रही है। मुझे नहीं पता कि यह कुछ कोड त्रुटि है या बस इसे करने का तरीका गलत है। मैं this अन्य सवाल पढ़ा है, लेकिन यह कुछ अलग लग रहा है कि मैं क्या उपयोग करने के बाद से एक गतिविधि के बजाय एक सेवा है, लेकिन शायद इस सवाल का जवाब समान है (एप्लिकेशन संदर्भ से संबंधित) ...पृष्ठभूमि में एक सेवा से एस्टिमोट बीकन क्षेत्र का पता लगाने

यहाँ मेरी सेवा कोड

है
public class BeaconsMonitoringService extends Service{ 

    private BeaconManager beaconManager; 

    private String user; 

    @Override 
     public void onCreate() { 
     // Configure BeaconManager. 
     beaconManager = new BeaconManager(this); 

     } 

     @Override 
     public int onStartCommand(Intent intent, int flags, int startId) { 
      Toast.makeText(this, "Beacons monitoring service starting", Toast.LENGTH_SHORT).show(); 

      user = intent.getStringExtra("user"); 

      // Check if device supports Bluetooth Low Energy. 
      if (!beaconManager.hasBluetooth()||!beaconManager.isBluetoothEnabled()) { 
       Toast.makeText(this, "Device does not have Bluetooth Low Energy or it is not enabled", Toast.LENGTH_LONG).show(); 
       this.stopSelf(); 
      } 

       connectToService(); 


      // If we get killed, after returning from here, restart 
      return START_STICKY; 
     } 

     @Override 
     public IBinder onBind(Intent intent) { 
      // We don't provide binding, so return null 
      return null; 
     } 

     @Override 
     public void onDestroy() { 
     Toast.makeText(this, "Beacons monitoring service done", Toast.LENGTH_SHORT).show(); 
     } 

     private void connectToService() { 


      beaconManager.connect(new BeaconManager.ServiceReadyCallback() { 

      @Override 
      public void onServiceReady() { 
       notifyEnterRegion(0); 
//   try { 
        beaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1), 0); 
        Log.i("BEACOON ", "ANTES DE"); 
        beaconManager.setMonitoringListener(new MonitoringListener() { 
        @Override 
        public void onEnteredRegion(Region region, List<Beacon> beacons) { 
         Log.i("BEACOON ", String.valueOf(beacons.get(1).getMinor())); 
        for (Beacon beacon: beacons){ 
         Log.i("BEACOON ", String.valueOf(beacon.getMinor())); 
         if (beacon.getMinor() == 64444) { 

          notifyEnterRegion(6444); 

         } else if (beacon.getMinor() == 36328) { 

          notifyEnterRegion(36328); 

         } else if (beacon.getMinor() == 31394) { 

          notifyEnterRegion(31394); 

         } 
        } 
        } 

        @Override 
        public void onExitedRegion(Region region) { 

         notifyExitRegion(); 

        } 
        }); 

      } 
      }); 
     } 

     public void notifyEnterRegion(int code) { 

      Toast.makeText(this, "Beacon "+code, Toast.LENGTH_SHORT).show(); 

      Intent targetIntent = new Intent(this, MainActivity.class); 
      PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

      Notification noti = new Notification.Builder(this) 
      .setContentTitle("Bienvenido "+user+"!") 
      .setContentText("Sólo por estar aquí has ganado....") 
      .setSmallIcon(com.smt.beaconssmt.R.drawable.beacon_gray) 
      .setContentIntent(contentIntent) 
      .getNotification(); 

      NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
      nManager.notify(1, noti); 
     } 

     public void notifyExitRegion(){ 

      AlertDialog.Builder builder = new AlertDialog.Builder(this); 

      builder.setMessage("Hasta pronto!") 
        .setTitle(user+", estás abandonando la zona de beacons"); 

      builder.setPositiveButton("Ver web", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int id) { 
          // User clicked OK button 
          Intent i = new Intent(BeaconsMonitoringService.this, WebViewActivity.class); 
          i.putExtra("web", "http://www.google.com/"); 
          startActivity(i); 
         } 
        }); 
      builder.setNegativeButton("Adios!", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int id) { 
          // User cancelled the dialog 
         } 
        }); 

      AlertDialog dialog = builder.create(); 

      dialog.show(); 
     } 



} 

मैं किसी भी तरह की मदद की सराहना करता हूं, अग्रिम धन्यवाद!

उत्तर

8

यह कोड मेरे लिए काम कर रहा है। सुनिश्चित करें कि आप सही यूयूआईडी, नाबालिग और प्रमुख संख्याएं रख रहे हैं।

//Using something like that as global variable 

    private static final Region[] BEACONS = new Region[] { 
    new Region("beacon1", "uuid1", 1, 19227), //uuid without "-" 
    new Region("beacon2", "uuid2", 1, 61690), 
    new Region("beacon3", "uuid3", null, null) 
}; 
//Note: setting minor == null and major == null will detect every beacon with that uuid 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     startMonitoring(); 
     return START_STICKY; 
    } 



private void startMonitoring() { 
    if (beaconManager == null) { 
     beaconManager = new BeaconManager(this); 

     // Configure verbose debug logging. 
     L.enableDebugLogging(true); 

     /** 
     * Scanning 
     */ 
     beaconManager.setBackgroundScanPeriod(TimeUnit.SECONDS.toMillis(1), 1); 

     beaconManager.setRangingListener(new RangingListener() { 

      @Override 
      public void onBeaconsDiscovered(Region paramRegion, List<Beacon> paramList) { 
       if (paramList != null && !paramList.isEmpty()) { 
        Beacon beacon = paramList.get(0); 
        Proximity proximity = Utils.computeProximity(beacon); 
        if (proximity == Proximity.IMMEDIATE) { 
         Log.d(TAG, "entered in region " + paramRegion.getProximityUUID()); 
         postNotification(paramRegion); 
        } else if (proximity == Proximity.FAR) { 
         Log.d(TAG, "exiting in region " + paramRegion.getProximityUUID()); 
         removeNotification(paramRegion); 
        } 
       } 
      } 

     }); 

     beaconManager.connect(new BeaconManager.ServiceReadyCallback() { 
      @Override 
      public void onServiceReady() { 
       try { 
        Log.d(TAG, "connected"); 
        for (Region region : BEACONS) { 
         beaconManager.startRanging(region); 
        } 
       } catch (RemoteException e) { 
        Log.d("TAG", "Error while starting monitoring"); 
       } 
      } 
     }); 
    } 
} 

*** संपादन: कोड सटीकता

public static double computeAccuracy(Beacon beacon) 
{ 
    if (beacon.getRssi() == 0) 
    { 
     return -1.0D; 
    } 

    double ratio = beacon.getRssi()/beacon.getMeasuredPower(); 
    double rssiCorrection = 0.96D + Math.pow(Math.abs(beacon.getRssi()), 3.0D) % 10.0D/150.0D; 

    if (ratio <= 1.0D) 
    { 
     return Math.pow(ratio, 9.98D) * rssiCorrection; 
    } 
    return (0.103D + 0.89978D * Math.pow(ratio, 7.71D)) * rssiCorrection; 
} 

public static Proximity proximityFromAccuracy(double accuracy) 
{ 
    if (accuracy < 0.0D) 
    { 
     return Proximity.UNKNOWN; 
    } 
    if (accuracy < 0.5D) 
    { 
     return Proximity.IMMEDIATE; 
    } 
    if (accuracy <= 3.0D) { 
     return Proximity.NEAR; 
    } 
    return Proximity.FAR; 
} 



public static Proximity computeProximity(Beacon beacon) { 
    return proximityFromAccuracy(computeAccuracy(beacon)); 
} 
+0

ठीक है, यह समाधान काम कर रहा है, धन्यवाद! लेकिन मुझे इसके बारे में एक संदेह है, आप "निकटता की गणना कैसे करते हैं"? एसडीके या आधिकारिक कोड में कुछ है या आपका स्वयं का समाधान है? तो इससे मैं समझता हूं कि BeaconManager.setMonitoringListener() इस मामले में प्रयोग योग्य नहीं है और हमें इसके बजाय setRangingListener() का उपयोग करना है ?? – Hugo

+0

सटीकता की गणना करने के लिए कोड एसडीके में होना चाहिए। लेकिन मैं एक कस्टम एसडीके कार्यान्वयन का उपयोग कर रहा हूं इसलिए मैंने आपको कोड दिखाने के लिए उत्तर संपादित किया। SetMonitoringListener के बारे में मुझे यह काम नहीं मिल सका, इसलिए मैं इस समाधान का उपयोग करना समाप्त कर देता हूं। – jDur

+0

मैं अपने ज़ैमरिन एप्लिकेशन के लिए एकीकृत कर रहा हूं, यहां एंटररेगियन और ExitRegion क्रमशः कई बार कॉल करता है, पता नहीं क्यों? मैंने इसके बारे में पढ़ा है, यह तब तभी ट्रिगर होना चाहिए जब डिवाइस क्षेत्र की सीमा के अंतर्गत आता है। लेकिन जब यह रेंज में आता है तो यह अनुक्रमिक रूप से ट्रिगर होता है जब तक कि डिवाइस बीकन की सीमा से बाहर नहीं जाता। कृपया इस –

0

चेक यह एक मुझे आशा है कि यह तुम्हारी मदद करेगा गणना करने के लिए। आप इस फ़ंक्शन Utils.computeProximity(nearestBeacon) से निकटता पा सकते हैं।

beaconManager.setRangingListener(new BeaconManager.RangingListener() { 

     @Override 
     public void onBeaconsDiscovered(Region region, final List<Beacon> beaconList) { 
      if (!beaconList.isEmpty()) { 
       Beacon nearestBeacon = beaconList.get(0); 
       Log.e("Current Proximity - ", String.valueOf(Utils.computeProximity(nearestBeacon))); 
      } 
     } 
}); 
0

आपकी सेवा से, आप भी इस library का उपयोग iBeacons के लिए स्कैन करने सकता है। यह आपके उपयोगकर्ताओं को कुछ battery बचा सकता है। मैं इसे भी पसंद करूंगा, क्योंकि बीकनमेनगर वास्तव में अपनी स्वयं की सेवा उत्पन्न करता है, और इसलिए आपके पास आईबीकॉन स्कैन करने के लिए केवल 2 सेवाएं चल रही हैं। हालांकि इसमें दूरी गणना की कमी है।

इसके अलावा कि बात नहीं, iBeacons आप की जरूरत के लिए स्कैन करने:

  • एक ब्लूटूथ LE चिप है: किसी भी।
  • ब्लूटूथ पर है: कोई भी।
  • पर स्थान है: एंड्रॉइड 6+।
  • स्थान रनटाइम अनुमति है: एंड्रॉइड 6+।
  • 30 सेकंड में अधिकतम प्रारंभ 5 स्कैन: एंड्रॉइड 7+।

और अपने सेवा चल रही आप निम्नलिखित प्रसारण श्रोताओं को जोड़ना होगा रखने के लिए:

  • स्थान राज्य बदल
  • ब्लूटूथ राज्य बदल
  • बूट रिसीवर

इन से रिसीवर आपको अपनी सेवा फिर से शुरू करनी चाहिए।

संबंधित मुद्दे