Difference between revisions of "Android SDK"
Line 526: | Line 526: | ||
Normally this works as such. In case of error no "BC" provider found, you can uncomment the line (which is what I had to do with Android 4.0.3) |
Normally this works as such. In case of error no "BC" provider found, you can uncomment the line (which is what I had to do with Android 4.0.3) |
||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()) |
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()) |
||
+ | ==Tips== |
||
+ | adb shell getprop |
||
+ | adb shell setprop ... |
||
+ | Check current clock speed |
||
+ | adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq |
||
+ | Disable CPU scaling |
||
+ | adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor |
||
+ | Change CPU frequency to 384000KHz |
||
+ | adb shell "echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor |
||
+ | adb shell "echo 384000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed |
||
+ | Load activity through ActivityManager |
||
+ | adb shell am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity -d "http://$1" & |
Revision as of 22:08, 6 September 2013
Back to Android
Getting Android SDK
Online using Linux/Windows
Instructions below are for linux, if you're running Windows please check the provided resource links for variants of the instructions.
Make sure you've Java Development Kit installed
apt-get install sun-java6-jdk
For Windows get it here e.g. jdk-6u29-windows-x64.exe Warning at the moment JDK7 created some errors in the compilation process, better to use JDK6.
As explained above, get Android SDK from here, following those instructions
Run tools/android (or for Windows run SDK Manager) -> in installed packages make sure to have:
- "Android SDK Tools", latest revision
- "Android SDK Platform-tools", latest revision
- a platform SDK, e.g. "Android 2.3.3"/"SDK Platform"
- (Windows only) Extras / Google USB Driver (SDK Manager must be run as Admin on Win7) then follow instructions here
As we will develop from the command-line, no need for the Eclipse plugin
If you want to update SDK
- tools/android update sdk
- Then restart tools/android
Offline installation under Windows
If you are behind a proxy, you can configure SDK Manager (Tools/Options).
If you've no Internet connection at all, you need to download components on another computer.
To know where are the packages let's spy SDK Manager & its logs (small icon at bottom right)
Here is what I got with the versions of the moment:
- https://dl-ssl.google.com/android/repository/repository.xml
- https://dl-ssl.google.com/android/repository/platform-tools_r08-windows.zip
- Extract content to C:\Program Files (x86)\Android\android-sdk\platform-tools
- https://dl-ssl.google.com/android/repository/tools_r14-windows.zip
- Normally you already got it via SDK install, but standalone file may be helpful where you don't need full SDK...
- https://dl-ssl.google.com/android/repository/platform-tools_r08-windows.zip
- https://dl-ssl.google.com/android/repository/repository-5.xml
- https://dl-ssl.google.com/android/repository/android-2.3.3_r02-linux.zip (yes I know, it says linux but it's cross-platform)
- Extract content of android-2.3.3_r02 to C:\Program Files (x86)\Android\android-sdk\platforms\android-10
- https://dl-ssl.google.com/android/repository/android-2.3.3_r02-linux.zip (yes I know, it says linux but it's cross-platform)
- https://dl-ssl.google.com/android/repository/addon.xml
- https://dl-ssl.google.com/android/repository/usb_driver_r04-windows.zip
- Extract content of usb_driver_r04-windows to C:\Program Files (x86)\Android\android-sdk\extras\google\usb_driver
- https://dl-ssl.google.com/android/repository/usb_driver_r04-windows.zip
Setting environment
We first define a number of things:
JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.26/
ANDROID_HOME=/path/to/your/android-sdk-linux_x86/
PACKAGE=com.foo.mytest1
PACKAGE_SLASH=${PACKAGE//.//}
DEV_HOME=$(pwd)/mytest
We need also to define the target. To know what are the available targets:
$ANDROID_HOME/tools/android list target Available Android targets: ---------- id: 1 or "android-10" Name: Android 2.3.3 Type: Platform API level: 10 Revision: 2 Skins: QVGA, WVGA854, HVGA, WQVGA432, WVGA800 (default), WQVGA400 ABIs : armeabi
So here we'll define:
TARGET=android-10
Under Windows it'll look like
set JAVA_HOME="C:\Program Files\Java\jdk1.6.0_29"
set ANDROID_HOME="C:\Program Files (x86)\Android\android-sdk\"
set PACKAGE=com.foo.mytest1
set PACKAGE_SLASH=com/foo/mytest1
set PACKAGE_BACKSLASH=com\foo\mytest1
set DEV_HOME=C:\path\to\mytest
set TARGET=android-10
Note that I needed here to use absolute path for DEV_HOME otherwise I get errors with dx.exe
Preparing and using emulator
Here is how to create a basic emulator instance:
$ANDROID_HOME/tools/android --verbose create avd --name MyNexusS --target $TARGET --sdcard 1024M
Later, to launch it just do:
$ANDROID_HOME/tools/emulator -wipe-data -avd MyNexusS &
If needed to delete it:
$ANDROID_HOME/tools/android --verbose delete avd --name MyNexusS
Under Windows it'll look like:
%ANDROID_HOME%\tools\android --verbose create avd --name MyNexusS --target %TARGET% --sdcard 1024M
%ANDROID_HOME%\tools\emulator -wipe-data -avd MyNexusS
%ANDROID_HOME%\tools\android --verbose delete avd --name MyNexusS
Android application in command-line
See http://geosoft.no/development/android.html
Preparing the working directory (based on the environment variables defined above):
rm -rf $DEV_HOME
mkdir -p $DEV_HOME/src/$PACKAGE_SLASH/
mkdir -p $DEV_HOME/res/drawable/
mkdir -p $DEV_HOME/res/layout/
mkdir -p $DEV_HOME/res/values/
mkdir -p $DEV_HOME/obj/
mkdir -p $DEV_HOME/lib/
mkdir -p $DEV_HOME/bin/
mkdir -p $DEV_HOME/docs/
Create a dummy keystore:
$JAVA_HOME/bin/keytool -genkeypair \
-validity 10000 \
-dname "CN=company name,
OU=organisational unit,
O=organisation,
L=location,
S=state,
C=country code" \
-keystore $DEV_HOME/AndroidTest.keystore \
-storepass password \
-keypass password \
-alias AndroidTestKey \
-keyalg RSA \
-v
Create a Manifest file, here with some examples of permissions:
cat << EOF > $DEV_HOME/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="$PACKAGE"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-sdk android:minSdkVersion="2"/>
<application android:icon="@drawable/mylogo"
android:label="@string/myApplicationName">
<activity android:name="$PACKAGE.HelloAndroid"
android:label="@string/myApplicationName">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
EOF
Provide source code of an app, here a simple HelloWorld, using an icon file some_icon.png:
cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloAndroid.java
package $PACKAGE;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
String text = getResources().getString(R.string.helloText);
textView.setText(text);
setContentView(textView);
}
}
EOF
cat << EOF > $DEV_HOME/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="myApplicationName">Android Test Program</string>
<string name="helloText">Hello, world!</string>
</resources>
EOF
cp some_icon.png $DEV_HOME/res/drawable/mylogo.png
Create R.java:
$ANDROID_HOME/platform-tools/aapt package -v -f -m \
-S $DEV_HOME/res -J $DEV_HOME/src -M $DEV_HOME/AndroidManifest.xml \
-I $ANDROID_HOME/platforms/$TARGET/android.jar || exit 1
Compile Java:
$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
-classpath "$ANDROID_HOME/platforms/$TARGET/android.jar:$DEV_HOME/obj" \
-sourcepath $DEV_HOME/src \
$DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1
Create DEX:
$ANDROID_HOME/platform-tools/dx --dex --verbose \
--output=$DEV_HOME/bin/classes.dex \
$DEV_HOME/obj $DEV_HOME/lib || exit 1
Create APK:
$ANDROID_HOME/platform-tools/aapt package -v -f \
-S $DEV_HOME/res -M $DEV_HOME/AndroidManifest.xml \
-I $ANDROID_HOME/platforms/$TARGET/android.jar \
-F $DEV_HOME/bin/AndroidTest.unsigned.apk \
$DEV_HOME/bin || exit 1
Sign APK:
$JAVA_HOME/bin/jarsigner -verbose \
-keystore $DEV_HOME/AndroidTest.keystore \
-storepass password \
-keypass password \
-signedjar $DEV_HOME/bin/AndroidTest.signed.apk \
$DEV_HOME/bin/AndroidTest.unsigned.apk \
AndroidTestKey || exit 1
Zip-align APK:
$ANDROID_HOME/tools/zipalign -v -f 4 \
$DEV_HOME/bin/AndroidTest.signed.apk \
$DEV_HOME/bin/AndroidTest.apk || exit 1
Generate documentation, if you wish:
$JAVA_HOME/bin/javadoc -verbose -d $DEV_HOME/docs -sourcepath $DEV_HOME/src \
-classpath "$ANDROID_HOME/platforms/$TARGET/android.jar:$DEV_HOME/obj" \
-author -package -use -splitIndex -version \
-windowtitle 'AndroidTest' -doctitle 'AndroidTest' \
$DEV_HOME/src/$PACKAGE_SLASH/*.java
To install the resulting application in the emulator (see above how to launch the emulator):
$ANDROID_HOME/platform-tools/adb -e install $DEV_HOME/bin/AndroidTest.apk
It's even possible to launch & control application from the PC.
See http://learnandroid.blogspot.com/2008/01/run-android-application-from-command.html
$ANDROID_HOME/platform-tools/adb -e shell am start -a android.intent.action.MAIN \
-n $PACKAGE/$PACKAGE.HelloAndroid
To remove it:
$ANDROID_HOME/platform-tools/adb -e uninstall $PACKAGE
To do the same on a real device rather than on the emulator, make sure the phone is connected by USB and running in debug mode as explained above, then simple use -d (device) instead of -e (emulator), so previous instructions become:
$ANDROID_HOME/platform-tools/adb -d install $DEV_HOME/bin/AndroidTest.apk
$ANDROID_HOME/platform-tools/adb -d shell am start -a android.intent.action.MAIN \
-n $PACKAGE/$PACKAGE.HelloAndroid
$ANDROID_HOME/platform-tools/adb -d uninstall $PACKAGE
Simple java code in command-line
See https://davanum.wordpress.com/2007/12/04/command-line-java-on-dalvikvm/
Not sure in which case you need it or not but it might be that you need:
- a rooted phone
- be root in shell as default (ro.secure=0 in the boot.img)
Preparing the working directory (based on the environment variables defined above):
rm -rf $DEV_HOME
mkdir -p $DEV_HOME/src/$PACKAGE_SLASH/
mkdir -p $DEV_HOME/obj/
mkdir -p $DEV_HOME/lib/
mkdir -p $DEV_HOME/bin/
Under Windows:
rmdir /S /Q %DEV_HOME%
mkdir %DEV_HOME%\src\%PACKAGE_BACKSLASH%\
mkdir %DEV_HOME%\obj\
mkdir %DEV_HOME%\lib\
mkdir %DEV_HOME%\bin\
Provide source code of an app, here a simple HelloWorld:
cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloWorld.java
package $PACKAGE;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
EOF
Under Windows:
No idea how to script it, just copy the java code to a file %DEV_HOME%\src\%PACKAGE_BACKSLASH%\HelloWorld.java
Compile Java:
$JAVA_HOME/bin/javac -verbose -d $DEV_HOME/obj \
-g $DEV_HOME/src/$PACKAGE_SLASH/*.java || exit 1
Under Windows:
%JAVA_HOME%\bin\javac -verbose -d %DEV_HOME%\obj ^
-g %DEV_HOME%\src\%PACKAGE_BACKSLASH%\*.java
Create DEX:
$ANDROID_HOME/platform-tools/dx --dex --verbose \
--output=$DEV_HOME/bin/classes.dex \
$DEV_HOME/obj $DEV_HOME/lib || exit 1
Under Windows:
%ANDROID_HOME%\platform-tools\dx --dex --verbose ^
--output=%DEV_HOME%\bin\classes.dex ^
%DEV_HOME%\obj %DEV_HOME%\lib
Create JAR:
pushd $DEV_HOME/bin/
$ANDROID_HOME/platform-tools/aapt add $DEV_HOME/CmdLine.jar \
classes.dex || exit 1
popd
Under Windows:
pushd %DEV_HOME%\bin\
%ANDROID_HOME%\platform-tools\aapt add %DEV_HOME%\CmdLine.jar ^
classes.dex
popd
To install the resulting application in the emulator (see above how to launch the emulator):
$ANDROID_HOME/platform-tools/adb -e push $DEV_HOME/CmdLine.jar /sdcard/
Under Windows:
%ANDROID_HOME%\platform-tools\adb -e push %DEV_HOME%\CmdLine.jar /sdcard/
To execute it from the PC:
$ANDROID_HOME/platform-tools/adb -e shell \
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
Under Windows:
%ANDROID_HOME%\platform-tools\adb -e shell ^
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld
To do the same on a real device rather than on the emulator, make sure the phone is connected by USB and running in debug mode as explained above, then simple use -d (device) instead of -e (emulator), so previous instructions become:
$ANDROID_HOME/platform-tools/adb -d push $DEV_HOME/CmdLine.jar /sdcard/
$ANDROID_HOME/platform-tools/adb -d shell \
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
Under Windows:
%ANDROID_HOME%\platform-tools\adb -d push %DEV_HOME%\CmdLine.jar /sdcard/
%ANDROID_HOME%\platform-tools\adb -d shell ^
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld
BouncyCastle library
Depending on the creation of a real Android app or a simple java code and depending on the fact you want to use the internal crippled version or the full fledged version, different approaches are needed.
Internal library API is explained here
Some RSA examples are given here and a tuto (fr) here
To get a list of supported algorithms, see here. This illustrates e.g. the differences between the crippled internal version of the library and the complete one.
Using internal BouncyCastle library from an Android application
That's the normal way.
Here is an example, mixing the HelloAndroid shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm
cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloAndroid.java
package $PACKAGE;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
keyGen.initialize(512, new SecureRandom());
KeyPair keyPair = keyGen.generateKeyPair();
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
signature.initSign(keyPair.getPrivate(), new SecureRandom());
byte[] message = "abc".getBytes();
signature.update(message);
byte[] sigBytes = signature.sign();
signature.initVerify(keyPair.getPublic());
signature.update(message);
if (signature.verify(sigBytes))
textView.setText("true");
else
textView.setText("false");
setContentView(textView);
} catch (java.security.NoSuchAlgorithmException e) {
textView.setText("NoSuchAlgorithmException");
setContentView(textView);
return;
} catch (java.security.NoSuchProviderException e) {
textView.setText("NoSuchProviderException");
setContentView(textView);
return;
} catch (java.security.InvalidKeyException e) {
textView.setText("InvalidKeyException");
setContentView(textView);
return;
} catch (java.security.SignatureException e) {
textView.setText("SignatureException");
setContentView(textView);
return;
}
}
}
EOF
Using external BouncyCastle library from an Android application
Not tested. The problem is that it's impossible to get an external library with the exact same name as the internal one (see bugreport), so different approaches are possible:
- SpongyCastle, BouncyCastle rebranded to avoid the conflict.
- Using JarJar to rebrand it yourself
Using internal BouncyCastle library from a simple java code
Here is an example, mixing the HelloWorld shown above with an example from http://www.java2s.com/Tutorial/Java/0490__Security/RSASignatureGeneration.htm
cat << EOF > $DEV_HOME/src/$PACKAGE_SLASH/HelloWorld.java
package $PACKAGE;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
public class HelloWorld {
public static void main(String[] args) throws Exception {
//Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
keyGen.initialize(512, new SecureRandom());
KeyPair keyPair = keyGen.generateKeyPair();
Signature signature = Signature.getInstance("SHA1withRSA", "BC");
signature.initSign(keyPair.getPrivate(), new SecureRandom());
byte[] message = "abc".getBytes();
signature.update(message);
byte[] sigBytes = signature.sign();
signature.initVerify(keyPair.getPublic());
signature.update(message);
System.out.println(signature.verify(sigBytes));
}
}
EOF
There is a little trick when you will run the example on the phone or emulator: you've to provide explicitly the path to internal BouncyCastle:
$ANDROID_HOME/platform-tools/adb -d shell \
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
Under Windows:
%ANDROID_HOME%\platform-tools\adb -d shell ^
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar %PACKAGE%.HelloWorld
UPDATE: on Android 4.0.3 (ICS) it doesn't work anymore, I get an error
java.security.NoSuchProviderException: BC
and in the logcat:
I/dalvikvm( 1983): DexOpt: Some deps went away E/dalvikvm( 1983): /system/framework/bouncycastle.jar odex has stale dependencies I/dalvikvm( 1983): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory D/dalvikvm( 1983): Unable to process classpath element '/system/framework/bouncycastle.jar'
This is because there is an extra dependency for bouncycastle, here is how to get the deps in a very hacky way:
$ adb shell strings /system/framework/bouncycastle.odex|grep odex /system/framework/core.odex /system/framework/core-junit.odex
So the proper way to call our jar is now:
$ANDROID_HOME/platform-tools/adb -d shell \
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
Using external BouncyCastle library from a simple java code
You can use the same code as above but you need this time to provide the external library:
# From http://www.bouncycastle.org/latest_releases.html
cp -a bcprov-jdk16-146.jar $DEV_HOME/lib
To run the example, don't provide any path to the internal lib of course:
$ANDROID_HOME/platform-tools/adb -d shell \
/system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar -classpath /sdcard/CmdLine.jar $PACKAGE.HelloWorld
Normally this works as such. In case of error no "BC" provider found, you can uncomment the line (which is what I had to do with Android 4.0.3)
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())
Tips
adb shell getprop adb shell setprop ...
Check current clock speed
adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
Disable CPU scaling
adb shell "echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
Change CPU frequency to 384000KHz
adb shell "echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor adb shell "echo 384000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
Load activity through ActivityManager
adb shell am start -a android.intent.action.MAIN -n com.android.browser/.BrowserActivity -d "http://$1" &