2012年12月7日 星期五

2012年12月6日 星期四

Android Fragments 的生命週期


當我們在寫Android程式時,程式的生命週期代表著這支程式的從出生、長大、老死的週期,這也代表著程式在每個階段都有屬於自己要執行的任務。
"第一支Android Fragment程式--HelloFragment"這篇文章介紹了基本的Fragments觀念,今天延續該篇繼續了解Fragments 的生命週期。
在前篇說到Fragment (碎片)不能獨立存在必須依附在Activity內,Fragment擁有自己的生命周期,但會受到Activity生命週期的約束。
所以,Fragment程式生命週期如下圖所示。

由於Fragment必須依附在Activity內,所以到底Activity與Fragment生命週期誰先執行,程式執行中哪個間點執行生命週期,以下用一個簡單的程式來討論。

2012年11月18日 星期日

[ iOS ] 利用StoryBoards,不用寫程式就可以達到畫面切換

Storyboards稱為情節串連圖板或稱為故事畫板,在使用Storyboards時,切換畫面就像是一個故事情節跳到另一個故事情節,完全不用寫程式,相當好用。
1.打開XCode。
 2.選擇Single View Application。
3.在Product Name設定成StoryboardTest。
4.儲存專案,選擇Create鍵。
 5.在專案中選擇Mainstoryboard.storyboard檔案,您會看到下圖中有視圖控制器(View Controller)這是根視圖控制器(Root View Controller),每個應用程式都有一個根視圖控制器。
 6.在Object Library中選擇Navigation Controller物件,把它放在View Controller的左邊。下圖是把它Zoom in便於讀者觀看。

7.選擇中間Table View Controller,按下Delete鍵。

8.在Navigation Controller上按下鍵盤的Control鍵及Mouse左鍵,利用拖移至View Controller。
 9.選擇Root View Controller。


10.選擇Navigation Controller,打開屬性檢視器(Attributes Inspector),勾選Is Initial View Controller核取方塊。
 11.執行

 12.新增一個View Controller。
 13.在中間的View Controller上放置一個按鈕,注意當您使用Zoom in時是無法放置物件。
 14.利用拖移功能來設定按鈕及新增加的View Controller之間的關係。
15.選擇push
16.執行結果


2012年11月17日 星期六

Android下如何寫出一個需要Root應用的程式


在Linux/Unix環境下root是最高權限者,所以擁有root就等於擁有系統全部控制權,也因為這樣只要使用root隨便一個動作將會造成系統的損毀或是產生資安問題。
正因如此Android裝置一般原廠不會開放root權限而只會提供uid及gid為shell的權限,除了擔心使用者勿刪重要檔案外,最主要的原因還是資訊安全的問題,例如保護apk程式、線上影音DRM、...等等。
本篇主要實作如何在Android程式中使用root權限執行動作,注意的是當Android裝置進行root後,原廠幾乎不在保固該設備,故本篇文章內容說明在SDK開發中使用root權限全所以不提供如何root方法,相關root方法有需要的Google搜尋一下吧。

[ iOS] Works with iPhone

External Accessory Development

2012年11月11日 星期日

[ Android NEON] HelloNeon範例編譯和執行

讀可以先看看步驟14,奇怪事情發生了,可以編譯,但因有錯誤所以沒辦法執行。

1. 在eclipse上選擇File->Import。
 2.滙入helloneon專案
 3.記得要勾選Copy Project into Workspace
 4.匯入的檔案結構
5. 點選helloneon.c會發現許多.h前面都標示"?",表丕找不到該檔案。 
 6.執行結果失敗,其原因是因為沒有.so。
7. 執行時可以發現有關c的程式沒有被編譯,在專案上按下mouse右鍵,選擇Android Tools->Add Native Support。
8.刪除 com.example.neon.HelloNeon.cpp這個檔案是自動產生的。
 9.打開helloneon.c可以看到蟲蟲了,所以沒法編譯。
10.設定專案的properties。
 11.選擇C/C++ Genera->Paths and Symbol設定路徑。
 12.設定路徑
 13.所有.h都找到但helloneon-intrinsics.c還是有問題
 14.奇怪事情發生了,可以編譯,但因有錯誤所以沒辦法執行。
 15.只好把錯誤訊息變成警告,讀者若有更好的辦法,請告訴敏哥。
 16.執行結果
後記:
文子提供的畫面

另外文子測試結果
使用android-ndk-r8b版本在同一支程式中沒有蟲出現,以下是我測試環境:
Win7 SP1
Eclipse 3.7.2
Java 1.6.0_35
JDT 20.0.3
NDK r8b
另外,跟敏哥部落格文章差別在Paths and Symbol設定路徑(這是自動帶出來的):
C:\cygwin\android-ndk-r8b\sources\android\cpufeatures

C:\cygwin\android-ndk-r8b\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.6.x-google\include

C:\cygwin\android-ndk-r8b\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.6.x-google\include-fixed

C:\cygwin\android-ndk-r8b\platforms\android-14\arch-arm\usr\include

敏哥也按照文子建議,重新下載NDK r8b,結果還是一樣,不過我使用的環境是XP。

[ Android NEON ] 測試 Android NDK 提供的 NEON 程式範例

在Android NDK中有提供一支範例,來介紹NEON的使用,以下是測試的結果。

使用AVD SDK 4.03版測試,有支援ARMv7 CPU。這個測試有違背常理,理論上要比較快,是不是因為採用模擬的結果,使得結果相反。

 使用AVD SDK 2.2版測試,沒有支援ARMv7 CPU。
 使用三星平板GalaxyTab P7510 10.1",CPU不支援,有點失望。
使用HTC Desire HD,測試結果很不錯。
長高設備 210L,測試結果還不錯
 長高 6410XP因為是ARM11不支援NEON
asus nexus測試結果 


[ ARM NEON ] NEON加速資料處理能力

今天我們要介紹NEON技術,當您使用維基百科查詢時,會發現Neon,它是一種化學元素,其符號是Ne,原子序數是10,是一種無色的稀有氣體,在放電時呈現橙紅色,因此廣泛用於霓紅燈之中。 不過今天要跟大家分享是有關於ARMNEON。NEON是一種進階SIMD延伸集,結合64位元和128位元的單指令多資料指令集(SIMD),可加速多媒體和訊號處理的處理。NEON技術用於ARM Cortex-A系列處理器其性能至少為ARM v5的3倍。

2012年11月10日 星期六

[ Android Audio ] 讀取 MIC 的音量

專案功能:能經由麥克風(MIC)讀取音量,並將數值顯示在TextView上

1. 新增專案
Project Name: voiceTest
Package Name: com.example.voicetest
Activity Name: MainActivity
SDK API: 15

2. 在TextView 新增 id

android:id="@+id/text1"

完整的main.xml如下:




3. 使用MediaRecorder來記錄聲音,並利用Handler來定時讀取音量的資訊,MainActivity.java完整程式列表。


package com.example.voicetest;

import java.io.IOException;

import android.media.AudioManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.support.v4.app.NavUtils;

public class MainActivity extends Activity {
private MediaRecorder mRecorder = null;
Handler handler = new Handler(){

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
double ringerVol = mRecorder.getMaxAmplitude();
       TextView tv = (TextView) findViewById(R.id.text1);
       tv.setText(Double.toString(ringerVol));
handler.sendMessageDelayed(Message.obtain(), 300);
}

};
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
   mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
   mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
   mRecorder.setOutputFile("/dev/null"); 
   try {
mRecorder.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
   mRecorder.start();
}
        handler.sendEmptyMessageDelayed(0, 1000);
    }

    @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

 
}

4.新增權限
 5. 執行結果