技术小黑屋

Refer String Resources From Other Applications

The following code works. Here take getting String resource for example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void testUseAndroidString() {

    Context context = getContext();
    Resources res = null;
    try {
        //I want to use the clear_activities string in Package com.android.settings
        res = context.getPackageManager().getResourcesForApplication("com.android.settings");
        int resourceId = res.getIdentifier("com.android.settings:string/clear_activities", null, null);
        if(0 != resourceId) {
            CharSequence s = context.getPackageManager().getText("com.android.settings", resourceId, null);
            Log.i(VIEW_LOG_TAG, "resource=" + s);
        }
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }

}

Others

Get Android System Available Features

An easy way to get system available features.

1
2
3
4
5
6
7
private void dumpSystemFeatures() {

    FeatureInfo[] features = this.getPackageManager().getSystemAvailableFeatures();
        for (FeatureInfo f : features) {
            Log.i(LOGTAG, "dumpSystemFeatures f" + f);
        }
}

Have a glance at the result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d74fd0 android.hardware.wifi fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75048 android.hardware.location.network fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d750d8 android.hardware.nfc fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75150 com.google.android.feature.GOOGLE_BUILD fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d751f0 android.hardware.location fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75270 android.hardware.sensor.gyroscope fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75300 android.hardware.screen.landscape fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75390 android.hardware.screen.portrait fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75420 android.hardware.wifi.direct fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d754a8 android.hardware.usb.accessory fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75530 android.hardware.bluetooth fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d755b0 android.hardware.touchscreen.multitouch.distinct fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75660 android.hardware.microphone fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d756e8 android.hardware.sensor.light fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75770 android.hardware.camera.autofocus fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75800 android.software.live_wallpaper fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75890 android.hardware.camera.flash fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75918 android.hardware.telephony fl=0x0}
I/MainActivity(13514): dumpSystemFeatures fFeatureInfo{40d75998 android.software.sip fl=0x0}
......

The Other way

You can also use adb shell to get into the shell of your device and the use pm list features to get the available features of a device.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
root@android:/ # pm list features
feature:reqGlEsVersion=0x20000
feature:android.hardware.bluetooth
feature:android.hardware.camera
feature:android.hardware.camera.autofocus
feature:android.hardware.camera.flash
feature:android.hardware.camera.front
feature:android.hardware.faketouch
feature:android.hardware.location
feature:android.hardware.location.gps
feature:android.hardware.location.network
feature:android.hardware.microphone
feature:android.hardware.nfc
feature:android.hardware.screen.landscape
feature:android.hardware.screen.portrait
feature:android.hardware.sensor.accelerometer
feature:android.hardware.sensor.compass
feature:android.hardware.sensor.gyroscope
feature:android.hardware.sensor.light
feature:android.hardware.sensor.proximity
feature:android.hardware.telephony
feature:android.hardware.telephony.gsm
feature:android.hardware.touchscreen
feature:android.hardware.touchscreen.multitouch
feature:android.hardware.touchscreen.multitouch.distinct
feature:android.hardware.touchscreen.multitouch.jazzhand
feature:android.hardware.usb.accessory
feature:android.hardware.usb.host
feature:android.hardware.wifi
feature:android.hardware.wifi.direct
feature:android.software.live_wallpaper
feature:android.software.sip
feature:android.software.sip.voip
feature:com.cisco.anyconnect.permissions.patch.htc
feature:com.htc.android.rosie.widget
feature:com.htc.lockscreen.fusion
feature:com.nxp.mifare

For a detailed understanding of use-filter,please read this post http://developer.android.com/guide/topics/manifest/uses-feature-element.html

Others

Get an Application Required Features

How to get application’s required features? Actually the aapt really does a great help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#Usage:aapt dump badging apk_location | grep feature 

#Example
aapt dump badging /tmp/language_check_maxthon_99985f_2793_4.1.3.1000_remote_develop.apk | grep Features

