2015年7月21日 星期二

Read an image file into bitmap and set it to the imageview

AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

如果沒有加 Permission,image file會無法被讀取,導致 ImageView無法正常顯示

Java
private static final String INTERNAL_STORAGE_PATH = "/storage/sdcard0";
private static final String FILE_NAME = "image.jpg";
private ImageView mImageView;
protected void onCreate(Bundle savedInstanceState) {
......
        mImageView = (ImageView)findViewById(R.id.origin_view);

        // From internal storage
        File imageFile = new File(INTERNAL_STORAGE_PATH + "/" + FILE_NAME);       
        Bitmap imageBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());

        // From external storage (SD card)
        File imageFile = new File(Environment.getExternalStorageDirectory() + "/" + FILE_NAME);
        Bitmap imageBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());

        // From app resource
        Bitmap imageBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);

        mImageView.setImageBitmap(imageBitmap);      
}
 

2015年7月20日 星期一

在 ActionBar顯示進度圖示

Reference:

http://androidbiancheng.blogspot.tw/2011/07/windowfeatureindeterminateprogress.html

步驟:


1. requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
2. 呼叫 setProgressBarIndeterminateVisibility(true/false) 方法來顯示/隱藏進度圖示

Send message by handler

Reference:

http://blog.csdn.net/ahuier/article/details/17012923
http://blog.csdn.net/ahuier/article/details/17013647

Handler sendMessage:

1. sendEmptyMessage(int what)
Example:
new Thread(new Runnable() { 
    @Override 
    public void run() { 
        mHandler.sendEmptyMessage(3); 
    } 
}).start();

protected static Handler mHandler = new Handler() {
     @Override 
     public void handleMessage(android.os.Message msg) { 
         System.out.println("--> what: " + msg.what); 
     } 
}; 

2. sendEmptyMessageAtTime(int what,long uptimeMillis)

3. sendEmptyMessageDelayed (int what, long delayMillis)

4. sendMessage (Message msg)
Example:
new Thread(new Runnable() { 
    @Override 
    public void run() { 
        Message msg = mHandler.obtainMessage();  
        msg.arg1 = 1; 
        msg.what = 3; 
        msg.obj = "AHuier"; 
        mHandler.sendMessage(msg); 
    } 
}).start(); 

Handler obtainMessage:

obtainMessage(int what, int arg1, int arg2, Object obj)
Ex:
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer).sendToTarget();

Message obtain:

1. obtain()
Ex:
Message message = Message.obtain(); 
message.what = 1; 
message.arg1 = 1; 
message.arg2 = 3; 
message.obj = "AHuier"; 
handler.sendMessage(message);

2. obtain(Handler h)
Ex:
Message message = Message.obtain(handler); 
message.what = 1; 
message.arg1 = 1; 
message.arg2 = 3; 
message.obj = "AHuier"; 
message.sendToTarget();

3. obtain(Handler h, int what)

4. obtain(Handler h, int what, int arg1, int arg2, Object obj)

5.使用 Bundle來傳遞複雜的資料型態
Ex:
Message message = Message.obtain(handler, 1, 1, 3, "AHuier"); 
Bundle data = new Bundle(); 
data.putStringArray("str", new String[]{"AHui", "AHui1", "AHui2"}); 
message.setData(data); 
message.sendToTarget();


Relative reference:

http://givemepass-blog.logdown.com/posts/296606-how-to-use-a-handler
http://j796160836.pixnet.net/blog/post/28766165




Bluetooth

Reference:

http://developer.android.com/guide/topics/connectivity/bluetooth.html

Get BluetoothAdapter:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
   
// Device does not support Bluetooth
}

Enable Bluetooth:


if (!mBluetoothAdapter.isEnabled()) {
   
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult
(enableBtIntent, REQUEST_ENABLE_BT);
}


Quering paired devices:

MAC address可以用來初始化BluetoothDevice物件

Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
   
// Loop through paired devices
   
for (BluetoothDevice device : pairedDevices) {
       
// Add the name and address to an array adapter to show in a ListView
        mArrayAdapter
.add(device.getName() + "\n" + device.getAddress());
   
}
}


Discovering devices:

只要呼叫 startDiscovery()就可以開始尋找device
應用程式需要註冊一個broadcase receiver來接收搜尋到的device的資訊

// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
   
