Search Results

Search Results for '안드로이드/펌글' : 5 POSTS

  1. 2011.07.11 AndroidManifest.xml
  2. 2011.03.16 Parcelable을 사용한 오브젝트 전달 (Object serialization using Parcelable)
  3. 2011.03.09 SQLite
  4. 2011.01.14 Intent 존재여부 확인하기
  5. 2010.08.22 RelativeLayout 사용하기

AndroidManifest.xml

출처: http://nuninaya.tistory.com/556



<?xml version=”1.0” encoding=”utf-8”?>

<manifest>

<uses-permission />

<permission />

<permission-tree />

<permission-group />

<instrumentation />

<uses-sdk />

<uses-configuration />

<uses-feature />

<supports-screens />

<application>

<activity>

<intent-filter>

<action />

<category />

<data />

</intent-filter>

<meta-data />

</activity>

<activity-alias>

<intent-filter> . . . </intent-filter>

<meta-data />

</activity-alias>

<service>

<intent-filter> . . . </intent-filter>

<meta-data/>

</service>

<receiver>

<intent-filter> . . . </intent-filter>

<meta-data />

</receiver>

<provider>

<grant-uri-permission />

<path-permission />

<meta-data />

</provider>

<uses-library />

</application>

</manifest>

 

매니패스트 파일은 어플리케이션에 대한 전반적인 정보를 담고 있는 파일로, 어플리케이션이 실행되기 전에 시스템이 알고 있어야 하는 파일이다. 이 매니페스트 파일 안에는 어플리케이션 컴포넌트(Activity, Service, intents, Content provider, Broadcast Receivers)에 대한 노드를 포함하고 있고 Intent filter와 같이 permissions을 사용해 다른 컴포넌트와 어플리케이션이 어떻게 상호 작용을 하는지를 결정한다.

 

</receiver>

<provider>

<grant-uri-permission />

<path-permission />

<meta-data />

</provider>

<uses-library />

</application>

</manifest>

<manifest>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.android.notepad"

android:versionCode="1"

    android:versionName="1.0">

[어플리케이션 태그  Permission 태그들]

</manifest>

AndroidManifest.xml의 root element로써 <manifest> 태그가 전체를 감싸는 구조를 하고 있으며 package attribute의 값으로는 어플리케이션의 base를 지정하는 Java package 이름이 온다.

 

<uses-permission>

<uses-permission android:name="string" />

어플리케이션의 필요한 기능의 권한을 정의해준다. 여기에 정의된 권한은 설치 과정 중 사용자에게 보여주고권한부여 혹은 거절이 결정된다.

android:name  애플리케이션 안에 <permission>엘리먼트를 사용해서 정의된 퍼미션 이름

다른 애플리케이션에 의해 정의된 퍼미션의 이름

표준 시스템 퍼미션의 이름( - android.permission.INTERNET)

 

<permission>

<permission android:description="string resource"

android:icon="drawable resource"

android:label="string resource"

android:name="string"

android:permissionGroup="string"

android:protectionLevel=["normal" | "dangerous" | "signature" | "signatureOrSystem"]

/>

컴포넌 사용하기 위한 권한 중에 안드로이드가 제공하는 권한 이외에 다른 권한이 필요할 때 정의한다. 다른 어플리케이션이 이 컴포넌트를 사용하려면 자신의 매니페스트에 uses-permission 태그를 설정해 주거나<activity android:permission>속성에 권한을 추가해 주면 된다.

                                android:description  퍼미션의 설명으로 사용자에게 퍼미션을 설명하기 위해 사용 될 수도 있다.

android:icon  퍼미션을 의미하는 아이콘의 리소스의 레퍼런스로 예를 들어res/drawable/app_note.png라는 파일이 있다면 @drawable/app_note라고 쓴다.

android:label  사용자에게 보여질 수 있는 퍼미션의 이름다. 배포가 될때는 string.xml에 정의하고 @string/app_name 같이 사용하여야 한다.

android:name  코드에서 사용되는 퍼미션의 이름이다.com.example.project.PERMITTED_ACTION과 같이 고유한 이름을 사용해야 한다.

android:permissionGroup  그룹에 퍼미션을 할당한다. <permission-group>으로 선언되어진 그룹의 이름을 지정한다.

android:protectionLevel  이 레벨 설정에 따라서 사용자가 퍼미션을 요구하는 애플리케이션을 알 수 있거나 해당 퍼미션을 누가 사용하는지를 알 수 있다.

normal : 디폴트 값으로 낮은 수위의 위험을 갖는다. 최소한의 위험요소를 가진 애플리케이션이 다른 애플리케이션 레벨의 기능들에 대해 접접근하는 것 부여한다.

dangerous : 높은 수위의 위험을 갖는다. 사용자의 사적 데이터 접근이나 디바이스에 대한 제어를 허용한다.

signature 애플리케이션이 다른 애플리케이션과 같은 인증서를 가지고 사인되었을때에 한하여 시스템이 퍼미션을 부여한다.

signatureOrSystem 시스템이 안드로이드 시스템 이미지 안에 있거나 시스템 이미지 안에 있는 것들과 같은 인증서로 사인된 애플리케이션에 한하여 부여한다.

 

<permission-tree>

<permission-tree android:icon="drawable resource"

   android:label="string resource"

      android:name="string" />

퍼미션 트리에 대한 기본적인 이름을 선언한다. 이 애플리케이션은 트리 내의 모든 이름들에 대한 소유권을 갖는다.

 

<permission-group>

<permission-group android:description="string resource"

 android:icon="drawable resource"

 android:label="string resource"

        android:name="string" />

퍼미션 그룹의 이름을 선언한다.

 

<instrumentation>

실행 시 액티비티와 서비스를 테스트 하기 위한 프레임워크롤 제공하며, 선언된 클래스는 시스템리소스와 상호작용을 모니터링하기 위한 연결 고리를 제공한다.

Jfeature를 설치해 Test를 사용할 경우

<instrumentation android:targetPackage="com.jfeature" android:name="android.test.InstrumentationTestRunner"/>

<instrumentation android:functionalTest=["true" | "false"]

android:handleProfiling=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:name="string"

android:targetPackage="string" />

이 엘리먼트가 매니페스트에 자동으로 생성된다.

android:functionalTest  기능적 테스트를 위해 수행되어야 하는지 여부를 표시한다. 디폴트 값은 false이다.

android:handleProfiling  프로파일링을 on, off 할 것인지의 여부를 표시한다. 프로파일링을 시작할 때와 멈출때는 결정하려면 ture, 프로파일링이 시행되는 모든 시간 동안 계속 하려면 false로 표시한다. 디폴트는 false이다.

android:targetPackage  타겟으로 정할 패키지 주소를 입력한다.

 

<uses-sdk>

<uses-sdk android:minSdkVersion="integer"

android:maxSdkVersion="integer"

amdroid:targetSdkVersion="integer" />

Android Version이 아닌 API 레벨을 설정한다.

android:minSdkVersion  API의 최소레벨을 지정하는 함수로 Default값은 1이다.

시스템이 지정한 값보다 낮은 버전 이라면 시스템에 설치 되지 않는다.

android:maxSdkVersion  API의 최소레벨을 지정하는 함수이다. 시스템이 지정한 값보다 높은 버전이라면 시스템에 설치 되지 않는다. 이 애트리뷰트를 사용하는 것을 권장하지 않는다. 왜냐하면 신규 버전의 안드로이드 플렛폼 배치가 차단되고더 높은 API 레벨로 시스템이 업데이트 된 이후 사용자의 디바이스에서maxSdkVersion이 시스템보다 낮은 값으로 설정된 애플리케이션이 제거된다.

android:targetSdkVersion - 애플리케이션이 타겟으로 하고 있는 API 레벨을 지정하는 함수이다.

 

<uses-feature>

<uses-feature android:glEsVersion="integer"

       android:name="string" />

SDK버전을 선언하는 것과 비슷하게 기능을 지원하지 않는 디바이스 상에는 설치가 되지 않도록 하는 옵션이다. 예를 들어 디바이스가 카메라를 지원하지 않으면 어플리케이션이 설치 되지 않는다. 애플리케이션이 특정 디바이스를 사용해야 한다면 이 옵션을 추가해야 한다.

                                   android:glEsVersion  애플리케이션이 필요로 하는 GLES 버전이다.

android:name  애플리케이션이 필요로 하는 기능의 이름으로써 예로android.hardware.camera와 같이 쓰이는데 이것은 애플리케이션이 카메라를 필요로 한다는 의미이다.

<supports-screens>

<supports-screens android:smallScreens=["true" | "false"]

                 android:normalScreens=["true" | "false"]

                 android:largeScreens=["true" | "false"]

                 android:anyDensity=["true" | "false"] />

