【问题标题】:Android Beacon Library, Null Object Reference when calling startRangingBeaconsInRegionAndroid Beacon 库,调用 startRangingBeaconsInRegion 时的空对象引用
【发布时间】:2017-02-20 21:29:35
【问题描述】:

我正在使用信标库开发一个 android 应用程序,该应用程序的一部分将通过其次要 ID(由用户通过对话框插入)搜索特定信标。

如果我在同一个活动中编写所有内容,则一切正常,但我想在外部纯 Java 类中保持对话框分开,因此在实现 BeaconConsumer 的活动中,我添加了一个“方法”,创建和绑定信标管理器。

public class Activity03 extends AppCompatActivity
    implements BeaconConsumer, RangeNotifier {

    ...

    public void scanForBeacon(Context context, String selectedMinorId){
        beaconManager = BeaconManager.getInstanceForApplication(context);

        beaconManager.getBeaconParsers().add(new BeaconParser()
            .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

        Identifier minorIdFilter = Identifier.parse(selectedMinorId);

        myRegion = new Region(
            "my_region",
             null,
             null,
             minorIdFilter);

        beaconManager.bind((BeaconConsumer) context);
    }
    ...
}

重点是当调用startRangingBeaconsInRegion时,我得到了:

尝试在空对象引用上调用虚拟方法“void org.altbeacon.beacon.BeaconManager.startRangingBeaconsInRegion(org.altbeacon.beacon.Region)”

顺序是:
1. 要求用户(通过 GoogleApiClient)开启 BLE 和本地化
2. 在 onActivityResult 中,插入次要 ID 的对话框是从 java 类 DialogUtilities
DialogUtilities.showSelectionDialog(Activity03.this);
中挑选出来的 3. 按下按钮对话框被关闭,BeaconConsumer 活动的一个实例被创建并且方法被调用:
Activity03 a03 = new Activity03(); a03.scanForBeacon(context, minorId);
4. 当 onBeaconServiceConnect() 被调用时,我在 startRangingBeaconsInRegion

行得到了空对象引用
@Override
public void onBeaconServiceConnect() {
    try {
        beaconManager.startRangingBeaconsInRegion(myRegion);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

我是 java 和 android 的新手,但在我看来,问题与区域无关,因为即使我将所有标识符都设置为 null,我也有相同的响应,所以我无法理解为什么为 null 引用。 由于 Dialog 返回的活动距离,我是否有可能创建两个不同的 BeaconMangers?如果是这样,我该如何解决?
如果不是,如何避免这个空对象引用?
在此先感谢

编辑
BeaconManager 声明

public class Activity03 extends AppCompatActivity implements BeaconConsumer, RangeNotifier {
    static final int REQUEST_CHECK_SETTINGS = 1000;

    private BeaconManager beaconManager;
    private Region myRegion;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(R.style.AppTheme);
        setContentView(R.layout.activity_03);
    }

    @Override
    protected void onResume() {
          @Override
          super.onResume();
          PermissionsUtilities.switchLocationAndBluetooth(Activity03.this);

    }


    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                          DialogUtilities.showSensorSelectionDialog(Activity03.this);
                    break;
                case Activity.RESULT_CANCELED:
                    ...
                    break;
                default:
                    break;
            }
            break;
    }
}

【问题讨论】:

    标签: java android altbeacon


    【解决方案1】:

    你可以试试下面的代码来避免空指针异常:

      beaconManager.setRangeNotifier(new RangeNotifier() {
                  @Override
                  public void didRangeBeaconsInRegion(Collection beacons, Region region) {
                      if (beacons.size() > 0) {
                          Log.i(TAG, "The first beacon I see is about "+beacons.iterator().next().getDistance()+" meters away.");
                      }
                  }
              });
    
              try {
                  beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
              } catch (RemoteException e) {
                  e.printStackTrace();
              }
    

    【讨论】:

    • 感谢您的建议,我很快根据您的建议重新排列了我的代码,并在setrangeNotifier 上得到了空指针异常;除此之外,我还知道以这种方式使用 setRangeNotifier 已被弃用。
    【解决方案2】:

    该问题没有显示beaconManager的声明以及它的作用域,因此很难说出确切的原因。

    两个提示:

    1. BeaconManager 是一个单例,这意味着每个 Java 进程有一个实例。因此,您始终可以从这样的 Activity 中获取此实例:BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(myRegion);

    2. 如下图手动构造一个新的Activity实例一般在Android编程中是行不通的。您必须使用 Intent 创建新的 Activity 实例。在您的情况下,我怀疑您可能根本不想创建一个新的 Activity 实例,而是要获取对现有实例的引用。这可能与您的要求无关,但肯定需要更改:Activity03 a03 = new Activity03(); a03.scanForBeacon(context, minorId);

    【讨论】:

    • 非常感谢您的及时回复和建议。见上文我编辑了我的问题。我还将通过Intent 重新尝试获取新的活动参考。
    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2016-06-15
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多