Saturday, 10 October 2009

android-scripting: Android Scripting Environment

The Android Scripting Environment (ASE) brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device.

To install and use ASE, it's no need Eclipse as in normal development. What you need is a Android Emulator, and a AVD with SD Card installed. Personally, I prefer to generate a fresh new AVD for ASE. Refer to the article Create Android Virtual Device (AVD) in command line to create a new AVD with 1000M SD Card.

After the AVD generated, you can start Android Emulator using the new AVD:

Start Terminal, switch to the tools folder of the installed Android SDK, it's ~/android-sdk-linux_x86-1.6_r1/tools in my own setup. Type the command:
$./emulator -avd my_android1.6_for_scripting

where my_android1.6_for_scripting is the name of my AVD.

Start Browser and go to android-scripting page:
http://code.google.com/p/android-scripting/
Click the Featured downloads link, ase_r13.apk.

Or go to the link directly:
http://android-scripting.googlecode.com/files/ase_r13.apk

Click on the downloaded file, and accept Install.



After a while, the ASE will be installed. It can be found in the application list.


Click to start ASE, press MENU key start the option menu, you can Add Script, Add Interpreter, start Terminal and call Help in Browser.


In Terminal, you can type any command as in desktop Linux (Shell).


To try the examples, select Add Interpreter>Lua 5.1.4


After the files downloaded and extracted, select hello.user.lua to see the result:



You may ask, why write scripts instead of real Android applications? Admittedly, Android's development environment makes life pretty easy, but you're tied to a computer to do your work. ASE lets you develop on the device itself using high-level scripting languages to try out your idea now, in the situation where you need it, quickly. Have a look at the example Lua and Python scripts to see for yourself.

Friday, 9 October 2009

Coming soon...

UPDATE: I've started working on the module that will intercept https requests from itunes to their activation server (albert). I'm adding a much-needed GUI to TinyTSS along with an option for soft/local activation. Soft Activation will (as of now) probably require some SIM information from your friend-with-an-official-carrier's SIM. Until/Unless I find a way to activate using an unofficial imei/imsi, this may be required.

UPDATE: I've been able to capture an activation request/response session. I'm looking at what would be required to turn this to an offline feature. After looking at it, this solution may soft activate unlocked phones as well. This means it would no longer be necessary to switch sim cards with a friend on an official carrier to activate your unofficial sim. I'll keep you all posted with more developments.

To make TinyTSS a bit more useful, I've decided to take a crack at implementing offline activation. Currently, TinyTSS will spoof the real TSS service but it still requires a net connection because of the activation request that is sent to albert.apple.com. I'm currently working on adding that functionality to TinyTSS and maybe (if possible) adding the activation response grabber to Umbrella. My hopes are that this will allow complete and total offline firmware restoration.

As this is quite a bit more difficult to implement, it will take me some time to implement. My motivation is luke-warm for the feature but I'm curious how many of you would be interested in this functionality. Vote with your comments (heh or your donations :) )


On Donations-

I've always sworn that Umbrella and TinyTSS will never have a donate button marring their UI. I don't believe in shamelessly begging folks for cash. So, because I have received quite a few emails asking how I can be reached for donations, I've decided to put a donate button on the sidebar. It's small and fairly tasteful.

