How to register broadcast receiver inside instrumentation?

纵饮孤独 提交于 2019-12-11 06:38:26

问题


I am trying to get bluetooth discovery results through an apk which runs as android junit runner. Everything works fine but while registerReciever I get below error. What could be the reason ?

java.lang.SecurityException: Given caller package com.ex.test is not running in process ProcessRecord{d740580 19462:com.ex/u0a302}

Code-

@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 works fine, but at ctx.registerReceiver(dReceiver, filter); , app is throwing exception.

Instrumentation cmd-

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


回答1:


InstrumentationRegistry.getTargetContext() returns the Context of the application under test.

InstrumentationRegistry.getContext() returns the Context of the Instrumentation running the tests.

Then, if you want to register a receiver as in the case you described you need you application Context. However, this is not really testing your application receives the broadcast as the receiver is not part of your it.

Anyway, and answering your second question, the reason to use InstrumentationRegistry.getContext() is when your tests need access to resources or files that are not part of the application but only used in tests.

EDIT

Here there's an example. Two files, one in the app the other in tests

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

then you can access them depending on the context

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

If you try the opposite the test will fail.




回答2:


I have found answer myself. Using InstrumentationRegistry.getTargetContext() solved my problem.

InstrumentationRegistry.getInstrumentation(), returns the Instrumentation currently running.

InstrumentationRegistry.getContext(), returns the Context of this Instrumentation’s package.

InstrumentationRegistry.getTargetContext(), returns the application Context of the target application.

Here are some info- https://developer.android.com/reference/android/support/test/InstrumentationRegistry.html#getTargetContext()

But still I am not sure when to use InstrumentationRegistry.getContext()...



来源:https://stackoverflow.com/questions/41987424/how-to-register-broadcast-receiver-inside-instrumentation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!