public void onReceive(Context context, Intent intent) {
       
String action = intent.getAction();
       
// When discovery finds a device
       
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
           
// Get the BluetoothDevice object from the Intent
           
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
           
// Add the name and address to an array adapter to show in a ListView
            mArrayAdapter
.add(device.getName() + "\n" + device.getAddress());
       
}
   
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver
(mReceiver, filter); // Don't forget to unregister during onDestroy


注意:
執行搜尋device會消耗很多資源,所以當找到一個要連接的device,在連接前要先呼叫cancelDiscovery(),停止搜尋device。
另外,當已經在連接中的情況下進行搜尋device,會減少已連接的連線的頻寬,所以在已連接的情況下不要再搜尋device

Get BluetoothDevice:

BluetoothAdapter
public BluetoothDevice  getRemoteDevice (String address)

Valid Bluetooth hardware addresses must be upper case, in a format such as "00:11:22:33:AA:BB". The helper checkBluetoothAddress(String) is available to validate a Bluetooth address.

Parameters

address
valid Bluetooth MAC address

Throws

IllegalArgumentException
if address is invalid 
Ex:
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

BluetoothSocket
public BluetoothDevice  getRemoteDevice ()

Get the remote device this socket is connecting, or connected, to.

Returns
remote device

Ex:
socket.getRemoteDevice()

Enabling discoverability:

要讓你的Device成為Discoverable,要呼叫StartActivityForResult(Intent,int),Intent要使用ACTION_REQUEST_DISCOVERABLE

Discoverable時間:
Default: 120s
Maximum: 3600s
Set to 0: always
< 0 或 > 3600: 120s

Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent
.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity
(discoverableIntent);


無論Discoverable成功或失敗,onActivityResult callback function都會收到呼叫

如果Device的Bluetooth還沒開啟,當Device變成Discoverable時,會自動開啟Bluetooth

若要知道Discoverable mode是否發生改變,可以註冊一個Broadcase receiver監聽ACTION_SCAN_MODE_CHANGED的intent,intent裡面會包含EXTRA_SCAN_MODE 和EXTRA_PREVIOUS_SCAN_MODE
mode分為以下三種:
SCAN_MODE_CONNECTABLE_DISCOVERABLE: 在Discoverable mode
SCAN_MODE_CONNECTABLE: 不在Discoverable mode,但仍可以接收connection
SCAN_MODE_NONE: 不在Disoverable mode,並且也不能接收connection

Connecting Devices:

要在兩台Device之間建立連線,一台Device(Server side)要先打開server socket,另外一台Device(Client side)要初始化connection(使用server device的MAC address)。當兩台Device在同一個RFCOMM channel上都有了已連接的BluetoothSocket,就可以取得input和output stream,進行資料交換

Server和Client取得Bluetooth的方法如下:
Server: when an incoming connection is accepted
Client: when it opens an RFCOMM channel to the server

實作方法:
法一:每一台device都打開server socket,等待device接收connection,當有一台server初始化connection,就變成client
法二:某一台device打開server socket,負責管理connection,其他device只要負責初始化connection

注意:
RFCOMM connection attempt會block住直到配對成功、使用者拒絕配對、配對失敗或time out

Connecting as a server:

server socket的目的是監聽connection request,當接收到request後,就會提供一個BluetoothSocket,當從BlutoothServerSocket取得BluetoothSocket後,除非想要接收更多的connection,否則就應該把BlutoothServerSocket關閉

設定和接受connection的步驟如下:
1. 取得 BluetoothServerSocket:
    呼叫 listenUsingRfcommWithServiceRecord(String, UUID)

    BluetoothAdapter
    public BluetoothServerSocket  listenUsingRfcommWithServiceRecord (String name, UUID uuid)

    Parameters


    name
    service name for SDP record


    uuid
    uuid for SDP record

    Returns
    a listening RFCOMM BluetoothServerSocket

    Throws

    IOException
    on error, for example Bluetooth not available, or insufficient permissions, or channel in use. 

2. 監聽connection request:
    呼叫 accept()

    BluetoothServerSocket
    public BluetoothSocket  accept ()

    Returns
    a connected BluetoothSocket

    Throws

    IOException
    on error, for example this call was aborted, or timeout 

3. 釋放 server socket (除非想要接收額外的connection)
    呼叫 close()

    BluetoothServerSocket
    public void  close ()

    Throws
    IOException

注意:
不應該在 Activity main UI thread呼叫 accept(),因為它是個 blocking call,會把 Application給block住。在使用BluetoothServerSocket和 BluetoothSocket時,應該在新的thread裡執行。