애플리케이션이 지원하는 스크린 크기를 지정하는 옵션이다.(멀티해상도 관련)

android:smallScreens  애플리케이션이 normal보다 더 작은 스크린을 지원하는지 여부이다. API 레벨 4이상에서는 디폴트 값이 ture이고 다른 레벨에서는 false이다.

android:normalScreens  애플리케이션이 normal 스크린을 지원하는지 여부다. 디폴트 값은 true이다.

android:largeScreens  애플리케이션이 normal보다 더 큰 스크린을 지원하는지 여부이다. API 레벨 4이상에서는 디폴트 값이 ture이고 다른 레벨에서는 false이다.

android:anyDensity  애플리케이션이 임의의 스크린 밀도를 수용할 수 있는 지에 대한 옵션이다. API레벨 4이상에서는 디폴트 값이 true이고 다른 레벨에서는false이다.

 

<application>

<application android:allowClearUserData=["true" | "false]

android:allowTaskReparenting=["true" | "false"]

android:debuggable=["true" | "false"]

android:description="string resource"

android:enabled=["true" | "false"]

android:hasCode=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:manageSpaceActivity="string"

android:name="string"

android:permission="string"

android:persistent=["true" | "false"]

android:process="string"

android:task="string"

android:theme="resource or theme" >

. . .

</application>

이 엘리먼트는 반드시 한번 사용되어야 한다. Application 아래에 있는 서브 엘리먼트는 없거나 순서가 바뀌어도 문제되지 않는다. 애플리케이션의 메타데이타(타이틀, 아이콘, 테마 등)을 지정한다.

                                    android:allowClearUserData  사용자들에게 사용자 데이터를 제거할 수 있는 옵션을 부여할 것인가에 대한 애트리뷰트이다.

                                    android:allowTaskReparenting  이 애트리뷰트가 true로 설정되어 있다면 액티비티는 시작된 태스크부터 affinity를 갖는 태스크가 된다.

예를 들어 e-mail Activity에서 web page링크를 클릭하게 되면 해당 페이지가 보여지는 브라우저가 시작되게 된다. 이 Activity는 Browser Application에 정의 되어 있지만 e-mail Task의 일부로 실행된 상태이다. 만약 android:allowTaskReparenting이 true로 되어있고 Browser Task로 Reparenting되면 Browser어플리케이션에서 그 페이지가 보여질 것이고 다시 e-mail Task가 보여지면 그 Activity는 보이지 않게 된다. 디폴트 값은 false이다.

D:\WORK\리소스\Task.png

                                 android:debuggable  사용자모드로 실행중일 때 디버그 될수 있는지를 설정한다. 디폴트 값은 false이다. false로 설정한다면 Wating for Debugger화면에서 더 이상 진행되지 않는다.

     android:enable  애플리케이션의 컴포넌트를 인스턴스화 할 수 있는지를 설정한다. 디폴트 값은 true이다“true”라면 각 컴포넌트의 enabled 애트리뷰트가 그 컴포넌트의 활성화 여부를 결정하고 false라면 모든 컴포넌트들은 비활성화 된다.

 android:hasCode  시스템 코드가 아닌 다른 코드를 포함하고 있는지를 설정한다. 디폴트 값은 true이다.

 android:manageSpaceActivity  디바이스상에서 애플리케이션이 점유하는 메모리를 사용자가 관리 할 수 있도록 하는 액티비티 이름이다.

adroid:permission  클라이언트와 애플리케이션이 상호작용하기 위해 필요한 퍼미션 이름이다. 이 애트리뷰트는 애플리케이션 안의 모든 컴포넌트에 퍼미션을 적용한다.

android:persistent  애플리케이션이 항상 실행 상태로 있는지의 설정값이다. 디폴트는false이다.

android:process  애플리케이션 프로세스의 이름이다. 애플리케이션 안에 모든 컴포넌트는 이 애트리뷰트의 프로세스로 실행이 되고 각 컴포넌트에 process 애트리뷰트를 설정 함으로써 오버라이드 할 수 있다. 디폴트 <manifest>엘리먼트의 package이름이다. 이 애트리뷰트의 이름이 콜론(:)으로 시작되면 private하고 소문자로 시작한다면 그 이름을 가진 글로벌 프로세스가 만들어진다. 글로벌 프로세스는 공유될 수 있어 리소스 사용을 감소시킨다.

android:taskAffinity  애플리케이션 안 모든 액티비티에 적용되는 affinity이름이다. 액티비티 내에 taskAffinity를 설정했다면 적용되지 않는다. 디폴트로 <manifest>엘리먼트의 package 이름을 가지고 어플리케이션내에 액티비티는 동일 Affinity를 공유한다.

android:theme  애플리케이션 안의 모든 액티비티에 적용되는 스타일 리소스에 대한 레퍼런스 이다. 각각의 액티비티는 이 설정을 override 할 수 있다.

 

<activity>

<activity android:allowTaskReparenting=["true" | "false"]

android:alwaysRetainTaskState=["true" | "false"]

android:clearTaskOnLaunch=["true" | "false"]

android:configChanges=[one or more of: "mcc" "mnc" "locale"

"touchscreen" "keyboard" "keyboardHidden" "navigation""orientation" "fontScale"]

android:enabled=["true" | "false"]

android:excludeFromRecents=["true" | "false"]

android:exported=["true" | "false"]

android:finishOnTaskLaunch=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:launchMode=["multiple" | "singleTop" | "singleTask"| "singleInstance"]

android:multiprocess=["true" | "false"]

android:name="string"

android:permission="string"

android:process="string"

android:screenOrientation=["unspecified" | "user" | "behind" | "landscape" | "portrait" | "sensor" | "nonsensor"]

android:stateNotNeeded=["true" | "false"]

android:taskAffinity="string"

android:theme="resource or theme"

android:windowSoftInputMode=[one or more of:"stateUnspecified"

"stateUnchanged" "stateHidden"

"stateAlwaysHidden" "stateVisible"

"stateAlwaysVisible" "adjustUnspecified"

"adjustResize" "adjustPan">

. . .

</activity>

각각의 액티비티마다 <activity>태그가 필요하다. 매니페스트 파일에 액티비티가 정의되어 있지 않다면 해당 액티비티를 실행시킬 수 없다.(런타임 오류가 발생)

                        android:allowTaskReparenting  친화력 있는 태스크 설정 애트리뷰트이다. 이 애트리뷰트가 설정되지 않으면 <application>엘리먼트의 allowTaskReparenting에 설정된 값이 액티비티에 적용된다. 디폴트 값은false이다.

                        android:alwaysRetainTaskState  사용자가 Task를 오랫동안 방치하면 시스템은 Root Activity를 제외한 모든 Activities의 Task를 Clear 시킨다. 이 애트리뷰트가 true로 설정 되어 있다면 Task는 오랜 시간이 지나도 Stack에 있는 모든 Activity를 유지한다. 디폴트 값은 false이다.

                        android:clearTaskOnLaunch  이 속성이 true로 설정되어 있으면 사용자가 Task를 떠났다가 다시 돌아 올 때마다 Stack은 Root Activity로 정리된다. 디폴트 값은 false이다.

                        Android:configChanges  시스템은 각 어플리케이션을 종료하고 재시작한 뒤 리소스 값을 다시 읽어 들임으로써 언어, 위치, 하드웨어에 대한 런타임 변경을 지원한다. 런타임 구성 변경을 감지하는 activity를 가지려면 Manifest 노드에 android: configChanges 속성을 추가 한 뒤 변경을 하고자 하는 구성 변경을 지정한다. 여러 값을 사용할 때는 |’에 의해 구분된다.

mcc IMSI 모바일 국가 코드가 변경되었다.

mnc : IMSI 모바일 네트워크 코드가 변경되었다.

locale : 사용자가 다른 언어 설정을 선택했다.

touchscreen : 터치스크린이 변경되었다.

keyboard : 키보드 종류가 바뀌었다.

keyboardHidden : 키보드가 보여졌거나 숨겨졌다.

navigation : 네비게이션 타입이 변경 되었다.

origentation : 화면이 세로 방향이나 가로 방향으로 회전됐다.

fontScale : 사용자가 선호하는 글꼴 크기를 변경했다.

 

/// Configuraion 객체를 사용해 새로운 구성 값을 결정하도록

/// OnConfigurationChnaged 메서드를  한다.

@Override

public void onConfigurationChanged(Configuration _newConfig) {

      super.onConfigurationChanged(_newConfig);

     // resource 값에 기반을 두고 있는 모든 GUI update 한다.

 

     // ....

     if (_newConfig.orientation == Configuration.OPRIENTATION_LANDSCAPE)

{

        // 방향이 landscape 변경되면 해당 방향으로 반응을 한다.

}

 

    if (_newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO)

    {

        // 변경된 키보드의 유무에 반응을 한다.

    }

}

시스템이 재시작 되지 않을 경우 다음과 같이한다.

android:excludeFromRecents  true이면 사용자가 볼 수 있는 최근 런치된 액티비티 리스트에서 제외되고 false이면 리스트에 포함된다. 디폴트 값은 false이다.

android:exported  다른 애플리케이션의 컴포넌트에서 이 액티비티를 런치 할 수 있는지를 설정한다. false”라면 이 액티비티는 같은 애플리케이션 혹은 같은 유저 ID를 가진 애플리케이션 컴포넌트만 런치 할 수 있다. 디폴트는 액티비티가 인텐트 필터를 포함하는지에 달려있다. 필터가 없다면 디폴트 값이 false이고 필터가 있다면 true이다.

MAIN/LAUNCHER 액티비티에는 절대로 false값을 주면 안 된다false값을 주게 되면 SecurityException이 발생하고 exported 속성을 true로 설정해 달라는 메시지가 출된다.

            android:finishOnTaskLaunch  사용자가 태스크를 런치 할 때 마다 액티비티의 기존 인스턴스가 종료 되어야 하는지의 여부를 설정한다. 종료되어야 한다면 true이고 종료되지 않아야 한다면 false이다. 디폴트 값은 false이다. 만약 이 애트리뷰트와 allowTaskReparenting이 모두 true라면 액티비티 친화력은 무시되어 액티비티는 부모를 바꾸지 않고 파괴된다.

android:launchMode  액티비티가 어떻게 런치되어야 하는지에 대한 명령이다. 4가지 런치모드(standard singleTop” “singleTask singleInstance )가 있고 디폴트는 standard이다.

모드는 두개의 main Group으로 나뉜다(standard, singleTop / singleTask, singleInstance). standardsingleTop모드를 가지는 액티비티는 여러 번 인스턴스화 될 수 있으나(Intent Object가 FLAG_ACTIVITY_NEW_TASK flag를 가지고 있지 않을 경우에 해당) singleInstance 액티비티는 하나의 Task만 시작 할 수 있다.

standard vs singleTop : standard 액티비티에 대한 새로운 Intent가 발생하면 언제나 해당 Class의 Instance가 만들어 지지만 singleTop 액티비티의 새로운 Instance는 생성 될 수도 있다. 즉, Target Task에 이미 해당 액티비티의 인스턴스가 존재하면 새로 만들어지지 않고 기존 인스턴스가 새로운 Intent를 받게 된다.

singleTask vs singleInstance : singleTask 액티비티는 다른 액티비티들이 해당 Task의 일부가 되는 것을 허락하여 singleTask 액티비티는 액티비티 스택의 root에 존재하게 되고 다른 액티비티들은 동일한 Task에서 시작 될 수 있다. 이와 달리singleInstance 액티비티는 어떤 다른 액티비티들도 해당 Task의 일부가 될 수 없다. 이로 인해 해당 Task에는 유일한 Activity만 존재하고 또 다른 Activity를 실행하려고 하면 새로운 Task로 할당이 된다.

android:multiprocess  이 플래그가 true이면 액티비티 인스턴스가 다양한 프로세스에서 실행 될 수 있다. 디폴트 값은 false이고 true값은 지양한다.

android:noHistory  true라면 사용자가 액티비티를 떠나 화면에 보이지 않았을 때 스택에서 제거되고 종료(finish()메소드가 호출됨)된다. 기본값은 false이다.

android:permission  액티비티를 런치하기 위해 혹은 인텐트에 응답하기 위해 얻어야 하는 퍼미션 이름이다. 만약 startActivity() 또는 startActivityForResult()의 호출자가 퍼미션을 부여받지 않으면 인텐트는 해당 액티비티에 전달 되지 않는다.

애트리뷰트가 설정되지 않으면 <application>엘리먼트의 퍼미션이 적용되고 <application>엘리먼트 퍼미션이 없다면 이 액티비티는 퍼미션에 의해 보호되지 않는다.

android:process  액티비티가 실행되어야 하는 프로세스의 이름이다. 디폴트 프로세스 이름은 어플리케이션 패키지 이름이다.

android:screenOrientation  액티비티의 방향을 설정한다.

unspecified : 시스템에서 디바이스에 따라 방향을 결정

landscape : 가로방향

portrait : 세로방향

behind : 이전 액티비티의 스택에 따라 결정

user : 사용자 설정

sensor : 가속 센서의 방향에 따라 결정

nosensor : 가속 센서를 사용하지 않음, unspecified와 비슷

android:stateNotNeeded  액티비티가 임시로 종료되기 전에 리소스를 저장하기위해 onSaveInstanceState() 메쏘드가 호출된다 메쏘드는 액티비티가 재시작될 , onCreate() 전달되는 Bundle 액티비티의 현재 상태를 저장한다만약 애트리뷰트가 true”로 설정되 onSaveInstanceState() 호출되지 onCreate() bundle 대신에 null 전달받는다. 디폴트 값은 false이다.

android:taskAffinity  이곳에 다른 task name을 설정해 주면 이 액티비티는 해당 task에 실행된다. 하나의 어플리케이션에서 실행되는 아이콘을 여러 개 만드는데 사용된다. 기본적으로 액티비티는 애플리케이션의 친화력을 상속한다. 애플리케이션의 디폴트 친화력 이름은 <manifest>엘리먼트의 패키지 이름이다.

android:theme  액티비티의 테마를 정의하는 스타일 리소스에 대한 레퍼런스이다. 기본적으로 <application>엘리먼트의 테마를 사용하고 테마가 없으면 시스템 테마가 사용된다.

android:windowSoftInputMode  소프트 키보드 상태 : 액티비티가 사용자 관심의 포커스를 받을 때 소프트 키보드가 보여지는지 여부를 설정한다.

액티비티 메인 윈도우에 대한 조정 : 소프트 키보드를 위한 공간을 만들기 위해 액티비티 메인 윈도우를 작게 줄일 지의 여부 또는 메인 윈도우 일부가 소프트 키보드에 의해 가려질 때 현재 포커스를 보이도록 하기 위해 메인 윈도우의 컨텐트가 상하로 움직일 지의 여부를 설정한다.

stateUnspecified : 소프트 키보드 상태에 대해 시스템이 적절한상태를 선택하거나 테마 설정값을 따른다. 소프트 키보드의 디폴트 설정 값.

stateUnchanged : 소프트 키보드는 마지막 상태로 유지

stateHidden : 사용자 액티비티를 선택할 때 소프트 키보드는 숨겨짐

stateAlwaysHidden : 액티비티의 메인 위도우가 입력 포커스를 가질 때 소프트 키보드는 항상 숨겨짐

stateVisible : 사용자가 액티비티 메인 위도우 앞으로 갈 때 소프트 키보드 보여짐

stateAlwaysVisible : 사용자가 액티비티를 선택할 때 소프트 키보드 보여짐

adjustUnspecified : 스크롤 할 수 잇는 레이아웃 뷰들을 가지고 있다면 윈도우 크기 재조정. 메인 윈도우의 디폴트 값

adjustResize : 스크린에 소프트 키보드 공간을 만들기 위해메인 윈도우 크기가 항상 재조정 됨

adjustPan : 소프트 키보드 공간을 만들기 위해 메인 윈도우 크기가 재조정 되지 않음

 

<intent-filter>

수행되어야 할 Action을 서술해 놓은 정보의 묶음이다. 이 정보에는 수행되었을 때의 데이터, Action을 수행하기 위한 구성 요소의 Category, 그리고 또 다른 적절한 지시 등이 포함된다.

Android System은 Component를 구동하기 전에 Component가 다루려 하는 의도를 파악해야 하기 때문에 Intent Filters은 <intent-filter> 요소로 Manifest에 규정되어 있어야 한다. 하나의 Component는 여러 개의 Filters을 가질 수 있고 각각은 서로 다른 Capabilities를 나타내게 된다.

<intent-filter android:icon="drawable resource"

android:label="string resource"

android:priority="integer" >

. . .

</intent-filter>

Target Component를 명시적으로 명명한 Intent는 해당 Component를 활성화 시키게 되는데 이 때는 filter가 사용되지 않는다. 그러나 명시적으로 Target을 정하지 않게 되면 Component's Filters 중 하나를 통해 전달하게 된다.

android:priority  부모 컴포넌트가 필터에 따른 인텐트 처리의 우선순위이다. 액티비티와 브로드캐스드의 경우에 해당한다.

필터와 일치하는 인텐트에 대해 응답 방법에 대한 정보를 제공하고 인텐트에 대한 잠재적 타겟으로 높은 우선순위인 액티비티만을 고려한다.

높은 우선순위의 값을 가지는 브로트캐스트 리시버가 먼저 호출된다.

 

<action>

<action android:name="string" />

<intent-filter>엘리먼트는 반드시 하나이상의 <action>엘리먼트를 포함해야 한다.

android:name  액선의 이름으로써 ACTION_문자열 상수이다. 예를들어 ACTION_MAIN에 대해서는android.intent.action.MAIN, ACTION_WEB_SEARCH에 대해서는 anroid.intent.action.WEB_SEARCH를 사용한다.

안드로이드 패키지가 아닌 직접 정의한 액션에 대해서는 접두어로 패키지 이름을 사용하는 것이 좋다. 예를들어 TRANSMOGRIFY액션은 com.example.project.TRANSMOGRIFY 처럼 사용한다.

<category>

<category android:name="string" />

인텐트가 카테고리 테스트를 통과하기 위해서는 인텐트 오브젝트 안의 모든 카테고리가 필터에 있는 카테고리와 일치해야 한다.

android:name  카테고리의 이름으로써 CATEGORY_name 상수이다. 예를들어 CATEGORY_LAUNCHER에 대한 문자열 값은 android.intent.category.LAUNCHER이다.

<data>

URI와 데이터 타입(MIME 미디어 타입) 지정 할 수 있다. schema, host, port, path와 같은 URI 애트리뷰트들에 의해 지정된다.

scheme://host:port/path 또는 pathPrefix 또는 pathPattern

예를들어 content://com.example.project:200/folder/subfolder/etc이다.

<data android:scheme=”something” android:host=”project.example.com” />

<data android:host="string"

android:mimeType="string"

android:path="string"

android:pathPattern="string"

android:pathPrefix="string"

android:port="string"

android:scheme="string" />

<data android:scheme=”something” /><data android:host=”project.example.com” /> 동일하다.

android:host  URI authority의 host영역이다. scheme가 없으면 이 애트리뷰트는 의미가 없다.호스트 이름은 항상 소문자로 지정해야 한다.

android:mimType  image/jpeg 또는 audio/mpeg4-generic과 같은 MIME 미디어 타입이다. 하위타입에 대해 와일드카드(*)를 사용할수 있으면 항상 소문자를 사용해서 지정해야 한다.

android:path

android:pathPrefix

android:pathPattern  URI authority의 path영역이다. path 애트리뷰트는 인텐트 오브젝트 내의 전체 path와 일치하는 path를 지정한다. pathPrefix 애트리뷰트는 인텐트 오브젝트 내 path의 첫 머리만 일치하는 부분적인 path를 지정한다. pathPattern 애트리뷰트는 인텐트 오브젝트 내의 전체 path와 일치하는 path를 지정하지만 다음과 같은 와일드카드를 포함할 수 있다. 첫째로 별표(*)는 바로 앞에 나오는 문자가 0번 이상 발생하는 것을 나타내고 둘째로는 마침표 뒤에 별표가 나오는 것(.*)은 어떤 문자든 0번 이상 발생하는 것을 나타낸다.

XML에서 \은 이스케이프 문자로써 사용된다.

scheme와 host 애트리뷰트가 필터에 없으면 이 애트리뷰트는 의미가 없다.

android:port - URI authority의 port영역이다. scheme와 host 애트리뷰트가 지정될 때에만 의미를 같는다.

android:scheme  URI authority의 scheme영역이다. Scheme이 없다면 나머지 애트리뷰트는 의미가 없다. 스키마는 항상 소문자를 사용해야 한다.

 

<meta-data>

데이터에 대한 정의나 설명이다. 컴포넌트 엘리먼트는 <meta-data> 서브엘리먼트를 포함할 수 있다. <meta-data>의 모든 값은 하나의 Bundle로 모아지고 PackageItemInfo.metaData 필드로써 컴포넌트에서 사용할 수 있다.

<meta-data android:name="string"

android:resource="resource specification"

android:value="string" />

android:name  아이템에 대한 고유한 이름이다. 예를들어 com.example.project.activity.fred처럼 Java 스타일 naming 규약을 사용해야 한다.

android:resource  리소스에 대한 레퍼런스 이다. ID는 Bundle.getInt() 메쏘드에 의해 meta-data Bundle로부터 얻을수 있다.

android:value  아이템에 할당된 값이다. 아래는 값으로 할당 할수 있는 데이터 타입과 값을 얻기 위해 사용하는 메쏘드들이다.

타입

Bundle 메쏘드

유니코드 문자를 위한 \\n  \\uxxxxx 같은 스케이프(escape) 캐릭터에 더블 백슬래시(\\) 사용하는 문자열 

getString()

100같은 정수(integer) 

getInt()

(true) 또는 거짓(false)  하나인 boolean 

getBoolean()

#rgb,#argb,#rrggbb 또는 #aarrggbb형식의 컬러 

getString()

1.23 같은 부동소수점 

getFloat()

 

<activity-alias>

<activity-alias android:enabled=["true" | "false"]

android:exported=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:name="string"

android:permission="string"

android:targetActivity="string" >

. . .

</activity-alias>

<activity> 타겟으로 지정해 그 타겟과 다른 속성으로 <activity>를 호출한다. targetActivity는 같은 <application>안에 있어야 하고 <activity-alias>보다 먼저 선언 되어 있어야 한다. targetActivity는 Activity-alias의 부모 엘리먼트이고 activity-alias는 targetActivity의 애트리뷰트를 따르지만 activity-alias안에 같은 애트리뷰트가 선언되면 activity-alias 애트리뷰트 값을 따른다.

android:exported  다른 애플리케이션의 컴포넌트들이 이 앨리어스를 통해 타겟 액티비티를 런치할 수 있는지를 설정한다. 런치할 수 있다면 true이다. 인텐트 필터가 없으면 디폴트 값은 false이고 인텐트 필터가 있다면 디폴트 값은 true이다.

android:name  앨리어스의 이름을 지정한다. 이름은 전체 클래스 이름과 비슷해야 하고 실제 클래스 이름을 참조하지 않는다.

android:permission  이것이 설정된다면 targetActivity 퍼미션을 대체한다. 설정이 되지 않는다면 앨리어스를 통해 타겟을 활성화 하기 위한 퍼미션은 필요하지 않다.

android:targetActivity  앨리어스를 통해 활성화 될 수 있는 액티비티의 이름을 지정한다.

 

<service>

<service android:enabled=["true" | "false"]

android:exported=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:name="string"

android:permission="string"

android:process="string" >

. . .

</service>

각 서비스마다 <service>태그가 필요하다. 서비스는 백그라운드 오퍼레이션이나 다른 애플리케이션이 호출 할 수 있는 커뮤니케이션 API를 구현하기 위해 사용된다.

android:icon  서비스 아이콘은 이곳에서 설정하던 <application>엘리먼트에서 설정하던 모든 서비스의 인텐트 필터에 대한 디폴트 아이콘이다.

android:label  서비스 아이콘은 이곳에서 설정하던 <application>엘리먼트에서 설정하던 모든 서비스의 인텐트 필터에 대한 디폴트 라벨이다.

android:name  서비스를 구현하는 Service 서브클래스의 이름이다.com.example.project.RoomService 처럼 전체 클래스 이름이어야 한다. 하지만 .RoomService와 같이 단축형 이름이라면 <manifest>엘리먼트에 지정된 패키지 이름 끝에 붙여진다.

android:permission  서비스를 런치하거나 바인드를 하 위해 가져야 하는 퍼미션 이름이다. 만약 startsService(), bindService(), stopService()의 호출자가 이 퍼미션을 부여받지 않는다면 이 메쏘느는 작동하지 않으며 인턴트 오브젝트는 서비스에 전달되지 않는다. 이 퍼미션을 설정하지 않으면 <application>퍼미션이 적용되고 <application>퍼미션이 없다면 퍼미션이 적용되지 않는다.

 

<receiver>

<receiver android:enabled=["true" | "false"]

android:exported=["true" | "false"]

android:icon="drawable resource"

android:label="string resource"

android:name="string"

android:permission="string"

android:process="string" >

. . .

</receiver>

어플리케이션이 브로드캐스트 메시지를 수신할수 있도록 한다. 브로드캐스트 리시버는 애플리케이션의 다른 컴포넌트들이 실행되지 않아도 다른 애플리케이션 또는 시스템에 의해 브로드캐스트 되는 인텐트를 받기 위해 애플리케이션을 활성화 한다.

시스템에게 브로드캐스트 리시버를 알기기 위한 방법으로는 이 엘리먼트를 가지고 매니페스트 파일 안에 선언하는 것과 코드 안에서 동적으로 리시버를 만들어서 Context.registerReceiver() 메쏘드를 사용해서 등록한다.

android:exported  브로드캐스트 리시버가 다른 애플리케이션 소스로부터 메시지를 받을수 있는지를 설정한다. 받을수 있으면 true이고 아니면 false이다. 인텐트 필터가 없으면 디폴트 값은 false이고 인텐트 필터가 있다면 디폴트 값은 true이다.

 

<provider>

<provider android:authorities="list"

android:enabled=["true" | "false"]

android:exported=["true" | "false"]

android:grantUriPermissions=["true" | "false"]

android:icon="drawable resource"

android:initOrder="integer"

android:label="string resource"

android:multiprocess=["true" | "false"]

android:name="string"

android:permission="string"

android:process="string"

android:readPermission="string"

android:syncable=["true" | "false"]

android:writePermission="string" >

. . .

</provider>

애플리케이션의 일부가 되는 모든 컨텐트 프로바이더를 선언해야 한다. 컨텐트 프로바이더 서브클래스에 대한 이름은 URI authority이다.

android:authorities  데이터를 구분하는 URI authority 목록이다. Authority가 여러 개이면 세미콜론(;)으로 이름을 구분한다. 최소한 하나의 authority가 지정되어야 한다.

android:grantUriPermissions  일시적으로 radPermission, writePermission, 데이터 접근 할수 있게 하려면 ture로 설정하거나 <grant-uri-permission>서브엘리먼트를 정의함으로써 이 기능을 활성화 한다. 퍼미션을 설정하지 않으려면  false로 한다.

android:initOrder  컨텐트 프로바이더가 인스턴스화되어야 하는 순서를 설정한다. 높은 숫자들이 먼저 초기화 된다.

android:permission  클라이언트가 컨텐트 프로바이더의 데이터를 읽거나 쓰기 위해 가져야 하는 퍼미션의 이름이다. 이 애트리뷰트는 읽기와 쓰기 모두에게 하나의 퍼미션을 설정한다. 하지만 readPermission과 writePermission 애트리뷰트가 이것보다 우선순위이다.

android:readPermission  클라이언트가 컨텐트 프로바이더에 쿼리하기 위해 가져야 하는 퍼미션이다.

android:syncable  컨텐트 프로바이더의 제어하에 있는 데이터가 서버 상의 데이터와 동기화되어져야 한다면 true 아니면 false이다.

android:writePermission  클라이언트가 컨텐트 프로바이더에 의해 제어되는 데이터를 변경하기 위해 가져야 하는 퍼미션이다.

 

<uses-library>

<uses-permission android:name="string" />

어플리케이션에 링크 되어야 하는 외부 라이브러리를 지정한다.

android:name  라이브러리 이름




디폴트 값

Element

Atrribute

디폴트 값

<instrumentation>

android:functionalTest

false

 

android:handleProfiling

false

<uses-sdk>

android:minSdkVersion

1

 

android:maxSdkVersion

없음

<supports-screens>

android:smallScreens

true(API Level 7 기준)

 

android:normalScreens

true(API Level 7 기준)

 

android:largeScreens

true(API Level 7 기준)

 

android:anyDensity

true(API Level 7 기준)

<application>

android:allowClearUserData

 

 

android:allowTaskReparenting

false

 

android:debuggable

false

 

android:enable

true

 

android:hasCode

true

 

android:persistent

false

 

android:process

<manifest>엘리먼트의 package 이름

 

android:taskAffinity

<manifest>엘리먼트의 package 이름

<activity>

android:alwaysRetainTaskState

false

 

android:clearTskOnLaunch

false

 

android:enabled

true

 

android:excludeFromRecents

false

 

android:exported

Intent 필터가 없다면 false

Intent 필터가 있다면 true

 

android:finishOnTaskLaunch

false

 

android:launchMode

standard

 

android:multiprocess

false

 

android:noHistory

false

 

android:permission

<application>엘리먼트의 퍼미션

<application>퍼미션이 없다면 퍼미션에 의해 보호 되지 않음

 

android:process

애플리케이션의 패키지 이름

 

android:stateNotNeeded

false

 

android:taskAffinity

어플리케이션의 친화력을 상속.

어플리케이션의 디폴트 친화력 이름은<manifest>엘리먼트의 패키지 이름이다.

 

android:theme

<application>테마

<application>테마가 없다면 시스템 테마

 

android:windowSoftInputMode

소프트 키보드 stateUnspecified

메인 윈도우 adjustUnspecified

<intent-filter>

android:label

부모 컴포넌트에 설정된 라벨

부모가 라벨을 설정하지 않으면<application>라벨

<activity-alias>

android:enabled

true

 

android:exported

인텐트 필터가 없으면 false

인텐트 필터가 있으면 true

 

android:permission

targetActivity의 퍼미션

targetActivity의 퍼미션이 없다면 퍼미션에 의해 보호되지 않음

<service>

android:enabled

true

 

android:exported

인텐트 필터가 없으면 false

인텐트 필터가 있으면 true

 

android:permission

<application>엘리먼트의 퍼미션

<application>퍼미션이 없다면 퍼미션에 의해 보호되지 않음

<receiver>

android:enabled

true

 

android:exported

인텐트 필터가 없으면 false

인텐트 필터가 있으면 true

 

android:permission

<application>엘리먼트의 퍼미션

<application>퍼미션이 없다면 퍼미션에 의해 보호되지 않음

<provider>

android:enabled

true

 

android:exported

인텐트 필터가 없으면 false

인텐트 필터가 있으면 true

 

android:multiprocess

false

 

android:process

<application>엘리먼트의 프로세스





출처: 
http://nuninaya.tistory.com/556
RSS :
Response
앱을 만들다 보면 인텐트를 통해 단순히 String, int, boolean 같은 기본 타입 뿐 아니고 커스텀 클래스나 오브젝트를 다른 컴포넌트에 전달해 줘야 할 경우가 많다. 그 경우 단순히 그냥 인텐트에 putExtra() 로는  넣어줄 수가 없다.
안드로이드에서는 그런 경우를 위해 자바의 Serialization 개념과 유사한 Parcelable이라는 클래스가 있다.

먼저 이런것이 왜 필요한가 살펴보겠다. 예를 들어 다음과 같은 클래스가 있다고 하자.

public class BookData {
  int _id;
  String title;
  String author;
  String publisher;
  int price;
}

도서관리 앱에서 ListView로 화면에 표시하기 위해 ArrayList<BookData>에 책들의 정보를 넣어 인텐트로 넘겨주려고 하면 BookData 클래스를 그대로 사용할수는 없다. 

오브젝트를 Parcelable 클래스로 만들어 주려면 android.os.Parcelable 인터페이스를 구현해야 한다. 그러므로 아래와 같이 클래스 정의를 변경한다.

public class BookData implements Parcelable {
  int _id;
  String title;
  String author;
  String publisher;
  int price;
}

그리고 android.os.Parcelable 인터페이스에 있는 2개의 메소드를 오버라이드 해 줘야만 한다. 

describeContents() - Parcel 하려는 오브젝트의 종류를 정의한다. 
writeToParcel(Parcel dest, int flags) - 실제 오브젝트 serialization/flattening을 하는 메소드. 오브젝트의 각 엘리먼트를 각각 parcel해줘야 한다.

public void writeToParcel(Parcel dest, int flags) {
  dest.writeInt(_id);
  dest.writeString(title);
  dest.writeString(author);
  dest.writeString(publisher);
  dest.writeInt(price);
}

다음으로 해야 할 일은 Parcel에서 데이터를 un-marshal/de-serialize하는 단계를 추가해줘야 한다. 그러기 위해서 Parcelable.Creator 타입의 CREATOR라는 변수를 정의해야 한다. 이 변수를 정의하지 않으면 안드로이드는 다음과 같은 익셉션을 발생한다.

Parcelable protocol requires a Parcelable.Creator object called CREATOR

아래는 위의 예제인 BookData 클래스를 위한 Parcelable.Creator<BookData>의 코드이다.

public class CustomCreator implements Parcelable.Creator<BookData> {
  public BookData createFromParcel(Parcel src) {
    return new BookData(src);
  }

  public BookData[] newArray(int size) {
    return new BookData[size];
  }
}

BookData.java에 모든 parcel된 데이터를 복구하는 생성자를 정의해 줘야만 한다.

  public BookData(Parcel src) {
    _id = src.readInt();
    title = src.readString();
    author = src.readString();
    publisher = src.readString();
    price = src.readInt();
  }

주의할것은 writeToParcel() 메소드에서 기록한 순서와 동일하게 복구해야만 한다.

전체 코드는 다음과 같다.

...
public class BookData implements Parcelable {
    private String title;
    private String author;
    private String publisher;
    private String isbn;
    private String description;
    private int price;
    private String photoUrl;
   
    public BookData() {
    }
   
    public BookData(Parcel in) {
       readFromParcel(in);
    }

    public BookData(String _title, String _author, String _pub, String _isbn, String _desc, int _price, String _photoUrl) {
         this.title = _title;
         this.author = _author;
         this.publisher = _pub;
         this.isbn = _isbn;
         this.description = _desc;
         this.price = _price;
         this.photoUrl = _photoUrl;
    }

// -------------------------------------------------------------------------
// Getters & Setters section - 각 필드에 대한 get/set 메소드들
// 여기서는 생략했음

// ....
// ....
// -------------------------------------------------------------------------
   

   public void writeToParcel(Parcel dest, int flags) {
           dest.writeString(title);
           dest.writeString(author);
           dest.writeString(publisher);
           dest.writeString(isbn);
           dest.writeString(description);
           dest.writeString(photoUrl);
           dest.writeInt(price);
   }

   private void readFromParcel(Parcel in){
           title = in.readString();
           author = in.readString();
           publisher = in.readString();
           isbn = in.readString();
           description = in.readString();
           photoUrl = in.readString();
           price = in.readInt();
   }
   
   public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public BookData createFromParcel(Parcel in) {
             return new BookData(in);
       }

       public BookData[] newArray(int size) {
            return new BookData[size];
       }
   };
}

Parcelable 오브젝트를 인텐트로 보내는 경우는 다음과 같이 하면 된다.

BookData book = new BookData();
// 각 필드에 값을 넣어줌

Intent i = new Intent(this, ShowBook.class);
i.putExtra("bookInfo", book);
startActivity(i);

인텐트를 받을 ShowBook.java에서는 다음과 같이 Parcelable 오브젝트를 복구하면 된다.

Bundle bundle = getIntent().getExtras();
BookData book = bundle.getParcelable("bookInfo");

ArrayList<BookData>인 경우는 Intent를 만들어 보내는 쪽에서는 다음과 같이 하면 된다.

ArrayList<BookData> bookList = new ArrayList<BookData>();
...
// bookList.add() 메소드를 사용해서 bookList에 BookData 엔트리를 추가
...

Intent i = new Intent(this, BookList.class);
i.putParcelableArrayListExtra("myBooks", bookList);
startActivity(i);

BookList.java (인텐트에 의해 호출되는 액티비티)에서는 다음과 같이 오브젝트를 복구하면 된다.

ArrayList<BookData> bookList;
...
Intent i = getIntent();
bookList = i.getParcelableArrayListExtra("myBooks");

출처 : 
http://arsviator.blogspot.com/2010/10/parcelable%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%9C-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%EC%A0%84%EB%8B%AC-object.html


RSS :
Response

SQLite

출처 : http://blog.naver.com/crowdark7/109969054


SQLite

A. SQLite의 사용

B. Query

C. 자료의 표현(CursorAdapter)

 

 

 

A. SQLite의 사용

 

SQLite

 데이터베이스는 어플리케이션이 자료를 다룬다면 중요한 요소입니다. 임베디드에 내장되는 소프트웨어 역시 DB를 가지고 있습니다. SQLite는 이러한 DB를 관리하는 DB엔진으로 2000년 리처드 힙 박사에 의해 개발된 무료 엔진입니다.

 안드로이드에서는 데이터를 저장하는 장소가 웹이 아닌 파일이 될 가능성이 큽니다. 그러므로 원하는대로 복사, 삭제, 이동할 수 있습니다.

 

SQLite 관련 클래스

 SQLite는 따로 GUI툴을 제공하지 않습니다. 편하게 테이블을 만들거나 할 수 없고 SQL문을 사용해야 합니다. 그래서 안드로이드에서는 DB를 관리할 수 있는, 그리고 SQLite를 편하게 쓸 수 있는 클래스를 제공합니다.

 

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

인수

설명

context

DB를 생성하는 컨텍스트입니다. 보통 메인 액티비티를 전달하게 됩니다.

name

DB 파일의 이름입니다.

factory

커스텀 커서를 사용할 때 지정하는데 null을 사용하게 되면 표준 커서를 사용합니다.

version

DB의 버전입니다.

* 커서는 후에 설명하겠습니다.

 

SQLiteOpenHelper의 주요 메서드

이 클래스에서는 DB를 생성하거나 읽을 때에 다음의 메서드들을 호출합니다.

메서드

호출시기

설명

onCreate

처음 DB생성 시

테이블을 만들고 초기 설정과 레코드들을 삽입합니다.

onUpgrade

DB를 업그레이드 시

기존의 테이블을 변형시키거나 새로 만들게 되는 작업을 수행합니다.

onOpen

DB를 열 때

파일이 존재한다면 이 메서드가 호출됩니다.

 

DB를 쓰거나 읽기 위해서는 다음의 메서드를 이용합니다.

메서드

설명

getReadableDatabase

읽기 전용으로 DB를 이용합니다.

getWritableDatabase

읽고 쓰기를 위해 DB를 이용합니다.

close

DB를 닫는 것으로 위 두 작업 이후 해주어야 합니다.

만약 DB파일이 없다면 파일을 생성한 후에 자동으로 onCreate를 호출하게 될 것입니다.

버전이 바뀐 경우는 onUpgrade를 호출하겠지요. 이 메서드들을 이용하면 DB를 열고 객체를 리턴받을 수 있습니다.

 

 

B. Query

 

DB를 가져왔다면 이를 사용해야 합니다.

안드로이드에서는 메서드를 이용해서 DB를 다룰 수도 있지만 직접 쿼리문을 사용해서 DB를 다룰 수도 있습니다.

메서드를 이용하는 것보다 쿼리문을 그대로 사용하는 게 더욱 편합니다.

그렇다면 이런 DB의 사용에 관해서 알아봅시다.

 

DB 가져오기

먼저 DB에 기록하거나 DB를 읽기 위해서는 앞서 본 메서드로 DB를 가져와야 합니다.

 

SQLiteDatabase db객체 = SQLiteHelper클래스.getWritableDatabase();

SQLiteHelper클래스의 경우는 SQLiteHelper를 상속해서 DB를 관리하기 위한 클래스를 하나 만들어줘야 합니다.

SQLiteHelper는 추상클래스 이기 때문에 위의 onCreate, onUpgrade, onOpen을 구현해야 하기 때문입니다.

 

데이터 맵 준비

 

DB를 불러왔으니 기록할 데이터를 작성합니다.

데이터는 기본적으로 키 값과 내용물로 구성됩니다. 그리고 이 데이터를 저장하기 위해서는 맵(Map)이 필요합니다.

이 맵을 생성시키는 생성자는 다음과 같습니다.

생성자

설명

ContentValues()

비어있는 디폴트 크기의 맵을 생성합니다.

ContentValues(int size)

size 만큼의 크기를 가진 맵을 생성합니다.

ContentValues(ContentValuse from)

인수로 받은 ContentValues의 복사본을 생성합니다.

 

맵에 데이터를 넣는 메서드는 put메서드를 사용합니다. 모든 타입에 오버로드 되어 있으므로 필드의 타입에 맞는 것을 사용하면 됩니다.

void put(String key, 데이터의 타입 value)

 

사용 예

ContentValues data = new ContentValues();

data.put(“key1”, “데이터1 입니다”);

data.put(“key2”, “데이터2 입니다”);

 

DB에 데이터 삽입

 

메서드를 이용한 삽입

long SQLiteDatabase.insert(String table, String nullColumnHack, ContentValues values)

인수

설명

table

DB Table의 이름을 말합니다.

nullColumnHack

DB에서는 완전히 비어있는 행을 삽입하는 것을 허용하지 않습니다. 대신 비어있다는 것을 표현하기 위해서 NULL을 쓰게 됩니다. 그래서 만약 NULL이 들어가야 할 곳에 들어가게 될 것을 말합니다.

values

생성해 놓은 데이터 맵을 말합니다.

 

쿼리를 이용한 삽입

void execSQL(String sql)

sql 인수는 SQL문이 들어가게 됩니다. SQL문은 삽입의 경우는 다음과 같습니다.

execSQL(“INSERT INTO 테이블 명 VALUES (데이터);”);

 

DB의 데이터 삭제

메서드를 이용한 삭제

조건에 맞는 데이터만을 삭제했다면 0, 모든 데이터를 삭제했다면 1을 리턴합니다.

int delete(String table, String whereClause, String[] whereArgs)

인수

설명

table

DB Table의 이름을 말합니다.

whereClause

조건항으로 해당 조건에 맞는 항을 삭제하라는 뜻입니다. null을 넣게 되면 모든 행을 삭제합니다.

whereArgs

조건을 규정하는 argument입니다.

 

쿼리를 이용한 삭제

void execSQL(String sql)

SQL문은 삭제의 경우는 다음과 같습니다.

execSQL(“DELETE FROM 테이블 명 WHERE 조건;”);

 

DB의 데이터 갱신

메서드를 이용한 갱신

 

int update(String table, ContentValues values, String whereClause, String[] whereArgs)

인수

설명

table

DB Table의 이름을 말합니다.

values

갱신 내용을 말합니다.

whereClause

조건항으로 해당 조건에 맞는 항을 삭제하라는 뜻입니다. null을 넣게 되면 모든 행을 삭제합니다.

whereArgs

조건을 규정하는 argument입니다.

 

쿼리를 이용한 갱신

void execSQL(String sql)

SQL문은 삭제의 경우는 다음과 같습니다.

execSQL(“UPDATE 테이블 명 SET 갱신 내용 WHERE 조건;”);

 

DB의 데이터 검색

메서드를 이용한 검색

엄청나게 인수가 많지만 대부분 null이 될 가능성이 큽니다.

Cursor query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

인수

설명

distinct

검색되는 행 중에서 중복되는 내용은 제거하고 출력합니다. null을 지정하면 모두 출력합니다. 이 행을 제외하고도 쓸 수 있습니다.

table

DB Table의 이름을 말합니다.

columns

보여줄 열을 지정합니다. null을 지정하면 모든 열을 보여줍니다.

selection

어떤 행을 검색할지 정합니다. WHERE에 해당하는 내용으로 null을 지정하면 모든 행을 출력합니다.

selectionArgs

 

groupBy

GROUP BY에 해당하는 내용으로 특정 속성을 기준으로 그룹을 지어 출력합니다. 설명이 힘들기 때문에 SQL문을 참조하시기 바랍니다. null을 지정하면 그룹을 만들지 않습니다.

having

GROUP BY에서 조건을 정하는 부분입니다. 해당 속성 기준으로 조건에 만족하는 것만 출력합니다.

orderBy

ORDER BY에 해당하는 내용으로 행을 어느 속성 기준으로 정렬시킬지 정합니다. null의 경우 정렬시키지 않습니다.

limit

LIMIT에 해당하는 내용으로 출력 행의 수를 제한합니다.

 

쿼리를 이용한 검색

void execSQL(String sql)

SQL문은 검색의 경우는 다음과 같습니다.

execSQL(“SELECT 속성 FROM 테이블 명 WHERE 조건

GROUP BY 속성 HAVING 조건 ORDER BY 속성 LIMIT 행의 수”);

 

SQLite 이용 예제

public class EnglishWord extends Activity {

                  WordDBHelper mHelper;

                  EditText mText;

                  public void onCreate(Bundle savedInstanceState) {

                                   super.onCreate(savedInstanceState);

                                   setContentView(R.layout.data_englishword);

 

                                   mHelper = new WordDBHelper(this);

                                   mText = (EditText)findViewById(R.id.edittext);

 

                                   findViewById(R.id.insert).setOnClickListener(mClickListener);

                                   findViewById(R.id.delete).setOnClickListener(mClickListener);

                                   findViewById(R.id.update).setOnClickListener(mClickListener);

                                   findViewById(R.id.select).setOnClickListener(mClickListener);

                  }

                 

                  Button.OnClickListener mClickListener = new View.OnClickListener() {

                                   public void onClick(View v) {

                                                     SQLiteDatabase db;

                                                     ContentValues row;

                                                     switch (v.getId()) {

                                                     case R.id.insert:

                                                                       db = mHelper.getWritableDatabase();

                                                                       // insert 메서드로 삽입

                                                                       row = new ContentValues();

                                                                       row.put("eng", "boy");

                                                                       row.put("han", "머스마");

                                                                       db.insert("dic", null, row);

                                                                       // SQL 명령으로 삽입

                                                                       db.execSQL("INSERT INTO dic VALUES (null, 'girl', '가시나');");

                                                                       mHelper.close();

                                                                       mText.setText("Insert Success");

                                                                       break;

                                                     case R.id.delete:

                                                                       db = mHelper.getWritableDatabase();

                                                                       // delete 메서드로 삭제

                                                                       db.delete("dic", null, null);

                                                                       // SQL 명령으로 삭제

                                                                       //db.execSQL("DELETE FROM dic;");

                                                                       mHelper.close();

                                                                       mText.setText("Delete Success");

                                                                       break;

                                                     case R.id.update:

                                                                       db = mHelper.getWritableDatabase();

                                                                       // update 메서드로 갱신

                                                                       row = new ContentValues();

                                                                       row.put("han", "소년");

                                                                       db.update("dic", row, "eng = 'boy'", null);

                                                                       // SQL 명령으로 갱신

                                                                       //db.execSQL("UPDATE dic SET han = '소년' WHERE eng = 'boy';");

                                                                       mHelper.close();

                                                                       mText.setText("Update Success");

                                                                       break;

                                                     case R.id.select:

                                                                       db = mHelper.getReadableDatabase();

                                                                       Cursor cursor;

                                                                       // query 메서드로 읽기

                                                                       //cursor = db.query("dic", new String[] {"eng", "han"}, null,

                                                                       //                                null, null, null, null);

                                                                       // SQL 명령으로 읽기

                                                                       cursor = db.rawQuery("SELECT eng, han FROM dic", null);

                                                    

                                                                       String Result = "";

                                                                       while (cursor.moveToNext()) {

                                                                                        String eng = cursor.getString(0);

                                                                                        String han = cursor.getString(1);

                                                                                        Result += (eng + " = " + han + "\n");

                                                                       }

 

                                                                       if (Result.length() == 0) {

                                                                                        mText.setText("Empyt Set");

                                                                       } else {

                                                                                        mText.setText(Result);

                                                                       }

                                                                       cursor.close();

                                                                       mHelper.close();

                                                                       break;

                                                     }

                                   }

                  };

}

 

class WordDBHelper extends SQLiteOpenHelper {

                  public WordDBHelper(Context context) {

                                   super(context, "EngWord.db", null, 1);

                  }

 

                  public void onCreate(SQLiteDatabase db) {

                                   db.execSQL("CREATE TABLE dic ( _id INTEGER PRIMARY KEY AUTOINCREMENT, " +

                                   "eng TEXT, han TEXT);");

                  }

 

                  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

                                   db.execSQL("DROP TABLE IF EXISTS dic");

                                   onCreate(db);

                  }

}

 

 

