Tuesday, 13 October 2009

Use base64 in Android

In my Twitter Client application, I need a encoder for base64. There is a undocumented classes sun.misc.BASE64Encoder. But it's not suggested, because Developers Should Not Write Programs That Call 'sun' Packages.

------------------------
Actually, I can't find anywhere to download sun.misc.BASE64Encoder. Somebody advise that it can be found in /jre/lib/rt.jar. I tried to add it to my build path, but my machine hang-up in build my project. So...I give-up sun.misc.BASE64Encoder finally.
------------------------

Alternatively, there is a package, Commons Codec, from apache.org.

To use the Commons Codec, you have to download it from http://commons.apache.org/codec/download_codec.cgi, and save it to your local driver. The current version 1.4 that requires a minimum of JDK 1.4.

In Eclipse, right click your project > Build Path > Add External Archives >, browse to select the downloaded and extracted JAR.




The syntex to encode a input to base54 is:

import org.apache.commons.codec.binary.Base64;

String outputString = new String(Base64.encodeBase64(inputString.getBytes()));


Both inputString and outputString are in type String.

Actual usage in my Android Twitter Client.

Allows Android applications to open network sockets: "android.permission.INTERNET"

If your Android application need to access Internet, you have to grand permission to open network sockets.

Add the code <uses-permission android:name="android.permission.INTERNET" /> in AndroidManifest.xml,

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidTwitterClient"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidTwitterClient"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-sdk android:minSdkVersion="3" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

EditText for password, inputType="textPassword"


I'm going to make a exercise of Twitter Client to post update status to Twitter. In which I need a EditText, with hiden input of password.

To achieve it, EditText with android:inputType="textPassword" can be used.The input characters will be displayed as password dots instead of themselves.

Alternatively, android:password="true" can be used. But it is deprecated and not suggested.







<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="User Name and Password"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="User Name:"
/>
<EditText
android:id="@+id/username"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Password:"
/>
<EditText
android:id="@+id/password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="What are you doing?"
/>
<EditText
android:id="@+id/whatareyoudoing"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/mySubmit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Submit"
/>
</LinearLayout>

Monday, 12 October 2009

Simulate Animation, using Runnable Thread

After the articles, Display a drawable graph, using ImageView and AndroidRunnable, with Runnable Thread, now we can try to simulate animation using setImageResource(), inside handleMessage() which are trigged by a Runnable Thread. A circle arrow rotate in duration of 1000ms.

This exercise extends from the previous article, AndroidRunnable, with Runnable Thread.




Save the four graphics, used to form the animation of a rotating arrow, in the /res/drawable/ folder.



Add a ImageView in main.xml to display the animation.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:id="@+id/i"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/myImageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
/>
</LinearLayout>


Modify update_i() to change i, and load ViewImage with arrow_01, arrow_02, arrow_03 and arrow_04 one by one.
package com.exercise.AndroidRunnable;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import android.widget.TextView;

public class AndroidRunnable extends Activity{

int i = 0;
TextView myi;
ImageView MyImageView;

Handler handler = new Handler(){

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
update_i();
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myi =(TextView)findViewById(R.id.i);
MyImageView = (ImageView)findViewById(R.id.myImageView);
}

@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();

Thread myThread=new Thread(new Runnable() {
public void run() {
while(true){
try {
handler.sendMessage(handler.obtainMessage());
Thread.sleep(1000);
}
catch (Throwable t) {
}
}
}
});

myThread.start();
}

private void update_i()
{
switch(i){
case 0:
i++;
MyImageView.setImageResource(R.drawable.arrow_01);
break;
case 1:
i++;
MyImageView.setImageResource(R.drawable.arrow_02);
break;
case 2:
i++;
MyImageView.setImageResource(R.drawable.arrow_03);
break;
case 3:
i = 0;
MyImageView.setImageResource(R.drawable.arrow_04);
break;
}
myi.setText(String.valueOf(i));
}
}
AndroidRunnable.java can be downloaded here.

For sure, it's not a good practice to implement animation. It is used to show the implementation of Runnable Thread, and Handle.

Here is another article about Animation background, using animation-list and AnimationDrawable.

Sunday, 11 October 2009

A Timely Warning - ipt3g

It seems the exploit that we were hoping would work (untethered) for ipt3g does not work as apple had implemented an unexpected fix.

That said, it is imperative that if you (or anyone you know) have an ipod touch 3g please please please get the shsh file from apple before they stop signing 3.1.1. Now that the jb is out, I think we can count the time apple will sign that fw version with days rather than weeks.

Repositories and applications that allow a user to obtain their SHSH files for future use cannot be more important to ipt3g users than right now. Cydia and my application are the two best ways to protect yourself against the firmware version restore lockout.

Pass it along, tell a friend, tweet. Do whatever you can for your ipt3g friends to help them.

AndroidRunnable, with Runnable Thread.

It's a very simple exercise to implament a activity with a Runnable Thread.



Modify main.xml to add a TextView, as a counter used to monitor the Runnable Thread. It count-up in every 1000ms.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:id="@+id/i"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Modify AndroidRunnable.java
package com.exercise.AndroidRunnable;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class AndroidRunnable extends Activity{

int i = 0;
TextView myi;

Handler handler = new Handler(){

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
update_i();
}
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myi =(TextView)findViewById(R.id.i);
}

@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();

Thread myThread=new Thread(new Runnable() {
public void run() {
while(true){
try {
handler.sendMessage(handler.obtainMessage());
Thread.sleep(1000);
}
catch (Throwable t) {
}
}
}
});

myThread.start();
}

private void update_i()
{
i++;
myi.setText(String.valueOf(i));
}
}

AndroidRunnable.java can be downloaded here.

Note that update_i() cannot be called inside myThread directly, because only the Thread create the View can touch it. Otherwise, Exception will be generated. That's why I have to implement a Handler to call update_i() indirectly.

Display a drawable graph, using ImageView.

If you want to display some simple graphics, you can just draw it to the background of a View, or use ImageView in layout.

Download the graphic android.png and save it in the /res/drawable folder.

- To set background of a View

Add a View in main.xml, and set thr background to "@drawable/android"

<View
android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@drawable/android"
/>


- Using ImageView

Add a ImageView in main.xml

<ImageView
android:id="@+id/myImageView"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

/>

Add the code in onCreate(), after setContentView(R.layout.main)

ImageView MyImageView = (ImageView)findViewById(R.id.myImageView); MyImageView.setImageResource(R.drawable.android);

Both have the same result.