2011年8月30日 星期二

[Android] How to read and parse xml files in android application.

I have a xml file named books.xml that is stored in my pad.

<?xml version="1.0" encoding="UTF-8"?>
<library-metadata title="My library">
  <book-metadata name="One Day" author="Nicholls, David">
    <publish-info publisher="Random House Inc" date="05-24-2011" ISBN="9780307946713"/>
  </book-metadata>
  <book-metadata name="Transformers: Exodus" author="Irvine, Alex">
    <publish-info publisher="Random House" date="06-28-2011" ISBN="9780345522528"/>
  </book-metadata>
</book-metadata>

I want to read the xml content and save it to my custom class.
The code as below.


        final String path = Environment.getExternalStorageDirectory().getPath() + "/books.xml";
        FileInputStream fstream = null;
        try
        {
            // read file.
            fstream = new FileInputStream(path);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(fstream);
            Element root = document.getDocumentElement();


            NodeList bookList = root.getElementsByTagName("book-metadata");
            for (int i = 0; i < bookList.getLength(); i++)
            {
                Element bookElement = (Element) bookList.item(i);


                NodeList publishList = bookElement.getElementsByTagName("publish-info");
                for (int j = 0; j < publishList.getLength(); j++)
                {
                    classBooks myBook = new classBooks();
                    Element publishElement = (Element) publishList.item(j);


                    // get xml value and set it into class object.
                    myBook.setName(Integer.parseInt(bookElement.getAttribute("name")));
                    myBook.setAuthor(bookElement.getAttribute("author"));
                    myBook.setPublisher(publishElement.getAttribute("publisher"));
                    myBook.setPublishDate(publishElement.getAttribute("date"));
                    myBook.setISBN(publishElement.getAttribute("ISBN"));


                    m_bookList.add(myBook);  // m_bookList is a member collection variable.
                }
            }
        }
        catch (Exception exception)
        {
            exception.printStackTrace();
        }
        finally
        {
            if (null != fstream)
            {
                fstream.close();
            }
        }

2011年8月2日 星期二

[.Net] Can't find PInvoke DLL 'sqlceme35.dll

You need to install Compact on the device if you met the problem.


1. Copy the file sqlce.ppc.wce5.armv4i.CAB in the path 
C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\Devices\wce500\armv4i into device or emulator


2. execute it on device.




Reference:
http://social.msdn.microsoft.com/Forums/en-US/sqlce/thread/8faa4e72-2dfe-44d4-b8b1-8fd64df01e7d/






[.Net] Emulate a storage card using folder sharing

We hope to simulate a storage card insert into Microsoft Device Emulator.
We have to create a folder shared to the emulator, it appears as a storage card.
You can also stop folder sharing when you no longer want to work with an emulated storage card.


To activate folder sharing

  1. On the Device Emulator File menu, click Configure.
  2. Select the General tab.
  3. In the Shared folder box, type the path and folder name for the directory you want to use as an emulated storage card. (also can click the Browse button, navigate to the directory that you want to use.)
  4. Click OK.


Reference:
http://msdn.microsoft.com/en-us/library/aa188184(v=vs.90).aspx

2011年7月27日 星期三

[Android] Read string from external files

There is a txt file named text.txt and it's content as below.
hello string.

I put the file into sdcard of my Pad under folder named /myfile.
I want get the content of the file in my android program.

At first of all, making sure your sdcard is ready.

       File fileSDCard = null;
       if(Environment.getExternalStorageState().equals(Environment.MEDIA_REMOVED))
       {
          return;
       }
       else
       {
           fileSDCard = Environment.getExternalStorageDirectory();
       }

next, open the file and read it.
       FileInputStream fstream = null;
       String readString = "";  
       try 
       {
           fstream = new FileInputStream(fileSDCard.getParent() + "/" + fileSDCard.getName() + "/myfile/test.txt");
           StringBuffer buffer = new StringBuffer();
           int readChar; 
           while ((readChar = fstream.read()) != -1) 
           { 
               buffer.append((char) readChar); 
           } 
           fstream.close(); 
           readString = buffer.toString(); 
       } 
       catch (Exception e) 
       {
           e.printStackTrace();
       }

It's done, so easy, isn't it?

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

2011年5月26日 星期四

[Android] Failed to install apk on device: timeout

I got error message as below:


[2011-05-26 15:03:37] Android Launch!
[2011-05-26 15:03:37] adb is running normally.
[2011-05-26 15:03:37] Performing com.test.myActivityactivity launch
[2011-05-26 15:03:37] Automatic Target Mode: using device '10005231b7a7'
[2011-05-26 15:03:37] Uploading myActivity.apk onto device '10005231b7a7'
[2011-05-26 15:03:46] Failed to install myActivity.apk on device '10005231b7a7': timeout 
[2011-05-26 15:03:46] Launch canceled!


This is cause by insufficient time out limit in eclipse default setting.
You can change the limit at Window -> Preference -> Android -> DDMS