C. 자료의 표현(CursorAdapter)

 

커서(Cursor)

앞서 보면 종종 커서에 대한 얘기가 나옵니다. 일반적인 커서의 뜻은 위치를 가리키는 곳이라는 뜻입니다.

안드로이드에서는 결과 셋의 위치를 가리키는 포인터라고 이해하면 됩니다. 커서를 이용하면 대단히 많은 양이라고 할지라도 위치를 가리키는 특성 때문에 부하가 높지 않습니다.

 

커서를 이용해 쿼리 읽기

검색을 한 경우 리턴되는 커서는 가장 처음 레코드의 앞을 가리킵니다. 이후에 moveToNext를 이용하여 첫 레코드부터 차례로 다 읽을 수 있습니다. 보통 while문을 사용합니다.

while(cursor.moveToNext()){ … }

 

어댑터를 이용한 출력

커서를 어댑터에 바인딩해 놓으면 어댑텨 뷰로 출력할 수가 있습니다. 커서를 사용하는 어댑터는 아래와 같습니다.

SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)

인수

설명

context

컨텍스트를 의미합니다. 보통 메인 액티비티가 됩니다.

layout

커서를 출력할 레이아웃을 말합니다.

c

검색한 데이터의 원본인 커서를 말합니다.

from

열 이름을 배열로 지정합니다.

