2012년 5월 8일 화요일

Intents and Intent Filters - 03

Note Pad Example

  • 노트 패드 예제는 사용자가 노트 리스트를 탐색하고 리스트내의 개별 아이템의 세부내용을 볼 수 있게 한다. 그리고 사용자는 리스트에 새로운 아이템을 추가할 수 있게 한다.

  • Note Pad 어플은 각각 최소한 하나 이상의 인텐트 필터를 가진 세 개의 액티비티를 manifest 파일에 선언한다. 그것은 노트 데이터를 관리하는 콘텐트 프로바이더를 추가로 선언한다.

  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.android.notepad">
        <application android:icon="@drawable/app_notes"
                     android:label="@string/app_name" >
    
            <provider android:name="NotePadProvider"
                      android:authorities="com.google.provider.NotePad" />
    
            <activity android:name="NotesList" android:label="@string/title_notes_list">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <action android:name="android.intent.action.EDIT" />
                    <action android:name="android.intent.action.PICK" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.GET_CONTENT" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
                </intent-filter>
            </activity>
            
            <activity android:name="NoteEditor"
                      android:theme="@android:style/Theme.Light"
                      android:label="@string/title_note" >
                <intent-filter android:label="@string/resolve_edit">
                    <action android:name="android.intent.action.VIEW" />
                    <action android:name="android.intent.action.EDIT" />
                    <action android:name="com.android.notepad.action.EDIT_NOTE" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.INSERT" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
                </intent-filter>
            </activity>
            
            <activity android:name="TitleEditor" 
                      android:label="@string/title_edit_title"
                      android:theme="@android:style/Theme.Dialog">
                <intent-filter android:label="@string/resolve_title">
                    <action android:name="com.android.notepad.action.EDIT_TITLE" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.ALTERNATIVE" />
                    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
                    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
                </intent-filter>
            </activity>
            
        </application>
    </manifest>

  • NoteList 액티비티는 일련의 노트에 대해 수행하며 어플의 최초 인터페이스로 작용한다.

  • <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    

    이 필터는 노트패드 어플의 엔트리 포인트로 선언되게 한다.

  • <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <action android:name="android.intent.action.EDIT" />
        <action android:name="android.intent.action.PICK" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
    </intent-filter>
    
    디렉토리를 탐색(VIEW), 편집(EDIT)하고 디렉토리내의 특정 노트를 선택(PICK)할 수 있게 한다.
    데이터 엘러먼트의 mimeType 속성은 액션들이 수행할 데이터 종류를 지정한다.
    이것은 액티비티가 노트패드 데이터(vnd.google.note)를 보유한 콘텐트 프로바이더로부터
    0개 이상의 아이템들(vnd.android.cursor.dir)에 대해 Cursor를 얻을 수 있음을 보인다.
  • <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
    </intent-filter>
  • 이 액티비티의 두번째 목적은 새로운 노트를 만들고 노트 디렉토리에 삽입하는 것이다.
    action : android.intent.action.VIEW
    data : content://com.google.provider.NotePad/notes/ID
    액티비티로 하여금 ID로 지정된 노트의 내용을 표현하게 한다.

    action : android.intent.action.INSERT
    data : content://com.google.provider.NotePad/notes
    액티비티가 새로운 빈 노트를 content://com.google.provider.NotePad/notes에 만들고 편집하게 한다.

  • TitleEditor는 노트의 제목을 편집한다.

  • <intent-filter android:label="@string/resolve_title">
        <action android:name="com.android.notepad.action.EDIT_TITLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.ALTERNATIVE" />
        <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
        <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
    </intent-filter>

    ALTERNATIVE와 SELECTED_ALTERNATIVE는 옵션의 메뉴로 표현될 수 있는 액티비티를 지정한다.

    action:com.android.notepad.action.EDIT_TITLE
    data:content://com.google.provider.NotePad/notes/ID
    노트 ID와 관련된 타이틀을 표시하고, 편집한다.