Connecting as a client

要初始化和remote device(擁有 open server socket)之間的connection,先要取得 BluetoothDevice物件代表這個 remote device

步驟:
1. 取得 BluetoothSocket
    呼叫createRfcommSocketToServiceRecord(UUID uuid)
    uuid必須符合server service在開啟BluetoothServerSocket (with   listenUsingRfcommWithServiceRecord(String, UUID))時所用uuid

    BluetoothDevice
    public BluetoothSocket  createRfcommSocketToServiceRecord (UUID uuid)

   
Parameters

    uuid
    service record uuid to lookup RFCOMM channel

    Returns
    a RFCOMM BluetoothServerSocket ready for an outgoing connection

    Throws

    IOException
    on error, for example Bluetooth not available, or insufficient permissions

2. 初始化connection
    呼叫connect()

    BluetoothSocket

    public void  connect ()

    Throws

    IOException
    on error, for example connection failure

    呼叫了connect(),system會查詢 remote device是否有符合的uuid,如果查詢成功,remote
    device會接受這個connection,並分享RFCOMM channel。
    connect()是一個blocking call,當connection fail或 connect()發生time out(約12秒),就會丟出
    exception

注意:
當呼叫 connect時,避免 device正在執行device discovery,否則 connection attempt會變得很慢,並且可能會fail

Managing a connction:

傳送任意資料的步驟:
1. 取得 InputStream和 OutputStream來處理資料傳輸
     呼叫 getInputStream()和 getOutputStream
2. 讀取 steam的資料
    呼叫 read(byte[])和 write(byte[])

注意:
因為 read(byte[])和 write(byte[])是 blocking call,所以應該create新的thread來讀取stream。
read(byte[])會 block住直到 stream有資料可以讀取;只有當device的讀取速度不夠快,導致bufer滿了,write(byte[])才會 block住

2015年7月16日 星期四

Boot time

BootEvent:

cat /proc/bootprof    /** M: Mtprof tool @{ */

LINUX/android/system/core/rootdir/init.rc
INIT: on init start

LINUX/android/device/mediatek/mt6795/init.mt6795.rc
INIT:Mount_START
INIT:Mount_END

LINUX/android/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
Zygote:Preload

frameworks/native/services/surfaceflinger/mediatek/SurfaceFlinger.cpp
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
BOOT_Animation:START
BOOT_Animation:END

./services/java/com/android/server/SystemServer.java
Android:SysServerInit_START

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
Android:PackageManagerService_Start

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
AP_Init:[]

Log:

Boot animation time:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
 316 void SurfaceFlinger::bootFinished()
 317 {
 318     const nsecs_t now = systemTime();
 319     const nsecs_t duration = now - mBootTime;
 320     ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
 321     mBootFinished = true;
 322
 323     // wait patiently for the window manager death
 324     const String16 name("window");
 325     sp<IBinder> window(defaultServiceManager()->getService(name));
 326     if (window != 0) {
 327         window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
 328     }
 329
 330     // stop boot animation
 331     // formerly we would just kill the process, but we now ask it to exit so it
 332     // can choose where to stop the animation.
 333     property_set("service.bootanim.exit", "1");
 334
 335 #ifdef MTK_AOSP_ENHANCEMENT
 336     // boot time profiling
 337     ALOG(LOG_INFO,"boot","BOOTPROF:BootAnimation:End:%ld", long(ns2ms(systemTime())));
 338     bootProf(0);
 339     SFWatchDog::getInstance()->setThreshold(500);
 340 #endif
 341 }

Scan package time:

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
            /** M: Add PMS scan package time log @{ */
            startScanTime = SystemClock.uptimeMillis();
            Slog.d(TAG, "scan package: " + file.toString() + " , start at: " + startScanTime + "ms.");
            /** M: Add PMS scan package time log @{ */
            endScanTime = SystemClock.uptimeMillis();
            Slog.d(TAG, "scan package: " + file.toString() + " , end at: " + endScanTime + "ms. elapsed time = " + (endScanTime - startScanTime) + "ms.");

            Slog.i(TAG, "Time to scan packages: "
                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
                    + " seconds");

