Tuesday, December 27, 2011

Recover text messages from nandroid backup

The objective is to restore the text messages that were on my Android phone before it got re-flashed, with an end result of all the old and current text messages being on the phone.

I have a nandroid backup image at ~/work/backup/, and the phone attached by USB with debugging enabled.

Previously I tried to install the yaffs file system on a Linux box and mount the image over loop back, however that did not work, the images failed to mount.

The solution turns out to be simple...

download the source for unyaffs, a program which extracts all the files form a yaffs image.

download unyaffs.c and unyaffs.h into ~/work/.

compile the source.
cd ~/work
gcc -o unyaffs unyaffs.c

make a target directory and run the program from the target directory.
mkdir data.img
cd data.img
../unyaffs ~/work/backup/data.img

after some quick reading I find that the text message database are at data/com.android.providers.telephony/databases/mmssms.db.

On the phone use SMS Backup & Restore to save the current text messages.

Make a backup of the message database on the phone, just in case.
adb pull /data/data/com.android.providers.telephony/databases/mmssms.db ~/work/mmssms.db-current

Push the pre-flash message database with the old messages onto the phone
adb push ~/work/data.img/data/com.android.providers.telephony/databases/mmssms.db /data/data/com.android.providers.telephony/databases/mmssms.db

Reboot the phone.

Only the old messages should be visible on the phone now.

On the phone use SMS Backup & Restore to restore the text messages that were just saved, there should be no need to check for duplicate messages.

All the messages should be visible now. All done.

Saturday, December 24, 2011

Minimal Swing GUI example

A well behaved graphical application will place windows like other applications on the platform place them, and will exit when the last window is closed, and also all GUI work will happen on the event thread, this example does all of that.

package org.yi.happy.teaching.gui;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class SwingLaunch {
    public static void main(String[] args) {

        /* ALL GUI work should be done on the event thread */
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {

                /* make a window */
                JFrame frame = new JFrame(SwingLaunch.class.getName());
                frame.pack();

                /*
                 * when all the windows are disposed the application will exit,
                 * make the window automatically dispose when it is closed
                 */
                frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

                /* put the window where the platform would put it */
                frame.setLocationByPlatform(true);

                /* show the window on the screen */
                frame.setVisible(true);
            }
        });
    }
}

For Day Job I have also written a GUI Launcher class that takes a swing component or a class and launches a window containing it with these settings.