2012년 5월 7일 월요일

Intents and Intent Filters 02

Intent Resolution

  • 인텐트는 두가지 그룹으로 나뉜다.
  • Explicit intents 컴퍼넌트 이름으로 타겟 컴퍼넌트를 지정한다. 외연적 인텐트은 하위 서비스나 자매 액티비티 실행 같은 어플 내부 메세지로 사용된다.
    Implicit intents 컴퍼넌트 이름을 지정하지 않고 다른 어플의 컴퍼넌트를 활성화시키는 데 사용된다.
  • Implicit Intents는 인텐트를 처리할 최적의 컴퍼넌트를 찾기 위해 인텐트 개체의 내용을 Intent filter와 비교한다.
  • 인텐트 필터는 컴퍼넌트의 능력을 알리고 그것이 다룰 수 있는 인텐트를 제한한다.
  • 인텐트 필터를 갖춘 컴퍼넌트는 explicit/implicit intents를 둘 다 처리할 수 있지만, 그렇지 않을 경우 explicit intents만 수신할 수 있다.
  • 인텐트는 action, data(uri/data type), category), category등의 세가지 측면에서 인텐트 필터로 테스트된다.

Intent filters

  • 시스템에게 어떤 implicit intents를 다룰 수 있는지 알리기 위해 액티비티, 서비스, 브로드캐스트 리시버는 하나 이상의 인텐트 필터를 가질 수 있다.
  • 필터는 컴포넌트가 수신하고자 하는 일련의 인텐트 집합을 기술한다.
Action test
  • manifest 파일에 의 하위 엘러먼트 로 액션들을 나열한다.
  • <intent-filter . . . >
        <action android:name="com.example.project.SHOW_CURRENT" />
        <action android:name="com.example.project.SHOW_RECENT" />
        <action android:name="com.example.project.SHOW_PENDING" />
        . . .
    </intent-filter>
Category test
  • <intent-filter> 엘러먼트는 action 엘러먼트와 같이 category를 하위 엘러먼트로 가진다.
  • <intent-filter . . . >
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        . . .
    </intent-filter>
  • 액션과 카테고리를 위한 상수 대신 문자열이 사용된다. CATEGORY_BROWSABLE에는 android.intent.category.BROWSABLE, ACTION_EDIT에는 android.intent.action.EDIT를 사용한다.
Data test
  • 액션과 카테고리처럼 데이타 역시 인텐트의 하위 엘러먼트로 포함된다.
  • <intent-filter . . . >
        <data android:mimeType="video/mpeg" android:scheme="http" . . . /> 
        <data android:mimeType="audio/mpeg" android:scheme="http" . . . />
        . . .
    </intent-filter>
  • 데이터 엘러먼트는 URI와 데이터 타입(MIME 미디어 타입)을 지정한다.
  • URI는 scheme, host, port 부분들로 이루어 진다.
  • scheme://host:port/path (ex. content://com.example.project:200/folder/subfolder/etc)
  • 데이터 패스 규칙
  • Intent object filter result
    URI data type URI data type
    xx xxpass
    ox oxpass
    xo xopass
    oo oopass
  • 인텐트가 하나 이상의 액티비티 또는 서비스의 필터를 통과하면 사용자는 어떤 컴퍼넌트를 활성화할 것인지 질의받는다. 대상이 존재하지 않는다면 예외가 발생한다.