Note that I appreciate anything you feel like donating. But remember that donations are completely voluntary. (Although big donations are a great way to get someone's ear). I never expect anything but I greatly appreciate what you do give.

Create Android Virtual Device (AVD) in command line

In the article How to create Android Virtual Device (AVD) in Eclipse and Create an SD Card to existing AVD, I described how to create AVD in Eclipse and how to add SD Card to existing AVD. In this article, I describe how to create AVD, with SD Card, in command line (Terminal of Ubuntu Linux).

Environment:
OS: Ubuntu Linux 9.04
Android SDK 1.6 r1

- Before create AVD, you have to check the available system image targets in your system.

Start Terminal, switch to the tools folder of the installed Android SDK, it's ~/android-sdk-linux_x86-1.6_r1/tools in my own setup. Type the command:
$./android list targets



- Now you can create a new AVD, eg. a new AVD base on Android 1.6 (ID = 2), with 1000M SD Card.

Type the command:
$./android create avd -n my_android1.6_for_scripting -t 2 -c 1000M

You will be asked: Do you wish to create a custom hardware profile
Press Enter to answer NO.

After a while, the new AVD will be created.

- Start Emulator with the new AVD
$./emulator -avd my_android1.6_for_scripting

Multi-Language Translate

Extends from previous exercise, AndroidTranslate, using Google Translate API in Android application. It's a multi-language translation application. There are two spinner in the application, user can select the language to be translated.



------------------------------------------
Please note:
- google-api-translate-java have to be downloaded and build path have to be set, refer the article google-api-translate-java.
- "android.permission.INTERNET" have to be set in AndroidMainfest.xml, refer to the article AndroidTranslate, using Google Translate API in Android application.
------------------------------------------

Modify main.xml to add two Spinner to select the language to be translated from and to.
<?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"
/>
<EditText
android:id="@+id/InputText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="from:"
/>
<Spinner
android:id = "@+id/spinner_InputLanguage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="to:"
/>
<Spinner
android:id = "@+id/spinner_OutputLanguage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/TranslateButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Translate"
/>
<TextView
android:id="@+id/OutputText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>

main.xml can be downloaded here.

Implement a file arrayLanguage.xml in the folder /res/values/

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="language">
<item>ARABIC</item>
<item>BULGARIAN</item>
<item>CATALAN</item>
<item>CHINESE</item>
<item>CHINESE_SIMPLIFIED</item>
<item>CHINESE_TRADITIONAL</item>
<item>CROATIAN</item>
<item>CZECH</item>
<item>DANISH</item>
<item>DUTCH</item>
<item>ENGLISH</item>
<item>FILIPINO</item>
<item>FINNISH</item>
<item>FRENCH</item>
<item>GERMAN</item>
<item>GREEK</item>
<item>HEBREW</item>
<item>HINDI</item>
<item>INDONESIAN</item>
<item>ITALIAN</item>
<item>JAPANESE</item>
<item>KOREAN</item>
<item>LATVIAN</item>
<item>LITHUANIAN</item>
<item>NORWEGIAN</item>
<item>POLISH</item>
<item>PORTUGESE</item>
<item>ROMANIAN</item>
<item>RUSSIAN</item>
<item>SERBIAN</item>
<item>SLOVAK</item>
<item>SLOVENIAN</item>
<item>SPANISH</item>
<item>SWEDISH</item>
<item>UKRANIAN</item>
<item>VIETNAMESE</item>
</string-array>
</resources>

arrayLanguage.xml can be downloaded here.

Modify AndroidTranslate.java
package com.exercise.AndroidTranslate;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import com.google.api.translate.Language;
import com.google.api.translate.Translate;



public class AndroidTranslate extends Activity {

EditText MyInputText;
Button MyTranslateButton;
TextView MyOutputText;
Spinner spinner_InputLanguage, spinner_OutputLanguage;

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

MyInputText = (EditText)findViewById(R.id.InputText);
MyTranslateButton = (Button)findViewById(R.id.TranslateButton);
MyOutputText = (TextView)findViewById(R.id.OutputText);

MyTranslateButton.setOnClickListener(MyTranslateButtonOnClickListener);

ArrayAdapter<CharSequence> adapter
= ArrayAdapter.createFromResource(this,
R.array.language, android.R.layout.simple_spinner_item);

spinner_InputLanguage = (Spinner) findViewById(R.id.spinner_InputLanguage);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_InputLanguage.setAdapter(adapter);

spinner_OutputLanguage = (Spinner) findViewById(R.id.spinner_OutputLanguage);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_OutputLanguage.setAdapter(adapter);
}

private Button.OnClickListener MyTranslateButtonOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String InputString;
String OutputString = null;
InputString = MyInputText.getText().toString();

Language fromLanguage =
Language.valueOf((String)spinner_InputLanguage
.getItemAtPosition((int) spinner_InputLanguage
.getSelectedItemId()));
Language toLanguage =
Language.valueOf((String)spinner_OutputLanguage
.getItemAtPosition((int) spinner_OutputLanguage
.getSelectedItemId()));

try {
Translate.setHttpReferrer("http://android-er.blogspot.com/");
OutputString = Translate.execute(InputString,
fromLanguage, toLanguage);

} catch (Exception ex) {
ex.printStackTrace();
OutputString = "Error";
}

MyOutputText.setText(OutputString);
}
};
}

AndroidTranslate.java can be downloaded here.

In this exercise, two spinner are used to select the language to be translated from and to. A array-string are used to store the languages.

It can be retrieved using:
(String)spinner_InputLanguage.getItemAtPosition((int) spinner_InputLanguage.getSelectedItemId())
(String)spinner_OutputLanguage.getItemAtPosition((int) spinner_OutputLanguage.getSelectedItemId())

It's same as the parameters to be passed to Translate.execute(), but in String type, not the expected Language type. So we have to use the Language.valueOf() to convert it to Language type.

Thursday, 8 October 2009

Support for 3.1.2 + SHSH parsing

Umbrella and TinyTSS have been updated to provide support for 3.1.2. I've also made a couple cosmetic modifications (an about menu option).



TinyTSS now also reconstitutes the shsh response from the binary restore files thanks to information I got from theheadfl. TinyTSS will detect the version of the restore files based on the .dmg files and recreate a file that can be used with TinyTSS to perform restores; just like the file Umbrella produces. TinyTSS also pulls the ECID out from the shshs for the naming of the file.



