2011年6月17日 星期五

[Android] Generating multitouch MotionEvents for testing

For testing the behaviour of the GestureDetector, i want to send MotionEvents to check action result.


Above android 2.3 we can use the method 'obtain' to get multitouch event.

public static MotionEvent obtain (long downTime, long eventTime, int action, int pointers, int[] pointerIds, PointerCoords[] pointerCoords, int metaState, float xPrecision, float yPrecision, int deviceId, int edgeFlags, int source, int flags)
            //action is an int variable indicate what event type to send. (DOWN, UP, POINIT_DOWN....)
            //point is an PointF array to indecate all coordinates touch on screen.
            int[] pointCoordsID = new int[point.length];
            PointerCoords[] pointCoords = new PointerCoords[point.length];
            for (int i = 0; i < point.length; i++) 
            {
                pointerIds[i] = i;
                pointerCoords[i] = new PointerCoords();
                pointerCoords[i].x = point[i].x;
                pointerCoords[i].y = point[i].y;
            }            
            long downTime = SystemClock.uptimeMillis();
            long eventTime = SystemClock.uptimeMillis();

            MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, point.lenth, pointCoordsID, pointCoords, 0, 1, 1, 0, 0, 0, 0);



#########################################################


If your device or sdk is android 2.2 or lower, you have to create MotionEvent from Parcel as below to perform it.


            //action is an int variable indicate what event type to send. (DOWN, UP, POINIT_DOWN....)
            //point is an PointF array to indecate all coordinates touch on screen.

            Parcel inParcel = Parcel.obtain();

            long downTime = SystemClock.uptimeMillis();
            long eventTime = SystemClock.uptimeMillis();
            inParcel.writeLong(downTime); //DownTime
            inParcel.writeLong(eventTime); //EventTime
            inParcel.writeInt(action);         //Action
            inParcel.writeInt(0);         //MetaState
            inParcel.writeFloat(point[0].x); //RawX
            inParcel.writeFloat(point[0].y); //RawY
            final int NP = m_point.length; //NumPointers
            inParcel.writeInt(NP);
            final int NS = m_point.length; //NumSamples
            inParcel.writeInt(NS);
            final int NI = NP*NS;
            if (NI > 0) 
            {
                int i;               
                //set point index
                for (i=0; i<NP; i++) 
                {
                inParcel.writeInt(i);
                }
                // set location, pressure, size for each sampleData
                int NUM_SAMPLE_DATA = 4;
                final int ND = NI*NUM_SAMPLE_DATA;
                float[] history = new float[ND];;
                for (i = 0; i < m_point.length; i++) 
                {
                history[i*NUM_SAMPLE_DATA] = point[i].x;
                history[i*NUM_SAMPLE_DATA + 1] = point[i].y;
                history[i*NUM_SAMPLE_DATA + 2] = 0;
                history[i*NUM_SAMPLE_DATA + 3] = 0;
                }
                for (i=0; i<ND; i++) 
                {
                inParcel.writeFloat(history[i]);
                }
                // set event time for each sampleData
                for (i=0; i<NS; i++) 
                {
                inParcel.writeLong(eventTime);
                }
            }
            inParcel.writeFloat(1); //PrecisionX
            inParcel.writeFloat(1); //PrecisionY
            inParcel.writeInt(0); //DeviceID
            inParcel.writeInt(0); //EdgeFlags
            
            inParcel.setDataPosition(0);
            
            MotionEvent event = MotionEvent.CREATOR.createFromParcel(inParcel);


###########################################


Reference:
http://stackoverflow.com/questions/3637044/generating-multitouch-motionevents-for-testing

2011年6月16日 星期四

[Android] Error: java.lang.NoClassDefFoundError

I got an error message: java.lang.NoClassDefFoundError

I tried to google antidote all day...

Here is a way to work it out but it doesn't match my case.
http://www.tech-recipes.com/rx/826/java-exception-in-thread-main-javalangnoclassdeffounderror/


Eventually, I found my SDK is android 3.0 but my device is android 2.2... (so stupid...)


Check SDK or device version is necessary.  :~|



2011年6月10日 星期五

[Android] Junit: get private variable, invoke private function

When we writing a JUnit test case, we sometimes need to get private member variable to verify the testing result or invoke private function to simulate software process.
We can use the object named PrivateAccessor to get private member like below.

To get private variable:
Integer.parseInt(PrivateAccessor.getPrivateField(Object, "Index").toString());

To invoke private function:
// The arguments to be passed to method
Object[] params = new Object[1]; 
params[0] = 0;
PrivateAccessor.invokePrivateMethod(Object, "functionName", params); 


Reference:
http://junit-addons.sourceforge.net/junitx/util/PrivateAccessor.html

2011年6月7日 星期二

[Android] Bound mismatch: The type XXX is not a valid substitute for the bounded parameter of the type ActivityInstrumentationTestCase2

I got an error message as title at android unit test case:
Bound mismatch: The type MyActivity is not a valid substitute for the bounded parameter <T extends Activity> of the type ActivityInstrumentationTestCase2<T>

I found the solution at link of reference and extract content as below:
The problem is that the android-support-v4.jar that you are using in your test project is different from the one in your application project. Remove all of the references to android-support-v4.jar from your test project. Then go to your application project Properties->Java Build Path->Order and Export and check android-support-v4.jar to export it. Now both projects will be using the same library, and dalvik won't complain.

Reference:
http://stackoverflow.com/questions/5561353/fragmentactivity-can-not-be-tested-via-activityinstrumentationtestcase2

2011年6月3日 星期五

[Android] Error: Test run failed: Test run incomplete. Expected 1 tests, received 0

I got an error message when execute Android JUnit Test
Test run failed: Test run incomplete. Expected 1 tests, received 0

I use this one

 public ReaderGestureDetectorTest() 
{
super(TestActivity.class);
}



Instead of original one

public ReaderGestureDetectorTest(Class<TestActivity> activityClass)
{
super(activityClass);
}


I work it out but don't know why...

Reference: 
http://code.google.com/p/android/issues/detail?id=8522