Android :java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission

前端 未结 9 1444
感动是毒
感动是毒 2020-12-01 11:48

Hi there I am new to Android Junit testing:

I have written some test code in MainActivityFunctionalTest.java file

MainActivityFunctionalTest.java:

         


        
相关标签:
9条回答
  • 2020-12-01 12:37

    Some more ways to fix "Injecting to another application requires INJECT_EVENTS permission" happening with TouchUtils...

    Eg. the official android developer site shows:

    // Stop the activity - The onDestroy() method should save the state of the Spinner
    mActivity.finish();
    
    // Re-start the Activity - the onResume() method should restore the state of the Spinner
    mActivity = getActivity();
    

    Yet, this can cause the error if in the test method this is followed directly by a TouchUtils.clickView:

    // Stop the activity - The onDestroy() method should save the state of the Spinner
    mActivity.finish();
    
    // Re-start the Activity - the onResume() method should restore the state of the Spinner
    mActivity = getActivity();
    
    // Possible inject error!
    TouchUtils.clickView(this, someView);
    

    However, splitting it into two test methods and allowing setUp() to run in-between appears to fix* the problem (Note this is controlled here by the method name as tests are run alphabetically):

    *this still might fail after an intent was called but no longer does after finish was called

    public void testYTestFinishing() {
    
        TouchUtils.clickView(this, someView);
    
        // Finish & restart the activity
        activity.finish();
    }
    
    // -------------------------------------------
    // Called before every test case method
    @Override
    protected void setUp() throws Exception {
        super.setUp();
    
        setActivityInitialTouchMode(true);
    
        activity = getActivity();
    
        getViews();
    }
    // -------------------------------------------
    
    public void testZOnReturn() {
    
        TouchUtils.clickView(this, someView);
    
    }
    

    Interestingly, putting what's in setUp() before the TouchUtils can both fail and work:

    public void testYTestFinishing() {
    
        TouchUtils.clickView(this, someView);
    
        // Finish & restart the activity
        activity.finish();
    
        setActivityInitialTouchMode(true);
    
        activity = getActivity();
    
        getViews();
    
        // SORRY, this fails here on some builds and succeeds on others
        TouchUtils.clickView(this, someView);
    }
    

    You can also try the waitForActivity timeout directly before the TouchUtils which can* fix it at other times such as after an intent was called:

    *Inject error can still occur if used within the same test method... will need to split out into another method as I show above.

        Instrumentation.ActivityMonitor monitor = getInstrumentation()
            .addMonitor(Instrumentation.ActivityMonitor.class.getName(),
            null, false);
    
        // Wait for activity to fix inject error; Increase or decrease as needed
        monitor.waitForActivityWithTimeout(2000);
    
        // Should no longer fail
        TouchUtils.clickView(this, someView);
    
    0 讨论(0)
  • 2020-12-01 12:42

    I had the same issue and adding the closeSoftKeyboard() method resolved it for me.

    onView(withId(R.id.view)).perform(typeText(text_to_be_typed), closeSoftKeyboard());
    
    0 讨论(0)
  • 2020-12-01 12:45

    I had the same problem, and my code was something like this (for a normal login activity):

        onView(withId(R.id.username))
                .perform(new TypeTextAction("test_user"));
        onView(withId(R.id.password))
                .perform(new TypeTextAction("test123"));
        onView(withId(R.id.login)).perform(click());
    

    The last line was crashing with SecurityException. Turned out after the last text typing, the keyboard was left open, hence the next click was considered on a different application.

    To fix this, I simply had to close the keyboard after typing. I also had to add some sleep to make sure the keyboard is closed, otherwise the test would break every now and then. So the final code looked like this:

        onView(withId(R.id.username))
                .perform(new TypeTextAction("test_user"));
        onView(withId(R.id.password))
                .perform(new TypeTextAction("test123")).perform(closeSoftKeyboard());
        Thread.sleep(250);
        onView(withId(R.id.login)).perform(click());
    

    This worked just fine.

    0 讨论(0)
提交回复
热议问题