如何在仪器内注册广播接收器?

时间:2017-02-01 18:51:50

标签: android broadcastreceiver android-bluetooth uiautomator android-instrumentation

我试图通过运行为android junit runner的apk获取蓝牙发现结果。一切正常,但registerReciever我得到以下错误。可能是什么原因?

  

java.lang.SecurityException:给定调用程序包com.ex.test未在进程ProcessRecord中运行{d740580 19462:com.ex / u0a302}

代码 -

@Test
public void demo() throws Exception {

    Context ctx = InstrumentationRegistry.getInstrumentation().getContext();
    BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();

    if (mBtAdapter.isDiscovering()) {
        System.out.println("Stop ongoing discovery");
        mBtAdapter.cancelDiscovery();
    }
    System.out.println("Start fresh discovery");
    mBtAdapter.startDiscovery();

    DisciveryRecv dReceiver = new DisciveryRecv ();
    // Register for broadcasts when a device is discovered
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    ctx.registerReceiver(dReceiver, filter);
}


public class DisciveryRecv extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction(); 
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            String dev = device.getName() + " - " + device.getAddress();
            mUtils.log("Found: " + dev);
        }
    }
}

startDiscovery工作正常,但在ctx.registerReceiver(dReceiver, filter);,app正在抛出异常。

仪器cmd -

  

adb shell am instrument -w -r -e debug false -e class com.ex.main#demo com.ex / android.support.test.runner.AndroidJUnitRunner

2 个答案:

答案 0 :(得分:3)

InstrumentationRegistry.getTargetContext()返回被测试应用程序的上下文。

InstrumentationRegistry.getContext()返回运行测试的Instrumentation的Context。

然后,如果您想要按照您所描述的情况注册接收器,则需要应用程序上下文。但是,这并不是真正测试您的应用程序接收广播,因为接收器不属于您的应用程序。

无论如何,回答第二个问题,使用InstrumentationRegistry.getContext()的原因是您的测试需要访问不属于应用程序但仅用于测试的资源或文件。

修改

这里有一个例子。两个文件,一个在app中,另一个在test

src/androidTest/assets/sometestfile
src/main/assets/someappfile

然后您可以根据上下文访问它们

@Test
public final void testAccessToAppAssetsFromTest() throws IOException {
    final AssetManager assetManager = mInstrumentation.getTargetContext().getAssets();
    assetManager.open("someappfile");
}

@Test
public final void testAccessToTestAssetsFromTest() throws IOException {
    final AssetManager assetManager = mInstrumentation.getContext().getAssets();
    assetManager.open("sometestfile");
}

如果您尝试相反,测试将失败。

答案 1 :(得分:0)

我自己找到了答案。使用InstrumentationRegistry.getTargetContext()解决了我的问题。

  

InstrumentationRegistry.getInstrumentation(),返回当前正在运行的Instrumentation。

     

InstrumentationRegistry.getContext(),返回此Instrumentation包的Context。

     

InstrumentationRegistry.getTargetContext(),返回目标应用程序的应用程序上下文。

以下是一些信息 - https://developer.android.com/reference/android/support/test/InstrumentationRegistry.html#getTargetContext()

但我仍然不确定何时使用InstrumentationRegistry.getContext() ...