#Result
uses-feature-not-required:'android.hardware.location'
uses-feature-not-required:'android.hardware.location.network'
uses-feature-not-required:'android.hardware.location.gps'
uses-feature-not-required:'android.hardware.screen.portrait'
uses-feature-not-required:'android.hardware.telephony'
uses-feature-not-required:'android.hardware.wifi'
uses-feature:'android.hardware.touchscreen'
uses-implied-feature:'android.hardware.touchscreen','assumed you require a touch screen unless explicitly made optional'

To understand the feature more detailed, please visit http://developer.android.com/guide/topics/manifest/uses-feature-element.html

Others

Jar Mismatch! Fix Your Dependencies

There was a requirement of my work. It requires me to integrated my current project with Facebook SDK for measuring. However this came into my sights.

1
Jar mismatch! Fix your dependencies

The fact is that Both my project and my library project which the former refers to have used android-support-v4.jar. However I realize the two android-support-v4.jar are different after making the md5 hash.
My solution:
I use the android-support-v4.jar in my project as the right one. And then replace the one in Facebook SDK with my project one. And then it works.
But my question remains; why it asks me for fix the dependencies to use the same lib jar file?
I guess android will keep only one file for all the references so this will ask developers to make all the same lib all the same. Sorry for the codeless post.

Others

How to Create Facebook Key Hash

When I create a new application on Facebook, I meet the problem. Facebook asks me to provide the Key Hash. But it does not show the guidance about how to generate. After Googling, I have found this works for me.
Before executing the following command, you need install openssl

1
keytool -exportcert -alias your-alias-value -keystore your-keystore-path | openssl  sha1 -binary | openssl  base64

Replace your-alias-value and your-keystore-path with the real data.

Others

Dump Table Structure in SQLite3

Best answer to the question
Use PRAGMA table_info

This pragma returns one row for each column in the named table. Columns in the result set include the column name, data type, whether or not the column can be NULL, and the default value for the column. The “pk” column in the result set is zero for columns that are not part of the primary key, and is the index of the column in the primary key for columns that are part of the primary key.

Reference:http://www.sqlite.org/pragma.html#pragma_table_info

1
2
3
4
5
6
7
8
sqlite> .header on
sqlite> PRAGMA table_info(password);
cid|name|type|notnull|dflt_value|pk
0|_id|INTEGER|0||1
1|host|TEXT|0||0
2|username|TEXT|0||0
3|password|TEXT|0||0
#password is the name of a table.

Another answer may also work
.schema [tablename] will show the CREATE statement(s) for a table or tables

1
2
sqlite> .schema password
CREATE TABLE password (_id INTEGER PRIMARY KEY, host TEXT, username TEXT, password TEXT, UNIQUE (host, username) ON CONFLICT REPLACE);

Others

Check if a Python Module Is Installed

I was once stucked in How to check Whether a Python module has been installed or not. After Googling, I found this trick.
Python allows user to pass command from out of a python file.See here

1
-c cmd : program passed in as string (terminates option list)

The result if we import an installed module

1
2
3
4
20:15:45-androidyue~/osc_git/LnxClient (master)$ python -c "import os"
20:31:24-androidyue~/osc_git/LnxClient (master)$ echo $?
0
#0 means the module has been installed

Now if we import an module which is not installed.

1
2
3
4
5
6
7
20:31:41-androidyue~/osc_git/LnxClient (master)$ python -c "import aaa"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named aaa
20:31:46-androidyue~/osc_git/LnxClient (master)$ echo $?
1
#1 means that module is not installed.

Others

Java Get Full Exception StackTrace

As a coder, I am always handling exceptions or errors,or in a word throwables. To impove the release build, I need to collect every throwable information.
And I need to get the information as string and post it to the Bug Collect Server. Now here is an easy trick to get stacktrace from a Throwable

1
2
3
4
5
6
7
private String getStackTrace(Throwable t) {

    final Writer result = new StringWriter();
    final PrintWriter printWriter = new PrintWriter(result);
    t.printStackTrace(printWriter);
    return result.toString();
}