Common cases
  • 컴퍼넌트는 파일 또는 콘텐트 프로바이더에 로컬 데이터를 얻는 경우 content:/file: scheme를 지정함이 없이 데이터 타입만을 나열한다.
  • 예를 들어 콘텐트 프로바이더으로부터 이미지 데이터를 얻는 컴퍼넌트를 다음과 같이 지정할 수 있다.
  • <data android:mimeType="image/*" />
  • 일반적인 경우 스킴과 데이터 타입을 다음과 같이 지정하여 컴퍼넌트가 네트워크에서 비디오 데이터를 구할 수 있게 한다.
  • <data android:scheme="http" android:type="video/*" />
  • 어플을 초기화하는 액티비티들은 "android.intent.action.MAIN" action를 포함하는 필터들을 가진다. 그들이 어플 론처로 나타난다면 "android.intent.category.LAUNCHER" category 역시 지정한다.
  • <intent-filter . . . >
        <action android:name="code android.intent.action.MAIN" />
        <category android:name="code android.intent.category.LAUNCHER" />
    </intent-filter>
Using intent matching
  • 인텐트는 인텐트 필터에 대칭되어 비교될 뿐만 아니라 장치내 컴퍼넌트들에 대한 것들 탐색하게 한다.
  • PackageManager는 특정 인텐트를 수용할 수 잇는 모든 컴퍼넌트를 리턴하는 query..() 메서들과 인텐트에 반응하는 최적의 컴퍼넌트를 결정하는 resolve...() 메서드들을 가진다.
  • queryIntentActivities() 인텐트에 대해 인수로 받아 그것에 대해 수행할 수 있는 모든 액티비티 리스트를 반환
    queryIntentServices()
    queryBroadcastReceivers()

Intents and Intent Filters 01


액티비티, 서비스, 브로드캐스트 리시버등의 컴퍼넌트들은 Intents로 불리는 메세지에 의해 활성화된다.
인텐트 메세지 장치는 동일한 앱의 컴포넌트들 또는 다른 앱의 컴포넌트들과 late runtime binding를 가능케 한다.
인텐트는 연산되어야 할 추상적인 명세를 지닌 데이터 구조이다.
예를 들어 브로드캐스트는 이미 발생되거나 알려져야 할 무엇인가를 나타낸다.

컴포넌트 유형별 인턴트 전달 메카니즘

  • 인텐트를 인수로 전달되어 액티비티로 하여금 다음과 같은 역활의 메서드를 수행한다.
  • Context.startActivity()새로운 액티비티를 시작한다.
    Activity.startActivityForResult()기존의 액티비티로 하여금 무언가를 지령한다.
    Activity.setResult()startActvityForResult()를 호출한 액티비티에 정보를 전달한다.
  • 다음과 같은 서비스 관련 메서드는 인텐트를 인수로 가지고 각각의 기능을 한다.
  • 브로드캐스트 메서드에 전달된 인텐트 개체들은 관심이 있는 모든 브로드캐스트 리시버들에게 전달된다.

Intent Object

컴퍼넌트가 수행해야 할 Action과 관련 데이터를 지니는 또는 안드로이드 시스템이 알아야 하는 해당 인텐트를 처리할 컴퍼넌트 카테고리와 타겟 액티비티를 실행하는 명령을 기술한  것을 포함하는 한 단위의 정보이다.

인텐트 구성

Component Name
인텐트를 처리할 컴퍼넌트의 이름이며 그 이름 형식은 컴퍼넌트 클래스 이름과 패키지 이름을 결합한 형태이다.
클래스 이름은 생략 가능하며 그 경우에 안드로이드는 인텐트의 다른 정보를 활용하여 타겟을 찾는다.
컴퍼넌트 이름은 setComponent(), setClass(), setClassName()으로 지정되고 getComponentName()로 접근된다.
-Action
수행되어야 액션을 가리키는 문자열
Context.startService()서비스를 초기화 또는 새로운 명령을 전달한다.
Context.bindService()호출 컴퍼넌트와 타겟 서비스간 연결을 성립시킨다.
Constant Target Component Action
ACTION_CALL activity 전화를 초기화
ACTION_EDIT activity 편집할 데이타를 표시
ACTION_MAIN activity 데이터입력과 출력없이 태스크의 초기 액티비티로써 시작
ACTION_SYNC activity 서버의 데이터를 모바일 장치와 동기화
ACTION_BATTERY_LOW broadcast receiver 배터리 잔량이 낮다는 경고
ACTION_HEADSET_PLUG broadcast receiver 헤드셋이 장치에 연결 또는 분리됨을 표시
ACTION_SCREEN_ON broadcast receiver 스크린이 켜졌음을 표시
ACTION_TIMEZONE_CHANGED broadcast receiver 타임존 설정이 변경되었음을 표시


