Thursday, November 29, 2012

Copy Windows Phone Content To Isolated Storage

Some times a database is deployed with the application as a content file.

However, the database can't be used directly, it must be copied to the storage first.

In this sample code, the content file is copied to the isolated storage if it isn't copied yet.
IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();
String DBFile = "DB.sqlite";
if (!ISF.FileExists(DBFile)) CopyFromContentToStorage(ISF, "Database/DB.sqlite", DBFile);

private void CopyFromContentToStorage(IsolatedStorageFile ISF, String SourceFile, String DestinationFile)
{
    Stream Stream = Application.GetResourceStream(new Uri(SourceFile, UriKind.Relative)).Stream;
    IsolatedStorageFileStream ISFS = new IsolatedStorageFileStream(DestinationFile, System.IO.FileMode.Create, System.IO.FileAccess.Write, ISF);
    CopyStream(Stream, ISFS);
    ISFS.Flush();
    ISFS.Close();
    Stream.Close();
    ISFS.Dispose();
}
private void CopyStream(Stream Input, IsolatedStorageFileStream Output)
{
    Byte[] Buffer = new Byte[5120];
    Int32 ReadCount = Input.Read(Buffer, 0, Buffer.Length);
    while (ReadCount > 0)
    {
        Output.Write(Buffer, 0, ReadCount);
        ReadCount = Input.Read(Buffer, 0, Buffer.Length);
    }
}
The code assumes that the file to be copied is named 'DB.sqlite' that resides in a folder named 'database' and was added to the project as a content file.

Copy Android Asset To Internal Storage

Some times a database is deployed with the application as an asset.

However, the database can't be used directly, it must be copied to the storage first.

In this sample code, the asset is copied to the internal storage if it isn't copied yet.
Context Context = getApplicationContext();
String DestinationFile = Context.getFilesDir().getPath() + File.separator + "DB.sqlite";
if (!new File(DestinationFile).exists()) {
  try {
    CopyFromAssetsToStorage(Context, "Database/DB.sqlite", DestinationFile);
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

private void CopyFromAssetsToStorage(Context Context, String SourceFile, String DestinationFile) throws IOException {
  InputStream IS = Context.getAssets().open(SourceFile);
  OutputStream OS = new FileOutputStream(DestinationFile);
  CopyStream(IS, OS);
  OS.flush();
  OS.close();
  IS.close();
}
private void CopyStream(InputStream Input, OutputStream Output) throws IOException {
  byte[] buffer = new byte[5120];
  int length = Input.read(buffer);
  while (length > 0) {
    Output.write(buffer, 0, length);
    length = Input.read(buffer);
  }
}
The code assumes that the file to be copied is named 'DB.sqlite' and it resides in a folder named 'database' in the assets.

Wednesday, November 28, 2012

Start Thread On Android

You can start a new thread by extending the Thread class or implementing the Runnable interface.

Extending the Thread class:
Thread T = new NewThread();
T.start();

private class NewThread extends Thread {
  @Override
  public void run() {
    //Your asynchronous code
  }
}
Implementing the Runnable interface:
Thread T = new Thread(new NewRunnable());
T.start();

private class NewRunnable implements Runnable {
  public void run() {
    //Your asynchronous code
  }
}
Your activity may implement the Runnable interface directly.
In this case, when creating the Thread object you must pass the activity (this) as the parameter.

Wednesday, November 21, 2012

Prevent Android UI Resize When Keyboard Opens

An android activity may be resized when the soft keyboard opens.

Sometimes that's not the behavior we want.

To disable the resizing, add the following line to the activity declaration on the manifest:

If the UI contains a ScrollView, then you can also add the following to the view declaration to prevent the resizing:
android:isScrollContainer="false" 

Thursday, November 8, 2012

Update Android UI From Other Threads

Asynchronous functions are useful to run code in background so the UI will not freeze.

Those functions can't access the UI directly because they aren't running in the UI thread.

If you try to access the UI from those threads you will get the error:
"Only the original thread that created a view hierarchy can touch its views."

The solutions is to use Handlers.
private Handler YOURHANDLER = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        //do some code in the UI thread
    }
};

public void ASYNCHRONOUSFUNCTION() {
    Message Msg = new Message();
    Msg.obj = "SOME TEXT"; //can be any object
    YOURHANDLER.sendMessage(Msg);
}
In the example, the ASYNCHRONOUSFUNCTION function runs in another thread.

The Message object will contain any information in it's obj property that you want to send to the handler.

Finally, you invoke the sendMessage method of the YOURHANDLER handler.

Programmatically Hide Android SIP

Some times we want to programmatically hide the virtual keyboard (SIP, soft input panel).

This is how you do it:
InputMethodManager IMM = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
IMM.hideSoftInputFromWindow(v.getWindowToken(), 0);
In the code, the V variable may represent any view of the activity.