顯示具有 command 標籤的文章。 顯示所有文章
顯示具有 command 標籤的文章。 顯示所有文章

2011年12月28日 星期三

Android - adb shell am broadcast指令

adb shell am broadcast 後面的參數有

[-a <ACTION>]
[-d <DATA_URI>]
[-t <MIME_TYPE>]
[-c <CATEGORY> [-c <CATEGORY>] ...]
[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
[--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
[-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
[-n <COMPONENT>]
[-f <FLAGS>] [<URI>] 

例如: adb shell am broadcast -a com.gill.test.broadcast --es TestString "this is test string" --ez TestBoolean true --ei TestInt 100

Android - adb logcat 實用的招式

詳細的用法請看原文:
http://developer.android.com/guide/developing/tools/adb.html

其中有一種用法對於了解較為大型的程式流程非常有用,原文中的例子是:
adb logcat ActivityManager:I MyApp:D *:S 
 
依個人經驗,在開發程式的時候,建議在每一個method()的第一行都下一個Log.d(),方便日後trace code。而且交接給別人維護時,別人只要執行一下程式順便把log印出來,馬上就能了解程式流程和架構。

舉例你有5個.java檔,分別是
A.java
B.java
C.java
D.java
E.java

裡面你可以為每支java都設立各自的tag,如:
TAG_A
TAG_B
TAG_C
TAG_D
TAG_E

在每一個程式的每一個method()都寫上Log.d("TAG_A",method name()); 其中TAG_A依不同程式TAG替換掉,而method_name()則依不同的method name替換掉。而adb logcat改下:

adb logcat TAG_A:D TAG_B:D TAG_C:D TAG_D:D TAG_E:D *:S >> log_file

或是

adb logcat | grep "TAG_"

如此一來,log_file裡面就不會有一大堆有的沒的其它不相關程式的log,而只會單純的顯示A~E.java這五支程式的log。又因為每支程式的method()第一行都有log.d(),所以就會變成光看log_file 就大致了解這個程式的流程了。

了解這種用法並加以變化應用,對學習較複雜的大型程式,非常有用!


另外,為了知道log發生的時間點,可以利用-v Time這個參數,比如:
adb logcat -v Time,則log會類似如下:
01-11 03:21:55.164 D/NotificationService(  237): mIntentReceiver() Intent.ACTION_BATTERY_CHANGED
01-11 03:21:55.164 D/NotificationService(  237): batteryCharging=true, level=100, status=5, health=2
01-11 03:21:55.164 D/PowerUI (  313): onReceive , action=android.intent.action.BATTERY_CHANGED

Ubuntu如何執行bin檔

In command line,
chmod a+x XXX.bin

then
./XXX.bin

Android - adb shell呈現系統目前資訊 (dumpsys)

不裝任何apk也想知道目前的電池狀況嗎?
直接下指令就可以了

adb shell dumpsys battery

就會秀出:

Current Battery Service state:
  AC powered: false
  USB powered: true
  status: 2
  health: 2
  present: true
  level: 26
  scale: 100
  voltage:3747
  temperature: 318
  technology: Li-ion


其它有關adb shell dumpsys 後面的參數還有很多用法,總共如下:
  SurfaceFlinger
  accessibility
  account
  activity
  alarm
  appwidget
  audio
  backup
  battery
  batteryinfo
  bluetooth
  bluetooth_a2dp
  bluetooth_dg_service
  bluetooth_fm_receiver_service
  clipboard
  connectivity
  content
  cpuinfo
  device_policy
  devicestoragemonitor
  diskstats
  dropbox
  entropy
  hardware
  htc_checkin
  htchardware
  input_method
  iphonesubinfo
  isms
  location
  media.audio_flinger
  media.audio_policy
  media.camera
  media.player
  meminfo
  mount
  netstat
  network_management
  notification
  package
  permission
  phone
  power
  search
  sensor
  simphonebook
  statusbar
  telephony.registry
  throttle
  uimode
  usagestats
  usbnet
  userbehavior
  vibrator
  wallpaper
  wifi
  window


如果什麼參數都不加,直接打adb shell dumpsys,就會出現全部的資訊了。

2011年12月26日 星期一

Android - BroadcastReceiver啟動Activity

在收到Broadcast後,直接啟動一個Activity,首先在AndroidManifest.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.testbroakcastreceiver" android:versionCode="1"
    android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <receiver android:name=".Main">
            <intent-filter>
                <action android:name="com.gill.test.broadcast" />
            </intent-filter>
        </receiver>
        <activity android:name=".Main2" >
        </activity>
    </application>
</manifest>

接下來需要2個java檔,Main.java繼承BroadcastReceiver,負責接收Broadcast,程式如下:
public class Main extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("Gill", "This is a test");
        Intent i = new Intent();
        i.setClass(context, Main2.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(i);
    }
}

Main2.java是一個單純的Activity,程式如下:
public class Main2 extends Activity {
     public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     }
}

測試方式,請先將手機和PC連接好後,在命令列模式下
adb shell am broadcast -a com.gill.test.broadcast
就可以看到手機執行Main2的畫面了。

Android tools (1) - aapt

先看官網說明
http://developer.android.com/intl/zh-TW/guide/developing/tools/aapt.html
aapt stands for Android Asset Packaging Tool and is included in the tools/ directory of the SDK. This tool allows you to view, create, and update Zip-compatible archives (zip, jar, apk). It can also compile resources into binary assets.


檔案位置 $ANDROID_HOME\platforms\$SDK\tools\
例如 D:\android-sdk-windows-1.5_r2\platforms\android-2.0\tools


搭配參數的實際用法

(1)list
aapt list HelloWorld.apk
可以看到HelloWorld.apk裡面所有的檔案,由此可知apk其實是個壓縮檔。如果用解壓縮軟體例如WinRAR或7-zip將apk解開,就會有下面這些檔案
res/layout/main.xml
AndroidManifest.xml
resources.arsc
res/drawable-hdpi/icon.png
res/drawable-ldpi/icon.png
res/drawable-mdpi/icon.png
classes.dex
META-INF/MANIFEST.MF
META-INF/CERT.SF
META-INF/CERT.RSA


(2)dump
aapt dump badging HelloWorld.apk
可以看到HelloWorld.apk裡package相關資料
package: name='com.gill.helloworld' versionCode='1' versionName='1.0'
application: label='HelloWorld' icon='res/drawable-mdpi/icon.png'
launchable activity name='com.gill.helloworld.Start'label='HelloWorld' icon=''
sdkVersion:'5'
main
supports-screens: 'small' 'normal' 'large'
locales: '--_--'
densities: '120' '160' '240'
我們來和AndroidManifest.xml比較一下內容,可發現相同之處
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.gill.helloworld"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Start"
                  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="5" />
    <uses-permission android:name="android.permission.VIBRATE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
</manifest>
請注意versionCode和versionName的差異。versionCode是整數,通常由1開始遞增到2、3、4…以此類推。versionName則是字串,例如一開始是1.1.1,下次為1.1.2。如有重大改版則為2.1.1…以此類推。


(3) dump permissions
aapt dump permissions HelloWorld.apk
可以看到HellowWorld.apk需要那些權限
package: com.gill.helloworld
uses-permission: android.permission.VIBRATE
uses-permission: android.permission.ACCESS_WIFI_STATE
uses-permission: android.permission.ACCESS_NETWORK_STATE
其它功能請參考網址 http://elinux.org/Android_aapt