인텐트 개체의 액션은 setAction()에 의해 지정되고 getAction() 의해 접근한다.

Data
  • 작용될 데이터의 URI와 데이터의 MIME 타입
  • 각각의 액션들은 각각 타입의 데이터명세와 쌍을 이룬다.
  • Action fieldData field
    ACTION_EDIT편집을 위해 표시할 다큐멘트의 URI
    ACTION_CALL전화번호를 나타내는 tel:URI
    ACTION_VIEW다운로드 또는 표현될 http:URI
  • 인텐트와 그것을 다룰 수 있는 컴퍼넌트를 매칭할 때 해당 URI와 데이터 타입을 아는 것이 중요하다.
  • 많은 경우, 데이터 타입은 URI로부터 추론될 수 있다. 예를 들어 content: URI는 데이터가 장치내 위치하며 Content Provider에 의해 관리된다는 것을 의미한다.
  • 타입은 인텐트 개체에 대해 명시적으로 지정될 수 있다.
    setData()URI 데이터를 지정
    setType()MIME 타입을 지정
    setDataAndType()
    getData()
    getType()
Category
  • 인텐트를 처리해야 할 컴퍼넌트의 종류에 대한 추가적인 정보를 담은 문자열
  • Category Constants
  • ConstantMeaning
    CATEGORY_BROWSABLE 이미지와 이메일 표시위한 브라우저
    CATEGORY_GADGET 해당 액티비티가 다른 액티비티에 임베디드될 수 있다.
    CATEGORY_HOME 액티비티가 홈스크린을 출력한다
    CATEGORY_LAUNCHER 태스크의 초기 액티비티가 될 수 있으며 최상위 어플 런처에 배치된다.
    CATEGORY_PREFERENCE 타겟 액티비티가 Preference Panel이다.
  • Method
  • addCategory()
    removeCategory()
    getCategories
Extras
  • 인텐트를 처리할 컴퍼넌트에 전달되어야 할 추가적 정보의 Key-value pair
  • ActionExtra설명
    ACTION_TIMEZONE_CHANGEDtime-zone
    ACTION_HEADSET_PLUGstate, name
    SHOW_COLOR
Flags

2012년 5월 6일 일요일

액티비티 라이프사이클 관리


사용자가 앱을 실행, 나오기, 다시 접근할 때
액티비티 인스턴스는 라이프사이클의 각각의 상태에
놓인다.

액티비티가 처음으로 시작할 때 시스템의 전면으로 나와
사용자의 사용자 포커스를 받는다.
이 과정에서 안드로이드 시스템은 사용자에 의해 설정된 유저 인터페이스
와 다른 컴퍼넌트들의 메스드를 호출한다.
사용자는 다른 액티비티 또는 다른 앱을 실행할 경우
해당 액티비티는 백그라운드로 이동하여 해당 액티비티의 또 다른
라이프 사이클 함수 그룹을 호출하여 처리한다.

액티비티 시작하기

main() 메서드에서 개시되는 다른 프로그래밍 패러다임과 달리
안드로이드는 라이프 사이클의 특정 단계에 대응되는 콜백함수를
호출함으로써 액티비티 인스턴스의 코드를 초기화한다.

라이프사이클 콜백 이해하기

onCreate() -> Created -- onStart() -> Started(visible) -- onResume() -> Resumed(visible)

Resumed(visible) -- onPause() -> Paused(partially visible)
Paused -- onResume() -> Resumed
Paused -- onStop() -> Stopped(hidden)