Others

乘手扶梯的正确方法

起因

之前一直和女朋友有一个讨论,就是搭乘扶梯时究竟时靠左站立,还是靠右站立。起因时从地铁北宫门出来的时候,我要求她站在左侧。

我的观点

  • 右侧留出来行走,更符合国内靠右行驶的习惯
  • 之前看到过日本的介绍,日本是靠左侧的。

她的观点

  • 现在很多人都是靠右站立
  • 她见过写着靠右站立的提示

事实

  • 左行右立(香港普遍称为左行右企)是指在歐美、香港、台灣、西日本等地於乘坐電扶梯时电梯左边空出留给有急事的乘客行走,只是站立在电梯上的人靠右侧站立的行为。與之相反的是,東日本、澳洲、新加坡等地卻採用右行左立的方式。
  • 此方式為一約定俗成之法則。香港地鐵(今港鐵)及台北捷運於從前曾參考歐美等地的習慣,宣傳「左行右立」,疏通繁忙時段的人流,但不奏效。在香港停止宣傳後,「左行右立」卻反而流行起來。
  • 但在電扶梯上步行會導致容易失去平衡,釀成意外,亦容易導致重力分布不均,增加電扶梯容易損壞的機率。[2]香港政府提醒市民盡量不要在電梯上走動[3],而台北捷運公司目前也基於上述之理由,不再宣傳此措施,然而大部分乘客均已養成左行右立的搭乘習慣;相較之下,台灣的另一座大眾運輸系統——高雄捷運即未若台北一般廣泛宣傳左行右立的習慣。
  • 2011年北京地铁动物园站出现电动扶梯事故后,京华时报指出左行右立是不安全的行为,可能是造成电动扶梯事故的诱因之一。
  • 左行右立是上海市迎接中国2010年上海世界博览会宣传倡导的城市文明行为之一。為宣傳“左行右立”标准,上海轨道交通扶手电梯处常见「左行右立」的標語,並指即使乘客站立不穩向後倒下,後面的乘客也可以支撐,不會出現骨牌效應,有利安全。[5]但自2012年12月开始,因为扶梯台阶过大,行走不安全,上海轨道交通不再强调左行右立,一些原先粘贴在扶梯上倡导左行右立的贴纸已被移除 以上事实部分参考维基百科 http://zh.wikipedia.org/wiki/%E5%B7%A6%E8%A1%8C%E5%8F%B3%E7%AB%8B 或者 Google 搜索 左行右立

总结

  • 就按我输了作为结果吧,哈哈。
  • 靠左靠右并无硬性规定,社会活动中多礼让,不妨碍他人

Others

Read Output From Shell

Python provides a lot of method to read output from a just executed shell. However many of them has been deprecated(Not recommened). But subprocess works at present compared to other methods.

1
2
3
4
5
6
7
8
9
10
11
12
from subprocess import Popen,PIPE,STDOUT

def readFromCommand(command) :
    p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
    result = p.stdout.read().strip()
    return result

print readFromCommand('ls')
#result
#0001-.patch
#0001-.patch.zip
#0001-Replace-app_name-into-Browser.patch

A detailed description about subprocess has been written down here. http://docs.python.org/2/library/subprocess.html

Others

How to Share Git Tag

Now I have two tags under my git repository. Let’s take a look at how to push the git tags to Server.

1
2
v2850
v4.1.1.2000_2852

Push a single tag to the server

1
2
3
#git push origin tag_name
#Take v2850 for example
git push  origin v2850

Push all tags to the server

1
git push  origin --tags

Others

Build Android Packages From Command Line

A few months ago,I dealed with a task:To build a large amount of apk files. The trick I came up with is to build apk file from the command so that I could use Python to glue all the works. Eventually I made it.And so this post is to make some description about the trick.