AP initialization time:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
            StringBuilder buf = mStringBuilder;
            buf.setLength(0);
            buf.append("Start proc ");
            buf.append(app.processName);
            if (!isActivityProcess) {
                buf.append(" [");
                buf.append(entryPoint);
                buf.append("]");
            }
            buf.append(" for ");
            buf.append(hostingType);
            if (hostingNameStr != null) {
                buf.append(" ");
                buf.append(hostingNameStr);
            }
            buf.append(": pid=");
            buf.append(startResult.pid);
            buf.append(" uid=");
            buf.append(uid);
            buf.append(" gids={");
            if (gids != null) {
                for (int gi=0; gi<gids.length; gi++) {
                    if (gi != 0) buf.append(", ");
                    buf.append(gids[gi]);
                }
            }
            buf.append("}");
            if (requiredAbi != null) {
                buf.append(" abi=");
                buf.append(requiredAbi);
            }
            Slog.i(TAG, buf.toString());

2015年7月14日 星期二

Install Java JDK on Ubuntu

Refernece:

http://www.dotblogs.com.tw/jhsiao/archive/2013/09/03/116186.aspx


Step1.首先到Oracle官網上下載,最新版的"jdk-7u25-linux-x64.tar.gz" or "jdk-7u25-linux-i586.tar.gz"
          (事先建立一個Downloads的資料夾,下載的東西都可放這裡面集中。)
Step2.將下載下來的JDK檔進行解壓縮,指令:tar -zxvf jdk-7u25-linux-i586.tar.gz
Step3.複製解壓縮後的資料夾jdk_1.7.0_25,到/usr/lib/jdk/目錄下面,指令:cp -r ~/Downloads/jdk1.7.0_25/ /usr/lib/jdk/
          (這裡如果沒有jdk資料夾,則建立該資料夾,指令:sudo mkdir /usr/lib/jdk)
Step4.設置環境變數,打開文件/etc/profile,指令:sudo vi /etc/profile
Step5.
在文件的最後端加上:
export JAVA_HOME=/usr/lib/jdk/jdk1.7.0_25 
export JRE_HOME=/usr/lib/jdk/jdk1.7.0_25/jre 
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
Step6.將系統默認的jdk修改過來,也就是java和javac指令由系統自帶的換成你自己安裝的
指令:
sudo update-alternatives --install /usr/bin/java java /usr/lib/jdk/jdk1.7.0_25/bin/java 300
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jdk/jdk1.7.0_25/bin/javac 300
sudo update-alternatives --config java
sudo update-alternatives --config javac
Step7.檢查版本,指令:java -version
如果出現以下字樣,代表順利完成安裝。
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) Server VM (build 23.25-b01, mixed mode)

Installing Android Studio behind Proxy on Ubuntu

l操作步驟:

1. 進入 ${android-studio path}/bin
    Ex: ~/Program/android-studio/bin
2. 編輯  idea.properties
    vi idea.properties
    在檔案尾端加入下列這行並儲存檔案
     disable.android.first.run=true
3. 執行執行Studio
    ./Program/android-studio/bi/studio.sh
4. 進入進入Studio後 從跳出的視窗進行進行proxy設定
    Configure > Settings > Appearance & Behavior > System Settings > HTTP Proxy
5. 關閉Studio
6.  編輯 idea.properties 將步驟2加入的那行刪除並儲存
7.  重新啟動Studio
     

Reference:

http://mayneax.blogspot.tw/2015/01/installing-android-studio-behind-proxy.html


Navigate to the android-studio/bin directory

you need to edit  idea.properties script to skip the initial set up page

so run vi idea.properties
and add this line at the end of the script

disable.android.first.run=true

save the script and the run
 ./studio.sh

 On the window that appears go to Configure>System Settings>http proxy  then set your proxy.

Exit and then edit idea.properties file and remove the line you added, then run

./studio.sh

2015年7月13日 星期一

System server blocked and killed by WatchDag

 如何從各種 log找出造成 System server block的原因

event_log:

07-12 01:42:44.727   956  1520 I [2802]  : Blocked in handler on main thread (main)

main_log:

