3

I writed a robotium test that runs a test on a apk file. In this case i created the apk file in a previous android poroject, as the apk is still in a debug mode. the test clicks and inserts data in the app.

as running it in emulator i get the error "Injecting to another application requires INJECT_EVENTS permission".

i tried every selution thst i finded in the internet, But to no avail.

Here is a list of the selutions i tried:

setting emulator on root.

making the test sleep for e few seconds in beginng of test.

adding to manifest:

<uses-permission android:name="android.permission.INJECT_EVENTS"/>

aslo adding this to manifest:

android:anyDensity="true"

adding in setUp function:

setActivityInitialTouchMode(true);

aslo adding this in setUp function:

KeyguardManager km = 
              (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
    if (km.inKeyguardRestrictedInputMode())
    {
      KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
      lock.disableKeyguard();
      SystemClock.sleep(2000);
    }

moved the app from data/appfolder to system aoo folder.

unlocked screen in code with:

mSolo.unlockScreen();

aslo unlocked with:

adb shell input keyevent 82

i am adding the code. the code contains three classes, and the manifest:

class Main:

package genericTest.test;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.SingleLaunchActivityTestCase;
import android.util.Log;
import android.view.Display;
import android.view.View;

import com.robotium.solo.Solo;

@SuppressWarnings("rawtypes")
public class Main extends ActivityInstrumentationTestCase2 {
//public class Main extends SingleLaunchActivityTestCase {  
    //SingleLaunchActivityTestCase
    private FunctonsForViews mFunctonsForViews;
    private Random mRand;
    private Solo mSolo;
    //private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.goldtouch.ynet.ui.activities.SplashActivity";
    private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.bignerdranch.android.criminalintent.CrimeListActivity";
    //in Manifest:  <!--android:targetPackage="com.bignerdranch.android.criminalintent"-->

    //private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.mojang.minecraftpe.MainActivity";
    //in Manifest:  <!--android:targetPackage="com.mojang.minecraftpe"-->

    private final int LIMIT_TIME = 300000;
    private final int DELAY = 200; 
    private final int SCREEN_SIZE = 200;
    private final int ERROR_COUNT_LIMIT = 10;
    private final int CLICK_ON_LOOP_LIMIT = 20;
    private final int WHAITING_FOR_VIEWS_LIMIT = 20;

    private static Class launcherActivityClass;
    private static int error_count = 0;

    static {
        try {
            launcherActivityClass = Class
                    .forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressLint("NewApi")
    @SuppressWarnings("unchecked")
    public Main() throws ClassNotFoundException {
        super(launcherActivityClass);

    }

    protected void setUp() throws Exception {
        setActivityInitialTouchMode(true);
        mSolo = new Solo(getInstrumentation(), getActivity());

        Context context = getActivity();
        int temp = 0;
        KeyguardManager km = 
                  (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
        if (km.inKeyguardRestrictedInputMode())
        {
          KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
          lock.disableKeyguard();
          SystemClock.sleep(2000);
        }
        setActivityInitialTouchMode(true);
    }

    /*
     * runs the test for the app.
     */
    public void testMethod()
    {
        mFunctonsForViews = new FunctonsForViews(mSolo);
        mSolo.sleep(10000);

        mRand = new Random();

        /*
         * the test will take place in the loop, and will be limit in time.
         * in every iteration it will get the vies in activity's, and run a test on a random view.
         */
        for(int i=0 ;i < LIMIT_TIME ; i += DELAY)
        { 
            mSolo.unlockScreen();
            ArrayList Views = mSolo.getViews();
            int arraySize = Views.size();
            if (arraySize == 0)// now View in activity.
            {
                whenNoViewsInScreen(Views, arraySize);
            }
            if (arraySize != 0)
            {
                int ViewIndexInArray = mRand.nextInt(arraySize + 1);
                if (ViewIndexInArray == arraySize)
                {
                    mSolo.scrollDown();
                }
                else
                {
                    View randomView = (View)(Views.get(ViewIndexInArray));
                    runTestOnOneView(randomView);
                }
            }
        }
    }

    /*
     * performing clicks onScreen()
     */
    public void myClickOnScreen()
    {
        try {
            mSolo.unlockScreen();
            mSolo.clickOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
            //mSolo.clickLongOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("in exception of clickOnScreen function.",  "error_count=" + error_count);
            if(error_count > ERROR_COUNT_LIMIT)
            {
                //goingBack();
                error_count = 0;
            }
            //e.printStackTrace();
        } catch (Error e2) {
            e2.printStackTrace();
            Log.e("in error of clickOnScreen function.",  "error_count=" + error_count);
            if(error_count > ERROR_COUNT_LIMIT)
            {
                //goingBack();
                error_count = 0;
            }
            //e2.printStackTrace();
        }   

    }

    /*
     * there is no Views available.
     * we will try pressing on screen or the goBack function.
     */
    public void whenNoViewsInScreen(ArrayList Views, int arraySize)
    {

        for (int j = 0; j < WHAITING_FOR_VIEWS_LIMIT; j++)
        {
            for (int k= 0; k < CLICK_ON_LOOP_LIMIT; k++)
            {   
                myClickOnScreen();
            }

            Views = mSolo.getViews();
            arraySize = Views.size();
            if (arraySize != 0)
            {
                return;
            }
            mSolo.sleep(DELAY);
            Views = mSolo.getViews();
            arraySize = Views.size();
            if (arraySize != 0)
            {
                return;
            }
        }
        goingBack();
        mSolo.sleep(DELAY);

        return;
    }

    public void runTestOnOneView(View randomView)
    {
        String rawViewName = randomView.getClass().getName();
        String viewName = parseRawViewName(rawViewName);
        Log.i("ViewName", viewName);
        //temp
        /*if (viewName.contains("ActionBarContainer"))
        {
            return;
        }*/

        MyRunnable  myRunnable = mFunctonsForViews.getMethodMap().get(viewName);
        try{
            if (myRunnable != null)
            {
                Log.e("myRunnable != null", viewName);
                myRunnable.run((View)randomView);
            }
            else // view not in map.
            {
                boolean inMap = false;
                Iterator it = mFunctonsForViews.getMethodMap().entrySet().iterator();
                /*
                 * iterating in case the View is a version of one of View in map
                 * example:
                 * View is "CustomEditText", and map contains o view "EditText".
                 */
                while (it.hasNext()) 
                {
                    Map.Entry pairs = (Map.Entry)it.next();
                    if (   viewName.contains((String)pairs.getKey())   )
                    {
                        inMap = true;
                        // next two lines changed
                        myRunnable = (MyRunnable)(pairs.getValue());
                        myRunnable.run((View)randomView);

                        break;
                    }
                }
                if (inMap == false)
                {
                    mSolo.clickOnView((View)randomView);
                }

                error_count = 0;
            }
        }catch(Exception exception)
        {
            exception.printStackTrace();
            Log.e("Exception click on view", viewName);
            for (int i=0 ; i < CLICK_ON_LOOP_LIMIT; i++)
            {
                myClickOnScreen();
                error_count ++;
                if(error_count > ERROR_COUNT_LIMIT)
                {
                    goingBack();
                    error_count = 0;
                }
            }
        }catch(Error error)
        {
            error.printStackTrace();
            Log.e("Error click on view ", viewName+ "  " + error.toString());
            for (int i=0 ; i < CLICK_ON_LOOP_LIMIT; i++)
            {
                myClickOnScreen();
                error_count ++;
                if(error_count > ERROR_COUNT_LIMIT)
                {
                    goingBack();
                    error_count = 0;
                }
            }
        }   
        mSolo.sleep(DELAY);
    }

    /*
     * performs a goBack command surrounded with catch/try
     */
    public void goingBack()
    {
        try {
            mSolo.goBack();
        } catch (Exception e) {
            //Log.e("Exeption! ", "Can;t go back" );
            e.printStackTrace();

        } catch (Error e) {
            //Log.e("Error! ", "Can;t go back" );
            e.printStackTrace();
        }
    }

    /*
     * extract the name of View from raw View name.
     * example:
     * raw View name: android.widget.TextView
     * raw View name:TextView
     */
    public String parseRawViewName(String rawViewName)
    {
        if (rawViewName.contains(" "))
        {
            String [] array = rawViewName.split(" ");
            rawViewName = array [0];
        }

        if (rawViewName.contains(".") || rawViewName.contains("$"))
        {
            String [] array = rawViewName.split("\\.|$");
            Log.i("array length:", ""+ array.length);
            rawViewName = array [array.length-1];
        }
        return rawViewName;
    }

    public void tearDown() throws Exception {
        mSolo.finishOpenedActivities();
        //super.tearDown();
    }

}

class FunctonsForViews:

package genericTest.test;

import java.lang.reflect.*;
import java.util.*;

import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TimePicker;

import com.robotium.solo.Solo;

/*
 * contains the functions and parameters running for every View.
 */
public class FunctonsForViews {

    private Map<String, MyRunnable> mMethodMap;
    private Solo mSolo;
    private Random mRand = new Random();
    private final int LIST_TEST_FUNCTIONS = 4;
    private final String TAG = "FunctonsForViews";
    private final String [] editTextMailInput = 
        {"example@gmail.com", "secondExample@gmail.com", "erongFormat","123"};
    private final String [] editTextPasswordInput = 
        {"0987654321", "0987654321a", "12","iioo", "ui9"};
    private final String [] editTextNameInput = 
        {"yoav", "567", "ran","iioott", "iioottrr", "iioottrraaqqhh", "iioottrraaqqhh23"};
    private final String [] editTextTelephoneInput = 
        {"078123456", "078123456a", "dan","4675", "123"};

    //getter
    public  Map<String, MyRunnable> getMethodMap()
    {
        return mMethodMap;
    }

    /*
    * initials the HashMap mMethodMap, and insert the fitting function for handling every View in activity
    */
    public FunctonsForViews(Solo solo)
    {
        mSolo = solo ;
        mMethodMap = new HashMap<String, MyRunnable>();
        try {
            mMethodMap.put("EditText", new MyRunnable() { 
                public void run(View view) { MyEnterText(view); }
            });

            /*
            mMethodMap.put("CustomEditText", new MyRunnable() { 
                public void run(View view) { MyEnterText(view); }
            });*/

            mMethodMap.put("ProgressBar", new MyRunnable() { 
                public void run(View view) { MySetProgressBar(view); }
            });

            mMethodMap.put("TimePicker", new MyRunnable() { 
                public void run(View view) { MySetTimePicker(view); }
            });

            mMethodMap.put("DatePicker", new MyRunnable() { 
                public void run(View view) { MySetDatePicker(view); }
            });

            mMethodMap.put("ListView", new MyRunnable() { 
                public void run(View view) { MyListTest(view); }

            });

            /*
            mMethodMap.put("e", new MyRunnable() { 
                public void run(View view) { doNuthing(view); }

            });
            */

        } catch (Exception e) {
            Log.i(TAG, "Cant put in map");
            e.printStackTrace();
        }
    }


    /*
     * sets random values in the TimePicker View
     */
    public void MySetTimePicker(View view)
    {
        int hour = mRand.nextInt(24);
        int minute = mRand.nextInt(60);
        mSolo.setTimePicker((android.widget.TimePicker)view, hour, minute);
    }

    /*
     * sets random values in the DatePicker View
     */
    public void MySetDatePicker(View view)
    {
        int year = mRand.nextInt((2020 - 1900) ) + 1900;
        int month = mRand.nextInt(12);
        int dayOfMonth = mRand.nextInt((31 - 1) ) + 1;
        mSolo.setDatePicker((android.widget.DatePicker)view, year, month, dayOfMonth);
    }

    /*
     * sets random values in the ProgressBar View
     */
    public void MySetProgressBar(View view)
    {
        ProgressBar progressBar = (ProgressBar)view;
        mSolo.setProgressBar(progressBar, mRand.nextInt(progressBar.getMax()));
    }

    /*
     * calls a random ViewList Solo function
     */
    public void MyListTest(View view)
    {   
        int function = mRand.nextInt(LIST_TEST_FUNCTIONS );
        switch (function)
        {

        case 0:
            if (((((ListView)view).getLastVisiblePosition() 
                                - ((ListView)view).getFirstVisiblePosition()) + 1)  >0)
            {
                mSolo.clickInList(mRand.nextInt(((ListView)view).getLastVisiblePosition() 
                                - ((ListView)view).getFirstVisiblePosition()) + 1);
            }
            break;

        case 1:
            if (((((ListView)view).getLastVisiblePosition() 
                                - ((ListView)view).getFirstVisiblePosition()) + 1)  >0)
            {
                //mSolo.clickLongInList(mRand.nextInt(((ListView)view).getLastVisiblePosition() 
                                //- ((ListView)view).getFirstVisiblePosition()) + 1);
                mSolo.clickInList(mRand.nextInt(((ListView)view).getLastVisiblePosition() 
                        - ((ListView)view).getFirstVisiblePosition()) + 1);
            }
            break;

        case 2:
            mSolo.scrollListToBottom((ListView)view) ;
            break;

        default:
            mSolo.scrollListToTop((ListView)view) ;
            break;

        }
    }

    /*
     * sets the text of a EditText View
     */
    public void MyEnterText(View view)
    {   
        mSolo.clearEditText((android.widget.EditText)view);
        mSolo.enterText((android.widget.EditText)view, getStringForEditTextInput(view));
    }

    /*
     * return a string to be use to set in EditText View.
     * the specific string will be choose randomly.
     */
    public String getStringForEditTextInput(View view)
    {
        ArrayList Views = mSolo.getViews();
        String EditTextInput = null;
        int index = Views.indexOf(view);
        for (int i = index - 1; i> index - 4; i--)
        {
            if (Views.get(i).getClass().getName() == "TextView"  )
            {
                String textViewText = ((TextView)Views.get(i)).getText().toString().toLowerCase();
                if(textViewText.contains("mail"))
                {
                    EditTextInput = editTextMailInput[mRand.nextInt(editTextMailInput.length) ];
                }

                else if(textViewText.contains("password"))
                {
                    EditTextInput = editTextPasswordInput[mRand.nextInt(editTextPasswordInput.length) ];
                }

                else if(textViewText.contains("telephone"))
                {
                    EditTextInput = editTextTelephoneInput[mRand.nextInt(editTextTelephoneInput.length) ];
                }
                return EditTextInput;

            }           
        }
        EditTextInput = editTextNameInput[mRand.nextInt(editTextNameInput.length) ];
        return EditTextInput;
    }
}

interface MyRunnable:

package genericTest.test;

import android.view.View;

/*
 * used for storing function HashMap
 */
public interface MyRunnable  {


    public void run(View view);

}

manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="genericTest.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="7" />
     <uses-permission android:name="android.permission.INJECT_EVENTS"/>
    android:anyDensity=”true"
    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.bignerdranch.android.criminalintent"/>
    />

<supports-screens 
    android:resizeable="true"
    android:smallScreens="true" 
    android:largeScreens="true"
    android:xlargeScreens="true"  
    android:normalScreens="true" 
    android:anyDensity="true"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>
Zag Gol
  • 1,038
  • 1
  • 18
  • 43
  • 2
    You can get that error if another app is active when you try to inject the events. Is the lock screen or some other app stopping your app from becoming active? – Dave C Sep 22 '14 at 16:35
  • Check this:http://stackoverflow.com/questions/22163424/android-java-lang-securityexception-injecting-to-another-application-requires – herbertD Feb 27 '15 at 02:42

0 Answers0