Requirements

  • Setup JDK
  • Setup Android SDK

    Steps

  • Generate R class file
  • Compile Java codes(.java files) into classes(.class) files
  • Convert .class files into .dex files
  • Package Resouces
  • Build Unsigned APK File
  • Sign Apk with Jarsigner
  • The Extra One:Use zipalign for optimization

Generate R class File

In Android,We use R class to refer resources instead of hard-coding the resouces.
For a better understanding,pleae have a look at http://www.satyakomatineni.com/akc/display?url=displaynoteimpurl&ownerUserId=satya&reportId=2883

1
aapt package -f -m -J /home/androidyue/temp/ubuntu/workspace/MxDataProvider/gen/ -S /home/androidyue/temp/ubuntu/workspace/MxDataProvider/res/ -I /home/androidyue/dev_tools/android-sdk-linux_86_backup/platforms/android-17/android.jar -M /home/androidyue/temp/ubuntu/workspace/MxDataProvider/AndroidManifest.xml

Some descriptions

  • -f force overwrite of existing files
  • -m make package directories under location specified by -J
  • -J specify where to output R.java resource constant definitions
  • -S directory in which to find resources. Multiple directories will be scanned and the first match found (left to right) will take precedence.
  • -I add an existing package to base include set
  • -M specify full path to AndroidManifest.xml to include in zip

Comiple .java into .class files

1
javac -encoding UTF-8 -source 1.6 -target 1.6 -bootclasspath /home/androidyue/dev_tools/android-sdk-linux_86_backup/platforms/android-17/android.jar -d /home/androidyue/temp/ubuntu/workspace/MxDataProvider/bin/ /home/androidyue/temp/ubuntu/workspace/MxDataProvider/src//coop/channel/provider/*.java /home/androidyue/temp/ubuntu/workspace/MxDataProvider/gen//coop/channel/provider/R.java

Some descriptions

  • -encoding encoding Set the source file encoding name, such as EUC-JP and UTF-8. If -encoding is not specified, the platform default converter is used.
  • -source release Specifies the version of source code accepted, Please Do NOT use Java 7(1.7)
  • -target version Generate class files that target a specified version of the VM. Class files will run on the specified target and on later versions, but not on earlier versions of the VM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6(also 6), and 1.7 (also 7).
  • -bootclasspath bootclasspath Cross-compile against the specified set of boot classes. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives.
  • -d directory Set the destination directory for class files. The directory must already exist; javac will not create it. As I have suffered a lot using Java 7, It’s recomended to use Java 6

Convert .class into .dex files

1
/home/androidyue/dev_tools/android-sdk-linux_86_backup/build-tools/17.0.0/dx --dex --output=/home/androidyue/temp/ubuntu/workspace/MxDataProvider/bin//class.dex /home/androidyue/temp/ubuntu/workspace/MxDataProvider/bin/

To dive into Dalvik, please visit http://source.android.com/devices/tech/dalvik/index.html

Package Resouces

1
aapt package -f -M /home/androidyue/temp/ubuntu/workspace/MxDataProvider/AndroidManifest.xml -S /home/androidyue/temp/ubuntu/workspace/MxDataProvider/res/ -A /home/androidyue/temp/ubuntu/workspace/MxDataProvider//assets/ -I /home/androidyue/dev_tools/android-sdk-linux_86_backup/platforms/android-17/android.jar -F /home/androidyue/temp/ubuntu/workspace/MxDataProvider/bin//resources.ap_

Some descriptions

  • -F specify the apk file to output
  • -A additional directory in which to find raw asset files

Build Unsigned APK File

1
/home/androidyue/temp/ubuntu/dev_tools/adt-bundle-linux_backup/sdk/tools/apkbuilder /tmp/unsignedApkFile.apk -v -u -z /home/androidyue/temp/ubuntu/workspace/MxDataProvider/bin//resources.ap_ -f /home/androidyue/temp/ubuntu/workspace/MxDataProvider/bin//class.dex -rf /home/androidyue/temp/ubuntu/workspace/MxDataProvider/src/