06-13 15:55:55.725  9028  9028 I AEE/AED : $** *** *** *** *** *** *** *** Fatal *** *** *** *** *** *** *** **$
06-13 15:55:55.725  9028  9028 I AEE/AED : Build Info: 'L0.MP6:ALPS.L0.MP6.TC9SP.V1.38_FIH6795.LWT.S50.L_P43:MT6795:S01,alps/hollyds/hollyds:5.0/2.60.J.1.3_3_04/1434012189:userdebug/test-keys'
06-13 15:55:55.725  9028  9028 I AEE/AED : Flavor Info: 'None'
06-13 15:55:55.725  9028  9028 I AEE/AED : Exception Log Time:[Sat Jun 13 15:55:55 CST 2015] [91427.879630]
06-13 15:55:55.725  9028  9028 I AEE/AED :
06-13 15:55:55.725  9028  9028 V AEE/AED : Write: Req.AE_REQ_CLASS, seq:0
06-13 15:55:55.727  9028  9028 V AEE/AED : Read: Rsp.AE_REQ_CLASS, seq:0, 0, 4
06-13 15:55:55.727  9028  9028 D AEE/AED :   Got data:SWT
06-13 15:55:55.727  9028  9028 I AEE/AED : SWT

06-13 15:55:55.727  9028  9028 V AEE/AED : Write: Req.AE_REQ_TYPE, seq:1
06-13 15:55:55.727  9028  9028 V AEE/AED : Read: Rsp.AE_REQ_TYPE, seq:1, 0, 17
06-13 15:55:55.827  9028  9028 D AEE/AED :   Type:system_server_watchdog
06-13 15:55:55.828  9028  9028 I AEE/AED : system_server_watchdog

06-13 15:55:55.828  9028  9028 V AEE/AED : Write: Req.AE_REQ_PROCESS, seq:2
06-13 15:55:55.828   799  1367 D AEE/LIBAEE: shell: got the request (cmd:Req,AE_REQ_PROCESS)
06-13 15:55:55.829  9028  9028 V AEE/AED : Read: Rsp.AE_REQ_PROCESS, seq:2, 0, e
06-13 15:55:55.829  9028  9028 D AEE/AED :   Process:system_server
06-13 15:55:55.829  9028  9028 I AEE/AED : system_server

06-13 15:55:55.830  9028  9028 V AEE/AED : Write: Req.AE_REQ_MODULE, seq:3
06-13 15:55:55.830  9028  9028 V AEE/AED : Read: Rsp.AE_REQ_MODULE, seq:3, 0, 1
06-13 15:55:55.830  9028  9028 D AEE/AED :   Module:
06-13 15:55:55.830  9028  9028 V AEE/AED : Write: Req.AE_REQ_BACKTRACE, seq:4
06-13 15:55:55.831  9028  9028 V AEE/AED : Read: Rsp.AE_REQ_BACKTRACE, seq:4, 0, bd
06-13 15:55:55.831  9028  9028 D AEE/AED :   Backtrace:Process: system_server
06-13 15:55:55.831  9028  9028 D AEE/AED : Subject: Blocked in handler on main thread (main)
06-13 15:55:55.831  9028  9028 D AEE/AED : Build: alps/hollyds/hollyds:5.0/2.60.J.1.3_3_04/1434012189:userdebug/test-keys
06-13 15:55:55.831  9028  9028 D AEE/AED :
06-13 15:55:55.831  9028  9028 D AEE/AED :
06-13 15:55:55.831  9028  9028 D AEE/AED : Unable to open log device 'crash'
06-13 15:55:55.831  9028  9028 D AEE/AED :
06-13 15:55:55.831  9028  9028 I AEE/AED : Process: system_server
06-13 15:55:55.831  9028  9028 I AEE/AED : Subject: Blocked in handler on main thread (main)

..........
06-13 15:55:42.483   799  1367 I Process : Sending signal. PID: 799 SIG: 3

sys_log:

06-13 15:55:33.637   799  1367 E Watchdog: **SWT happen **Blocked in handler on main thread (main)
.......
06-13 15:56:00.575   799  1367 W Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: Blocked in handler on main thread (main)
06-13 15:56:00.576   799  1367 W Watchdog: main thread stack trace:
06-13 15:56:00.593   799  1367 W Watchdog:     at android.media.ToneGenerator.native_setup(Native Method)
06-13 15:56:00.593   799  1367 W Watchdog:     at android.media.ToneGenerator.<init>(ToneGenerator.java:746)
06-13 15:56:00.593   799  1367 W Watchdog:     at com.android.server.notification.NotificationManagerService$2.onReceive(NotificationManagerService.java:775)
06-13 15:56:00.593   799  1367 W Watchdog:     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:912)
06-13 15:56:00.593   799  1367 W Watchdog:     at android.os.Handler.handleCallback(Handler.java:815)
06-13 15:56:00.593   799  1367 W Watchdog:     at android.os.Handler.dispatchMessage(Handler.java:104)
06-13 15:56:00.593   799  1367 W Watchdog:     at android.os.Looper.loop(Looper.java:194)
06-13 15:56:00.593   799  1367 W Watchdog:     at com.android.server.SystemServer.run(SystemServer.java:359)
06-13 15:56:00.593   799  1367 W Watchdog:     at com.android.server.SystemServer.main(SystemServer.java:227)
06-13 15:56:00.593   799  1367 W Watchdog:     at java.lang.reflect.Method.invoke(Native Method)
06-13 15:56:00.593   799  1367 W Watchdog:     at java.lang.reflect.Method.invoke(Method.java:372)
06-13 15:56:00.596   799  1367 W Watchdog:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955)
06-13 15:56:00.597   799  1367 W Watchdog:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750)

