2014-10-20 55 views
0

我使用android-beacon-library (altbeacon)來檢測周圍,前景和背景的信標。我使用了Samples中顯示的示例。我成功地讓它檢測到我的一個燈塔,但它並不真正工作。有時它會檢測並打開新的活動,有時它不會。altbeacon - 無法聯繫服務來設置掃描週期

不知道這是我的編碼錯誤還是別的。至於我的理解,通過在Application類中實現BeaconManager初始化,它會在應用程序打開後自動掃描信標。所以,我沒有在我的Activity類中初始化任何東西,我只是讓它掃描應用程序級別。

我已經通過BeaconManager指定我的燈塔在應用程序類,如下所示:

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); 
    } 

} 

在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" 
       ); 
      } 
     } 
    } 

} 

清單中,

<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> 

對於錯誤,這裏是我的full logcat debug。正如你所看到的,有很多Cannot contact service to set scan periods。我假設它沒有正確設置掃描週期。

當我打開應用程序並在應用程序關閉時還在後臺掃描它時,我該如何進行掃描?

+0

我很抱歉現在評論,但我有同樣的問題,我想知道你是如何解決這個PLZ? – hanaa 2015-07-23 12:39:14

回答

1

代碼設置的方式,它只會在第一次看到信標時啓動活動。這是因爲regionBootstrap.disable();代碼行基本上停止了信標檢測。

如果你拿出regionBootstrap.disable();這條線,那麼它會在每次開始看到與你的區域相匹配的信標時發送一個啓動活動的意圖。由於清單中標記爲singleInstance的活動,如果它已經啓動,它將重新啓動相同的活動。

+0

但是,如果我註釋掉這一行,它將始終在不調用'didEnterRegion'的情況下循環掃描。但是如果我關閉了應用程序,它將開始掃描期間。有沒有辦法來解決這個問題? – AimanB 2014-10-23 09:26:34

+0

我不確定我是否理解這個問題。 RegionBootstrap的全部用途是在後臺掃描並啓動或以其他方式喚醒您的應用程序,所以是的,它必須在關閉應用程序的可見活動後在後臺掃描才能執行此操作。由於這聽起來像是一個新的(儘管相關)問題,請考慮發佈一個新問題並將其鏈接到此處。 – davidgyoung 2014-10-23 12:37:14