Stopped -- onStart() -> Started
Stopped -- onDestroy() -> Destroyed

액티비티 라이프사이클 함수들의 역활
-사용자가 앱을 사용중 전화 수신시 또는 다른 앱으로 전환될 경우 종료되지 않게 한다.
-시스템 자원의 효율적 관리
-사용자 어플을 떠나서 다시 복귀해 어플의 전개과정을 이어간다.
-스크린의 랜드스케이프와 포트레이트 회전시 어플의 크래시 방지와 프로그래스를 잃지 않게 함.

액티비티의 정적 상태
-Resumed
: 액티비티가 전면에 배치되고 사용자와 상호작용할 수 있음
-Paused
: 액티비티가 다른 액티비티에 의해 부분적으로 가려지며 사용자와 상호작용이
중지된다.
-Stopped
: 액티비티는 완전히 숨겨져 백그라운드로 놓인며 해당 인스턴스와 멤버변수같은 상태정보들이 저장된다.

론처 액티비티 지정
사용자가 홈화면에서 앱아이콘을 클릭하면 시스템은 론처 또는 메인으로 지정된
액티비티의 onCreate()를 호출한다.
메인 액티비티는 프로젝트의 루트 디렉토리에서 AndoridManifest.xml에서 정의하며
MAIN action과 LAUNCHER category를 포함하는 <intent-filter>를 선언함으로써
이루어진다.

<activity android:name=".MainActivity" android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity

새 인스턴스 생성

TextView mTextView; // Member variable for text view in the layout

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Set the user interface layout for this Activity
    // The layout file is defined in the project res/layout/main_activity.xml file
    setContentView(R.layout.main_activity);
   
    // Initialize member TextView so we can manipulate it later
    mTextView = (TextView) findViewById(R.id.text_message);
   
    // Make sure we're running on Honeycomb or higher to use ActionBar APIs
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        // For the main activity, make sure the app icon in the action bar
        // does not behave as a button
        ActionBar actionBar = getActionBar();
        actionBar.setHomeButtonEnabled(false);
    }
}

액티비티 종료하기

@Override
public void onDestroy() {
    super.onDestroy();  // Always call the superclass
   
    // Stop method tracing that the activity started during onCreate()
    android.os.Debug.stopMethodTracing();
}

액티비티의 중지와 재개

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first

    // Release the Camera because we don't need it when paused
    // and other activities might need to use it.
    if (mCamera != null) {
        mCamera.release()
        mCamera = null;
    }
}

액티비티 정지와 재시작
-시나리오
사용자가 Recent Apps window를 열어 다른 앱으로 이동한다. 현재의 사용자 앱은
전면에 있는 것은 stop된다.

@Override
protected void onStop() {
    super.onStop();  // Always call the superclass method first

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    getContentResolver().update(
            mUri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
            );
}

@Override
public void onResume() {
    super.onResume();  // Always call the superclass method first

    // Get the Camera instance as the activity achieves full user focus
    if (mCamera == null) {
        initializeCamera(); // Local method to handle camera init
    }
}

2012년 4월 30일 월요일

2012년 4월 29일 일요일

안드로이드 에뮬레이터 초기화


$cd ~/.android/avd/[user-defined.avd]/
$rm -f userdata-qemu.img

안드로이드 개발환경 설치


pre. 유분투 64에서 ia32-libs 설치

1. 이클립스 설치
$sudo apt-get install eclipse eclipse-jdt -force-yes=yes

2. 이클립스 실행문제
 #eclipse가 실행되지 않을 경우
$sudo update-alternatives --config java
실행하여 openjdk를 선택
 OR
 ln -s /usr/lib/jni/libswt-* ~/.swt/lib/linux/x86_64/
3. ADT 설치
 eclipse에서 Help-Install New Software를 클릭햐여
 https://dl-ssl.google.com/android/eclipse/ 주소를
추가하여 ADT를 설치