to

각 열이 어느 위젯으로 출력될지 위젯의 ID를 지정합니다.

 

커서 어댑터 사용 예제

 

public class ProductList extends Activity {

                  ProductDBHelper mHelper;

                  public void onCreate(Bundle savedInstanceState) {

                                   super.onCreate(savedInstanceState);

                                   setContentView(R.layout.data_productlist);

                                  

                                   mHelper = new ProductDBHelper(this);

                                   Cursor cursor;

                                   SQLiteDatabase db = mHelper.getWritableDatabase();

 

                                   cursor = db.rawQuery("SELECT * FROM product", null);

                                   startManagingCursor(cursor);

 

                                   SimpleCursorAdapter Adapter = null;

                                   Adapter = new SimpleCursorAdapter(this,

                                                                       android.R.layout.simple_list_item_2,

                                                                       cursor, new String[] { "name", "price" },

                                                                       new int[] { android.R.id.text1, android.R.id.text2});

                                   ListView list = (ListView)findViewById(R.id.list);

        list.setAdapter(Adapter);

                  }

}

 

class ProductDBHelper extends SQLiteOpenHelper {

                  public ProductDBHelper(Context context) {

                                   super(context, "Product.db", null, 1);

                  }

 

                  public void onCreate(SQLiteDatabase db) {

                                   db.execSQL("CREATE TABLE product ( _id INTEGER PRIMARY KEY AUTOINCREMENT, " +

                                                     "name TEXT, price INTEGER);");

                                   db.execSQL("INSERT INTO product VALUES (null, '오징어 땅콩', 900);");

                                   db.execSQL("INSERT INTO product VALUES (null, '농심 포테이토 칩', 2000);");

                                   db.execSQL("INSERT INTO product VALUES (null, '로보트 태권 V', 1000);");

                                   db.execSQL("INSERT INTO product VALUES (null, '꼬마 자동차 붕붕', 1500);");

                                   db.execSQL("INSERT INTO product VALUES (null, '윈도우즈 API 정복', 32000);");

                                   db.execSQL("INSERT INTO product VALUES (null, '롯데 인벤스 아파트', 190000000);");

                                   db.execSQL("INSERT INTO product VALUES (null, '88 라이트', 1900);");

                                   db.execSQL("INSERT INTO product VALUES (null, '프라이드 1.6 CVVT 골드', 8900000);");

                                   db.execSQL("INSERT INTO product VALUES (null, '캐리비안 베이 입장권', 25000);");

                  }

 

                  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

