2014-10-20 26 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