Android 使用ActivityInstrumentationcase2测试应用程序

Android 使用ActivityInstrumentationcase2测试应用程序,android,automated-tests,Android,Automated Tests,当我在模拟器上使用ActivityInstrumentationcase2测试我的应用程序时,它工作正常,但当我在设备上运行它时,它会显示出来 java.lang.SecurityException:注入到另一个应用程序需要INJECT\u EVENTS权限 但我已经在清单文件中给出了这个权限 我的代码是: package cybercom.datamatics.baba.test; import static android.test.ViewAsserts.assertOnScreen;

当我在模拟器上使用ActivityInstrumentationcase2测试我的应用程序时,它工作正常,但当我在设备上运行它时,它会显示出来

java.lang.SecurityException:注入到另一个应用程序需要INJECT\u EVENTS权限

但我已经在清单文件中给出了这个权限

我的代码是:

package cybercom.datamatics.baba.test;

import static android.test.ViewAsserts.assertOnScreen;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.test.InstrumentationTestCase;
import android.test.TouchUtils;
import android.test.suitebuilder.annotation.MediumTest;
import android.view.View;
import cybercom.datamatics.baba.CDIS_SMSActivity;
import cybercom.datamatics.baba.Compose;

public class CDIS_SMSTests extends InstrumentationTestCase 
{
    @MediumTest

    public void testActivity()
    {
        Instrumentation instrumentation = getInstrumentation();
        Instrumentation.ActivityMonitor monitor =instrumentation.addMonitor(CDIS_SMSActivity.class.getName(),null,false);
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setClassName(instrumentation.getTargetContext(),CDIS_SMSActivity.class.getName());
        instrumentation.startActivitySync(intent);

        Activity currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor,5);
        assertNotNull(currentActivity);
        View view = currentActivity.findViewById(cybercom.datamatics.baba.R.id.Composemessage);
        assertNotNull(view);
        View origin = currentActivity.getWindow().getDecorView();
        assertOnScreen(origin, view);

        instrumentation.removeMonitor(monitor);     
        monitor = instrumentation.addMonitor(Compose.class.getName(),null,false);       
        Intent ointent = new Intent();
        ointent.setClassName(instrumentation.getTargetContext(),Compose.class.getName());
        ointent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        instrumentation.startActivitySync(ointent);     
        Activity nextActivity = getInstrumentation().waitForMonitorWithTimeout(monitor,5);
        assertNotNull(nextActivity);

        View numberview = nextActivity.findViewById(cybercom.datamatics.baba.R.id.number);
        assertNotNull(numberview);
        View nextview = nextActivity.getWindow().getDecorView();
        assertOnScreen(nextview, numberview);       
        TouchUtils.clickView(this,numberview);
        instrumentation.sendStringSync("9964973058");

        View messageview = nextActivity.findViewById(cybercom.datamatics.baba.R.id.message);
        assertNotNull(messageview);
        TouchUtils.clickView(this,messageview);
        assertOnScreen(nextview, messageview);

        instrumentation.sendStringSync("hi");       
        View sendview = nextActivity.findViewById(cybercom.datamatics.baba.R.id.send);
        assertNotNull(sendview);
        assertOnScreen(nextview, sendview);
        TouchUtils.clickView(this,sendview);


    }
}

检查您是否正在单击您认为您所在的位置-在我的例子中,这是使用Robotium方法Solo.clickOnView

当我调试代码时,我发现我试图单击的视图的View.getLocationOnScreen方法将值填充为0,0,这显然超出了我和你的应用程序的范围。我仍然不确定为什么视图会报告这些值,但它是DialogFragment中GridView的子视图,谢天谢地,我可以使用GridView计算出正确的偏移量,从此类视图获得正确屏幕位置的代码如下所示:

private int[] getLocationOnScreen(View view) {
    Rect r = new Rect();
    view.getGlobalVisibleRect(r);
    int[] xy = new int[2];
    View viewParent = (View) view.getParent();
    viewParent.getLocationOnScreen(xy);
    xy[0] += r.left;
    xy[1] += r.top;
    viewParent.getGlobalVisibleRect(r);
    xy[0] -= r.left;
    xy[1] -= r.top;
    return xy;
}

emulator也会出现此问题

您必须检查您的屏幕是否未锁定。 当屏幕被锁定时,您正在测试的应用程序没有焦点,因此UI命令被发送到锁定屏幕,而不是您的应用程序。这会引发安全异常


添加权限并不能解决问题,唯一的解决方案是手动或编程解锁屏幕。

您不需要家长在屏幕上获取查看位置。int[]xy=新的int[2];view.getLocationScreenxy;返回xy;够了。顺便说一下,它并没有为这个问题提供答案。