달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

'Android 이야기'에 해당되는 글 8

  1. 2010.04.08 '10.04.09 Story
2010. 4. 8. 22:45

'10.04.09 Story Android 이야기2010. 4. 8. 22:45

인텐트 리시버

액티비티가 아닌 다른 컴포넌트에 인텐트를 전달해야 할 수도 있다.

- 특정 시스템 이벤트가 발생하면 액티비티가 아닌 지정된 서비스를 실행시켜야 하는 경우

- 특정 이벤트가 발생했을 때 인텐트뿐만 아니라 다른 정보를 함께 참조해 상황에 맞는 액티비티를 실행시켜야 하는 경우. 예를 들어, 인텐트 X가 발생했을 때, 데이터베이스에 Y라는 값이 있다면 액티비티 M을 실행하고, Y라는 값이 없다면 액티비티 N을 실행해야 하는 상황을 쉽게 생각해볼 수 있다.

 

이런 경우에 대비할 수 있도록 안드로이드는 BroadcastReceiver라는 리시버 인터페이스를 정의하고 있는데, 인텐트 리시버는 인텐트, 특히 브로드캐스트된 인텐트를 받아 처리하도록 구성되어 있다. 일반적으로 인텐트를 받은 다음 다른 인텐트를 발생시켜 다른 액티비티나 서비스 등의 컴포넌트를 실행시키려는 경우에 인텐트 리시버를 많이 사용.