                                   db.execSQL("DROP TABLE IF EXISTS product");

                                   onCreate(db);

                  }

}

 

* 포스트의 내용은 김상형 저, "안드로이드 프로그래밍 정복"의 내용을 참고하였습니다.

 

출처 : http://blog.naver.com/crowdark7/109969054


RSS :
Response

Intent 존재여부 확인하기

Android는 Intent라고 불리는 아주 강력하지만 사용하기 편리한 Message Type을 제공한다. Intent를 사용함으로써 Applications을 고수준의 라이브러리로 바꾸어 코드의 모듈화 및 재사용을 가능하게 한다. 예를 들어, Android Home Screen과 응용프로그램의 단축 버튼들은 단축키를 생성하는데 Intents를 광범위하게 사용하고 있다.

느슨하게 결합되어 있는 API를 사용하는 것이 좋은 반면 사용자가 보내는 Intent가 다른 Application에 의해 받아지는 것에 대한 확신은 가질 수 없다. 이러한 현상은 Panoramio(위치정보를 제공하는 App)와 그것의 RADRA Intent와 같이 3rd-party Apps에서 특히 일어난다.

이번 Article은 여러분이 사용하고 싶어하는 Intent를 처리할 수 있는 어떤 Application을 시스템이 포함하고 있는지를 알아볼 수 있는 Technique을 기술하게 된다. 아래의 예제는 시스템 Package Manager에게 어떤 App이 특정 Intent에 응답할 수 있는지의 여부를 결정하도록 요청하는 Helper Method를 보여준다. 여러분의 응용프로그램은 해당 Method로 Intent를 보낼 수 있고, 예를 들자면 그런 다음에 해당 Intent를 보낼 수 있는 사용자 Options을 숨기거나 보여줄 수 있다.