Some descriptions

  • -u Creates an unsigned package.
  • -z Followed by the path to a zip archive. Adds the content of the application package.
  • -f Followed by the path to a file. Adds the file to the application package.
  • -rf Followed by the path to a source folder. Adds the java resources found in that folder to the application package, while keeping their path relative to the source folder.

Sign Apk with Jarsigner

1
jarsigner -keystore /home/androidyue/temp/ubuntu/myKeystore -storepass storepassValue -keypass keypassValue -signedjar /home/androidyue/Desktop/output/max1111111.apk /tmp/unsignedApkFile.apk maxthon -digestalg SHA1 -sigalg MD5withRSA

Some descriptions

  • [-keystore ] keystore location
  • [-storepass ] password for keystore integrity
  • [-keypass ] password for private key (if different)
  • [-signedjar ] name of signed JAR file
  • [-digestalg ] name of digest algorithm
  • [-sigalg ] name of signature algorithm

Use Zipalign for optimization

1
zipalign -f -v 4 /home/androidyue/Desktop/output/max1111111.apk /home/androidyue/Desktop/output/max222222.apk

Some descriptions

Others

Start an Android App by ADB

To be more geek,I began to start an Android App by using adb.Thanks to Google.It’s possible and powerful.
The tool we use to make it is ADB(Android Debug Tool),For more detailed use please visit http://developer.android.com/tools/help/adb.html#shellcommands Actually What I use here is

1
start [options] <INTENT>

An example is followed.

1
2
3
4
#Here I want to start MxBrowser app by using ADB
17:04:30-androidyue/tmp$ adb shell am start -n com.mx.browser/com.mx.browser.MxBrowserActivity
Starting: Intent { cmp=com.mx.browser/.MxBrowserActivity  }
Warning: Activity not started, its current task has been brought to the front

the Package name(com.mx.browser) before the slash is provided to determine which app should the intent delivered to.The com.mx.browser.MxBrowserActivity is the destination Activity.
For more explanations about ADB INTENT,please visit http://developer.android.com/tools/help/adb.html#IntentSpec

Could Not Reliably Determine the Server’s Fully Qualified Domain Name

An easy trick to solve problem:Could not reliably determine the server’s fully qualified domain name
Let’s take Linux for example.

1
2
#Modify your configuration file.
12:52:21-androidyue/etc/httpd/conf$ sudo vim httpd.conf

Find out the following sentence

1
2
3
4
5
6
7
8
9
10
11
12
13
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If this is not set to valid DNS name for your host, server-generated
# redirections will not work.  See also the UseCanonicalName directive.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
# You will have to access it by its address anyway, and this will make 
# redirections work in a sensible way.
#
#ServerName localhost:80

If the ServerName localhost:80 has been commented,it may cause above problem.A simple trick is just uncomment the sentence.Let it be like this

1
ServerName localhost:80

Hope you could resolve your problem,Guys.

Get MD5 Hash of Big Files

Recently I have been dealing with files and I need to get md5 hash of all kinds of files;Some are small and some are big.
For the small files I use this method to get md5 hash value.

1
2
3
4
5
6
7
def getFileMd5(filename):
    file = open(filename, 'rb')
    m = md5()
    m.update(file.read())
    file.close()
    result =  m.hexdigest()
    return result

However for calculating md5 hash value of big files,the above method will be very Less Efficient.For Big files I use the following method(It’s acquired from stackoverflow)

1
2
3
4
5
6
7
8
9
10
def getBigFileMd5(filename, block_size=2**20):
    f = open(filename, 'rb')
    m = md5()
    while True:
        data = f.read(block_size)
        if not data:
            break
        m.update(data)
    f.close()
    return m.hexdigest()

And I did a test.The cost of Getting md5 hash of a Big file(size:10.7 GiB; 11,455,512,109 bytes) is 213.447s.And I think it’s OK.