如何從Backtrace中尋找block的原因:

1. 看 Process是 block在哪一個 thread
2. Trace block tread的 callstack,觀察 class name或 function name,尋找可能造成block的地方
    (不管是在 Java code或 native code)
3. 如果是 block在 main thread,從 call stack中又無法看出可能造成 block的地方,可以嘗試搜  
    尋同一個 process下的其他 tread的 call stack,觀察是否有和 main thread呼叫相同 method的地
    方

Backtrace:

----- pid 956 at 2015-07-12 09:42:08 -----
Cmd line: system_server
............
DALVIK THREADS (111):
"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 obj=0x747d7fa8 self=0x558db4b0e0
  | sysTid=956 nice=-2 cgrp=apps sched=0/0 handle=0x7f88880150
  | state=S schedstat=( 2873204364724 2124560498532 5319630 ) utm=153154 stm=134166 core=7 HZ=100
  | stack=0x7fcc017000-0x7fcc019000 stackSize=8MB
  | held mutexes=
  kernel: __switch_to+0x70/0x7c
  kernel: binder_thread_read+0x47c/0xec4
  kernel: binder_ioctl+0x3f8/0x828
  kernel: do_vfs_ioctl+0x4c4/0x598
  kernel: SyS_ioctl+0x5c/0x88
  kernel: cpu_switch_to+0x48/0x4c
  native: #00 pc 0005eeb4  /system/lib64/libc.so (__ioctl+4)
  native: #01 pc 0006882c  /system/lib64/libc.so (ioctl+100)
  native: #02 pc 00028544  /system/lib64/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+164)
  native: #03 pc 00028fa4  /system/lib64/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+112)
  native: #04 pc 00029218  /system/lib64/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+176)
  native: #05 pc 0001ff18  /system/lib64/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+64)
  native: #06 pc 0008aa10  /system/lib64/libmedia.so (???)
  native: #07 pc 00071c38  /system/lib64/libmedia.so (android::AudioSystem::getDevicesForStream(audio_stream_type_t)+40)
  native: #08 pc 000264b8  /system/framework/arm64/boot.oat (Java_android_media_AudioSystem_getDevicesForStream__I+144)
  at android.media.AudioSystem.getDevicesForStream(Native method)
  at android.media.AudioService.getDeviceForStream(AudioService.java:3399)
  at android.media.AudioService.getStreamVolume(AudioService.java:1698)
  at android.media.AudioManager.getStreamVolume(AudioManager.java:961)
  at com.android.server.notification.NotificationManagerService.buzzBeepBlinkLocked(NotificationManagerService.java:1966)
  at com.android.server.notification.NotificationManagerService.access$3600(NotificationManagerService.java:128)
  at com.android.server.notification.NotificationManagerService$7.run(NotificationManagerService.java:1880)
  - locked <0x3d78bf02> (a java.util.ArrayList)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:135)
  at com.android.server.SystemServer.run(SystemServer.java:295)
  at com.android.server.SystemServer.main(SystemServer.java:183)
  at java.lang.reflect.Method.invoke!(Native method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
............

"NetworkPolicy" prio=5 tid=42 Native

  | group="main" sCount=1 dsCount=0 obj=0x139b2860 self=0x557590bc50

  | sysTid=1191 nice=0 cgrp=apps sched=0/0 handle=0x557523dcb0

  | state=S schedstat=( 66132269378 123944333623 433825 ) utm=3755 stm=2858 core=5 HZ=100

  | stack=0x7f6d87d000-0x7f6d87f000 stackSize=1036KB

  | held mutexes=

  kernel: __switch_to+0x70/0x7c

  kernel: binder_thread_read+0x47c/0xec4

  kernel: binder_ioctl+0x3f8/0x828

  kernel: do_vfs_ioctl+0x4c4/0x598

  kernel: SyS_ioctl+0x5c/0x88

  kernel: cpu_switch_to+0x48/0x4c

  native: #00 pc 0005eeb4  /system/lib64/libc.so (__ioctl+4)

  native: #01 pc 0006882c  /system/lib64/libc.so (ioctl+100)

  native: #02 pc 00028544  /system/lib64/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+164)

  native: #03 pc 00028fa4  /system/lib64/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+112)

  native: #04 pc 00029218  /system/lib64/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+176)

  native: #05 pc 0001ff18  /system/lib64/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+64)

  native: #06 pc 000d99dc  /system/lib64/libandroid_runtime.so (???)

  native: #07 pc 010e0fec  /system/framework/arm64/boot.oat (Java_android_os_BinderProxy_transactNative__ILandroid_os_Parcel_2Landroid_os_Parcel_2I+212)

  at android.os.BinderProxy.transactNative(Native method)

  at android.os.BinderProxy.transact(Binder.java:501)

  at com.android.internal.telephony.ISub$Stub$Proxy.getDefaultDataSubId(ISub.java:845)

  at android.telephony.SubscriptionManager.getDefaultDataSubId(SubscriptionManager.java:887)

  at com.android.server.net.NetworkPolicyManagerService.isDdsSimStateReady(NetworkPolicyManagerService.java:2269)

  at com.android.server.net.NetworkPolicyManagerService.setNetworkTemplateEnabled(NetworkPolicyManagerService.java:1019)

  at com.android.server.net.NetworkPolicyManagerService.updateNetworkEnabledLocked(NetworkPolicyManagerService.java:989)

  at com.android.server.net.NetworkPolicyManagerService$7.onReceive(NetworkPolicyManagerService.java:563)

  - locked <0x3532129f> (a java.lang.Object)

  at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:869)

  at android.os.Handler.handleCallback(Handler.java:739)

  at android.os.Handler.dispatchMessage(Handler.java:95)

  at android.os.Looper.loop(Looper.java:135)
  at android.os.HandlerThread.run(HandlerThread.java:61)