/** 
* Indicates whether the specified action can be used as an intent. This 
* method queries the package manager for installed packages that can 
* respond to an intent with the specified action. If no suitable package is 
* found, this method returns false. 

* @param context The application's environment. 
* @param action The Intent action to check for availability. 

* @return True if an Intent with the specified action can be sent and 
*         responded to, false otherwise. 
*/
public static boolean isIntentAvailable(Context context, String action) {
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List<ResolveInfo> list =
            packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

다음에는 그러한 Helper Method를 어떻게 사용할 수 있는지를 보여준다.
@Overridepublic boolean onPrepareOptionsMenu(Menu menu) {
    final boolean scanAvailable = isIntentAvailable(this, "com.google.zxing.client.android.SCAN");
    MenuItem item;
    item = menu.findItem(R.id.menu_item_add);
    item.setEnabled(scanAvailable);
    return super.onPrepareOptionsMenu(menu);
}

이러한 예제에서, Barcode Scanner Application이 설치되어 있지 않다면 Menu는 비활성화 처리된다.

좀더 간단하게 startActivity()를 호출했을 때 ActivityNotFoundException을 캐치하도록 하는 또다른 방법이 있지만 그러한 문제발생에 반응만 할 수 있다. 즉, 여러분은 그러한 것을 예측할 수 없고 동작하지 않기를 바라는 무언가를 차단하는 것에 따라 UI를 업데이트할 수 없다는 것이다. 또한 여기에 기술된 방법은 설치 되지않은 패키지를 설치하고자 하는지를 사용자에게 Startup time시에 묻는데 사용될 수 있다. 그런 다음, 적당한 URI를 사용하여 사용자를 Android Market으로 간단하게 안내할 수 있게 된다.


RSS :
Response

RelativeLayout 사용하기

2. RelativeLayout

RelativeLayout은 위젯의 위치를 상대 위젯/ 컨테이너를 기준으로 결정하는 방법이다.

첫 번째로, 부모 컨테이너 내부에서 위젯 자신의 위치를 결정하는 속성은 다음과 같다.


위의 속성들은 모두 true, false 값을 입력 받는다.

 두 번째로, 상대 위젯/컨테이너를 기준으로 배치 시 사용하는 속성은 다음과 같다.


마지막 android:layout_alignBaseline는 label과 EditText등의 Text기반 위젯의 글자 높이를 맞추는데 유용하게 쓰임.

위의 모든 attribute들은 기준이 되는 상대 위젯/컨테이너의 id를 값으로 지정하여야 한다.

 

기준이 되는 상대 위젯의 id는 "@id/위젯id"로 결정한다.

예를들어, 위젯 A 가 android:id="@+id/A"로 identiy되어있다면XML 내부에서 위젯 A는 "@id/A"로 불린다.

그럼으로 위젯 B를 위젯 A 오른쪽에 위치 하게 하고 싶다면 위젯 B의 alignment 속성을 다음과 같이 지정한다.

<위젯 A

......

android:id="@+id/A" />

<위젯 B

......

android:layout_alignRightOf="@id/A" />

 

이 경우 위젯 A, B는 다음과 같은 형태로 배치 된다.

 

  RelativeLayout에서 주의할 두 가지 점은:

  • XML Layout 파일은 위에서 아래로 순차적으로 한번 파싱됨으로 XML 문서상 밑에 위치한 위젯의 id를 위에 위치한 위젯이 참고하는 것은 불가능 하다. (아직 선언되지 않은 변수를 참조 할 수 없는 것과 같다.)
  • 모든 fill 관련 속성은 자신 이외의 위젯이 사용하고 남은 스페이스에만 적용됨.

  

RelativeLayout 예제 (main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:padding="5px" >

	<!-- XML layout은 위에서 부터 밑으로 parsing 됨으로  -->
	<!-- 다음의 TextView내부에서 아직 선언되지 않은   -->
	<!-- EditText나 Button들의 id(@id/edittext, @id/ok, @id/cancel)를 사용할 수 없음  -->
	<TextView
		android:id="@+id/label"  
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content" 
		android:text="URL" 
		android:paddingTop="15px"
		android:paddingRight="10px" />

	<!-- 다음의 EditText(edittext)의 layout_width="fill_parent"는 -->
	<!-- 위 TextView(lable)가 사용하고 남은 공간을 채움 -->
	<EditText
		android:id="@+id/edittext"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/label"
		android:layout_alignBaseline="@id/label"
		android:text="http://tigerwoods.tistory.com" />
	<Button
		android:id="@+id/ok"
		android:layout_width="80px"
		android:layout_height="wrap_content"
		android:layout_alignRight="@id/edittext"
		android:layout_below="@id/edittext"
		android:text="OK" />
	<Button
		android:id="@+id/cancel"
		android:layout_width="80px"
		android:layout_height="wrap_content"
		android:layout_toLeftOf="@id/ok"
		android:layout_below="@id/edittext"
		android:text="Cancel" />
</RelativeLayout>

 

실행결과는 다음과 같다.



RelativeLayout의 완전한 API Reference는 다음의 링크를 참조.

RelativeLayout API Reference 링크



출처 : http://tigerwoods.tistory.com/11

RSS :
Response