“注入另一个应用程序需要INJECT_EVENTS权限”错误,在android上测试android apk

时间:2014-09-16 23:24:44

标签: android robotium

我写了一个在apk文件上运行测试的机器人测试。 在这种情况下,我在之前的android poroject中创建了apk文件,因为apk仍处于调试模式。 测试点击并在应用程序中插入数据。

在模拟器中运行时我收到错误“注入另一个应用程序需要INJECT_EVENTS权限”。

我尝试了每次在互联网上发布的洗礼,但无济于事。

以下列出了我尝试的各种措施:

在root上设置模拟器。

在测试开始时让测试睡几秒钟。

添加到清单:

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

aslo将此添加到清单:

android:anyDensity="true"

添加setUp函数:

setActivityInitialTouchMode(true);

aslo在setUp函数中添加:

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

将应用程序从data / appfolder移动到system aoo文件夹。

代码解锁屏幕:

mSolo.unlockScreen();

aslo解锁:

adb shell input keyevent 82

我正在添加代码。 代码包含三个类,以及清单:

班级主要:

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();
    }

}

类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;
    }
}

接口MyRunnable:

package genericTest.test;

import android.view.View;

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


    public void run(View view);

}

清单:

<?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>

0 个答案:

没有答案