Static broadcast receiver in the stopped application can't receive the broadcast

Android developer document:


Launch controls on stopped applications

Starting from Android 3.1, the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents.

It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stoppped applications.

Applications are in a stopped state when they are first installed but are not yet launched and when they are manually stopped by the user.


Article form internet:



1. android 3.1中有一類package 叫做stopped package 它們就是那種安裝了但是從來沒有啟動過的apk,或者被使用者在程式管理裡面force stop了的apk

2. intent中新加了一組flagFLAG_INCLUDE_STOPPED_PACKAGESFLAG_EXCLUDE_STOPPED_PACKAGES),帶有FLAG_EXCLUDE_STOPPED_PACKAGES intentstopped package是不起作用的。

3. 系統對所有的廣播intent都加了flagFLAG_EXCLUDE_STOPPED_PACKAGES,當然boot complete廣播也不例外。

這裡需要注意一點: /system/app下面的apk都是非 stopped package。所以如果你的手機root了,那你可以把apk pushsystem/app


Conclusion:


This is why the SOS app can’t receive the HEADSET_PLUG broadcast when it is first installed but is not yet launched or manually stopped through Settings.

By marking the following command in ActivityManagerService experimentally, I have verified the SOS app can receive the HEADSET_PLUG broadcast successfully.

Source code:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    private final int broadcastIntentLocked(ProcessRecord callerApp,

            String callerPackage, Intent intent, String resolvedType,

            IIntentReceiver resultTo, int resultCode, String resultData,

            Bundle map, String requiredPermission, int appOp,

            boolean ordered, boolean sticky, int callingPid, int callingUid,

            int userId) {

        intent = new Intent(intent);


        // By default broadcasts do not go to stopped apps.

        //intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

                        ……

2015年7月1日 星期三

Enable/Disable SELinux by command

SELinux 可以使用setenforce 0/1來切換mode.
<Permissive mode>
$setenforce 0
<Enforcing mode>
$setenforce 1


SELinux 可以使用getenforce 0/1讀取mode.
Ex:
shell@hollyds:/ # getenforce
getenforce
Enforcing