And, because someone complained I've added a build number to the archive file. I know it's not full versioning but tbh I don't get paid for this so I really don't care enough to do more.



207: Changed the AWFUL logging format for TinyTSS.

213: Fixed an egregious error with 3.0.1 - Wrong plist in the distro - somehow I was using the iPhone 1g 3.0.1 ipsw buildmanifest - Thanks CleanAir75

215: Added full partial digest checking for detection of shsh version.

216: Added ipt3g/2g 3.1.2 shsh support! Removed unnecessary class(es)

217: Fixed a stupid bug concerning SAX parsers and xml entity resolvers... ugh.


218: Added 3.1.3 support - Not that I can think of any real reason to restore to 3.1.3



Enjoy




Download



fw-umbrella-semaphore-218.zip md5: a0e5082be5aa480539a3444dcd0bf920

fw-umbrella-semaphore-218.zip sha1: b48159004a82714b316029ade808ac5810d92b6c




umbrella.exe md5:  6a964cb8f507748244358115c6639387

umbrella.exe sha1:  9dcda837bcd2881b3d44c0a36bccad809a7a3766

tinytss.exe md5:  16ed36f69d7b918524f70695cbe592ca

tinytss.exe sha1:  600b6d0c3a7c9d2fa45d5b61f2c7f92d3159deb0

umbrella64.exe md5: 1b722a485d03e19fca9d299ba2f790d8

umbrella64.exe sha1: a2d7daa57f7790121d8071371d2e7156cca9db11

tinytss64.exe md5: a6eca19690a53f3963d7aed3e1c68d4d

tinytss64.exe sha1: a43448a271093b9ee454744a38d75949cd729747

Umbrella.dmg md5: 04d7654cee890a61e5cf471a0c183995

Umbrella.dmg sha1: 6616c86ee997cfc5837b6705d6ae6c3eaa41757c



AndroidTranslate, using Google Translate API in Android application.

It's a simple Android Application using google-api-translate-java to involve Google Translate, to translate the text input in the TextView in English to French.



In order to use google-api-translate-java in our application, we have to do some preparation as described in the article google-api-translate-java.

In our project, we have to grand permission to access internet, add the code <uses-permission android:name="android.permission.INTERNET" /> in AndroidMainfest.xml.

AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidTranslate"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidTranslate"
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>


Modify main.xml to include a EditText to input text to be translate, a Button to start translation, and a TextView to display the result.

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"
/>
<EditText
android:id="@+id/InputText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/TranslateButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Translate"
/>
<TextView
android:id="@+id/OutputText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>

main.xml can be downloaded here.

Finally, modify AndroidTranslate.java to implement the function.

AndroidTranslate.java
package com.exercise.AndroidTranslate;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.google.api.translate.Language;
import com.google.api.translate.Translate;



public class AndroidTranslate extends Activity {

EditText MyInputText;
Button MyTranslateButton;
TextView MyOutputText;

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

MyInputText = (EditText)findViewById(R.id.InputText);
MyTranslateButton = (Button)findViewById(R.id.TranslateButton);
MyOutputText = (TextView)findViewById(R.id.OutputText);

MyTranslateButton.setOnClickListener(MyTranslateButtonOnClickListener);
}

private Button.OnClickListener MyTranslateButtonOnClickListener
= new Button.OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String InputString;
String OutputString = null;
InputString = MyInputText.getText().toString();

try {
Translate.setHttpReferrer("http://android-er.blogspot.com/");
OutputString = Translate.execute(InputString,
Language.ENGLISH, Language.FRENCH);
} catch (Exception ex) {
ex.printStackTrace();
OutputString = "Error";
}

MyOutputText.setText(OutputString);

}

};

}

AndroidTranslate.java can be downloaded here.

google-api-translate-java

updated 2011-12-8:
google-api-translate-java now supports Version 2 of the API,this requires using an API key. refer http://code.google.com/p/google-api-translate-java/.

Google Translate API v2 is now available as a paid service only, and the number of requests your application can make per day is limited. Refer http://code.google.com/apis/language/translate/v2/getting_started.html.


-----

google-api-translate-java is a Google Code project enables using Google Translate from a Java application, to provides a simple, unofficial, Java client API for using Google Translate.

In order to include google-api-translate-java application, you have to download the jar, save to any location in your local had disk. In my case, it's /google-api-translate-java-0.82.jar in my home folder.

In Eclipse, Right click your project>Properties>>Java Build Path, and click Add External JARs, browse to include the downloaded jar file in your path.



I have a simple Android exercise, AndroidTranslate, using google-api-translate-java to involve Google Translate.