BroadcastReceiver에는 onReceiver(0라는 하나의 메소드만 정의돼있다. 인텐트 리시버는 인텐트를 받았을 EO 처리하는 기능을 모두 onReceive()메소드를 구현해야 한다.

인텐트 리시버를 정의하려면 AndroidManifest.xml 파일에 다음과 같은 receiver 엘리먼트를 추가한다.

<receiver android:name = ".MyIntentReceiverClassName"/>

 

인텐트 리시버는 onReceive()메소드를 호출하는 순간만 인스턴스로 생성되었다가 사라진다. 다시 말해 onReceive() 메소드가 완료되는 즉시 가비지 컬렉션 대상이 되며 재사용 할 수 없다.

 

실행

인텐트 작성

new Intent(this, HelpActivity.class)'

위 코드로 생성한 인텐트는 명확하게 HelpActivity를 실행하겠다는 의미이다.

HelpActivity는 AndroidManifest.xml 파일에 정의돼있어야 하고, 대신 직접 실행할 예정이기 때문에 다로 인텐트 필터를 지정할 필요는 없다. 아니면 같이 Uri를 지정해 작업 자체를 요청할 수 도 있다.

 

Uri uri = Uri.parse("geo"+lat.toString()+","+lon.toString());

Intent I = new Intent(Intent.ACTION_VIEW,uri);

 

여기서는 lat변수와 lon변수에 Double형태로 각각 위도와 경도값이 들어있다고 해보자. 그러면 위와 같이 geo스키마를 사용하는 Uri를 생성해 ACTION_VIEW 액션과 함계 인텐트를 생성한다.

 

실행

실행시키는 방법은 4가지 방법이 있다.

가장 간단한 방법은 startActivity()메소드에 Intent를 넘겨주는 방법이다. 그러면 안드로이드는 Intent와 가장 잘 맞아떨이즌 액티비티를 찾아 실행시키고 해당 Intent를 전달한다.

startActivityForResult() 메소드에 Intent와 숫자 하나를 넘겨준다. 안드로이드는 Intent와 가장 잘 맞아떨어지는 액티비티를 하위 액티비티로 실행하고 해당 Intent를 전달한다. 그리고 실행된 액티비티가 종료되면 onActivityResult() 메소드가 호출된다.

넘겨진 액티비티 -> 처리 -> 호출한 액티비티의 onActivityResult()메소드 실행

 

sendBroadcast()메소드를 사용한다. 그러면 안드로이드는 등록된 모든 BroadcastReceiver가운데 해당 Intent를 처리할 수 있는 모든 BroadcastReceiver에 Intent를 전달한다. 앞의 두 가지 방법은 가장 많이 맞아 떨어지는 액티비티 하나만 실행하지만, 이 방법은 여러 개의 액티비티를 실행시키기도 한다.

 

sendOrderedBroadcast() 메소드를 사용한다. 그러면 안드로이드는 해당 Intent를 처리할 수 있는 모든 액티비티를 차례대로 실행한다. 만약 특정 액티비티에서 Intent를 사용해버렸다면 그 이후에 다른 액티비티는 실행하지 않는다.

 

앞의 두가지를 제일 많이 사용. startActivity() startActivityForResult() 메소드를 많이 사용

 

startActivityForResult() 메소드를 사용할 때 onActivityForResult() 메소드만를 구현해두면 서브 액티비티의 작업이 RMxskT을 때 작업 결과를 넘겨 받을 수 있다.

 

대상 액티비티 찾기

안드로이드는 특정 항목에 대한 Uri를 어떻게 처리하는지 전혀 알지 못하는 상황에서 해당 Uri를 처리할 수 있다고 생각되는 여러 개의 액티비티를 화면에 표시해주고 사용자가 선택할 수 있게 도와준다.

 

액티비티 선택

간혹 특정 Uri를 처리할 수 있는 애플리케이션이 무엇인지 사용자가 쉽게 알 수 있는 경우도 있다. 예를 들어, content :// contacts/people 이라는 Uri는 안드로이드에 내장된 주소록에 기록돼있는 사람의 목록을 의미한다.

위와 같이 동작하게 하려면 먼저 해당 Uri와 ACTION_PICK 액션을 지정한 Intent를 생성하고, startActivityForResult()메소드로 하위 액티비티를 실행한다.

 

버튼을 클릭(xml파일에 버튼 엘리먼트에 android:text = "content://contracts/people" 속성이 지정되어 있다)하면 ACTION_PICK 액션과 사용자가 입력한 Uri를 지정해 새로운 Intent를 만들고, 그에 해당하는 하위 액티비티를 실행한다. 하위 액티비티가 종료되고 RESULT_OK 결과 코드를 넘겨받으면, 결과로 받은 Uri를 대상으로 ACTION_VIEW 인텐트가 실행된다.

 

컨텐트 프로바이더

안드로이드 시스템에서 content://로 시작하는 모든 Uri는 컨텥느 프로바이더를 통해 제공디는 데이터를 의미한다. 다시 말하자면 컨텐트 프로바이더는 Uri의 인스턴스가 가리키는 특정 데이터를 제공할 수 있게 준비된 프로그램이다. 따라서 Uri가 가리키는 데이터를 사용하는 프로그램은 실제 데이터가 어디에 djEJs 방법으로 저장되는지는 알 수 없고, 알아야 할 필요도 없다. 데이터는 컨텐트 프로바이더 내부의 SQLite 데이터베이스에 저장됐을 수도 있고, 아니면 일반 파일 형태로 저장되었을 수도 있고, 인ㅌ넷을 통해 언격지 서버에서 가져올수도 있다. Uri를 컨텐트 프로바이더에 전달하면 기본적인 CRUD 연산을 처리할 수 있다. 데이터 집합을 가리키는 Uri라면 추가 연산을 사용해 데이터를 새로 집어넣을 수 있다. 특정 개별 항목을 가리키는 Uri라면 데이터 내용을 읽거나 변경, 삭제할 수 있다.

 

Uri 구성

Uri를 구성하는 요소로는 스키마, 데이터의 네임스페이스 ,그리고 필요한 경우 인스턴스 ID를 포함한다.

content://constants/5 라는 Uri는 ID값이 5번인 상수값을 의미한다.

Uri는 content://contacts/people

안드로이드 SDK 내부에 정의된 대부분의 API는 Uri클래스로 Uri를 표현하지만, 일반적으로 하나의 문자열로 간주해도 큰 무리는 없다. 또한 Uri.parse()메소드를 사용하면 문자열로 표현된 Uri를 Uri클래스의 인스턴스로 변환해준다.

 

Uri생성

Uri인스턴스는 어디에서 만들어지는 건가!!

작업에 사용할 데이터 형태를 알고 있는 경우라면 프로그램 코드가 직접 컨텐트 프로바이더로부터 Uri인스턴스를 받아오는 방법이 가장 일반적이다.

 

쿼리 실행

일단 Uri를 혹보하면 해당하는 컨텐트 프로바이더를 대상으로 Uri데이터를 꺼내달라고 쿼리를 실행할 수 있다. 컨텐트 프로바이더에 대한 쿼리는 가져올 컬럼이나 행을 지정하거나, 데이터의 정렬 순서 등을 지정할 수 있다는 점에서 SQL의 쿼리와 비슷한 부분이 많다.

액티비티에 내장된 managedQuery()메소드를 사용해 Uri데이터를 쿼리할 수 있다.

managedQuery() 메소드에는 다음과 같이 다섯 개의 인자가 필요하다.

1. 쿼리할 컨텐트 프로바이더의 기본 Uri, 또는 개별 항목의 Uri

2. 컨텐트 프로바이더가 갖고 있는 항목별 속성 가운데 쿼리 결과로 받아오려는 속성의 배열

3. SQL의 Where문과 유사한 조건 지정 부분

4. 세 번째 조건 부분에 ? 표시된 부분 대신 대치시켜 넣을 값이 들어 있는 배열

5. SQL의 Order by 문과 유사한 정렬 방법 지정 부분

 

리턴 값은 Cursor 인스턴스로 넘겨 받는다.

 

컨텐트 프로바이더에서 ‘속성’이라고 하는 부분은 데이터베이스에서 컬럼과 같은 의미이다.

다시 말해 Cursor를 통해 가져온 각 건의 데이터는 데이터베이스의 한 행을 뜻하며, 한 건의 데이터 안에는 여러 개의 속성이 들어 있다.

constantsCursor = managedQuery(Provider.Constants.CONTENT_URI, PROJECTION, null, null, null)

 

private static final String[] PROJECTION = new String[]{

Provider.COnstants._ID, Provider.Constants.TITLE, Provider.Constants.VALUE};

컨텐트 프로바이더의 데이터에서 어떤 속성을 사용할 수 있는지에 대해서는 컨텐트 프로바이더 자체 문서에 자세히 설명해야 한다. 컨텐트 프로바이더를 구현한 Provider클래스에 상수로 _ID, TITLE, VALUE와 같이 속성 이름을 정의해두었다.

 

데이터 자동 적용

managedQuery()를 실행하면 Cursor인스턴스를 받아오며, Cursor인스턴스를 사용하면 쿼링에 대한 결과를 자유자재로 다룰 수 있다. 예를 들어 Cursor에서 뽑아낸 데이터를 사용에 화면에 위젯을 배치하거나 다른 클래스의 인스턴스를 생성해 사용할 수도 있다.

SimpleCursorAdapter 라는 클래스는 Cursor 인스턴스가 갖고 있는 내용을 ListView나 Spinner와 같은 선택 위젯에 표현할 수 있게 만들어져 있다.

 

constantsCursor = managedQuery(Provider.Constants.CONTENT_URI,PROJECTION,null,null,null);

ListAdapter adapter = new SimpleCursorAdapter(this,R.layout.row,

new String[] {Provider.Constants.TITLE,Provider.Constants.VALUE},

new int[] {R.id.title, R.id.value});

setListAdapter(adapter);

registerForContextMenu(getListView());

 

managedQuery()를 실행해 받아온 Cursor를 constantsCursor변수에 설정하고, SimpleCursorAdapter를 생성한다. SimpleCursorAdapter를 생성 할 때 사용한 값은 다음과 같다.

어댑터를 생성하는 액티비티. 여기서는 this를 사용해 스스로의 인스턴스를 사용

목록 항목을 표시하는데 사용할 레이아웃의 ID

Cursor 인스턴스

커서에서 뽑아내 목록의항목 하나를 만드는데 사용할 속성의 이름 배열

커서에서 뽑아낸 값을 넣을 항목별 레이아웃의 위젯 ID 배열

'Android 이야기' 카테고리의 다른 글

Android App 만들엇당 ㅋ  (0) 2010.09.01
'10.04.06 Story  (0) 2010.04.06
'10.04.05 story 안드로이드 2주차 과제  (0) 2010.04.05
'10.04.05 Story  (0) 2010.04.05
'10.04.04 Story  (0) 2010.04.05
:
Posted by НooпeУ


Code Start Code End