350 likes | 630 Views
모바일멀티미디어프로그래밍. 4 장 . 인텐트와 브로드캐스트 리시버 4.1. 인텐트 4.2. 인텐트 필터 4.3. 브로드캐스트 리시버. 4.1.1 명시적 인텐트와 암시적 인텐트. Intent 라는 단어의 사전적인 의미는 “의향 , 목적 , 의도” 로 안드로이드에서는 의도가 적절한 의미라고 할 수 있다 . 인텐트는 어떤 동작의 의도를 나타내는데 일종의 메시징 시스템이다 . “의도”라는 것은 예를 들어 , “전화를 건다” , “문자를 보낸다”와 같은 것이다 .
E N D
모바일멀티미디어프로그래밍 4장. 인텐트와브로드캐스트 리시버4.1. 인텐트4.2. 인텐트 필터4.3. 브로드캐스트 리시버
4.1.1 명시적 인텐트와 암시적 인텐트 • Intent라는 단어의 사전적인 의미는 “의향, 목적, 의도”로안드로이드에서는 의도가적절한 의미라고 할 수 있다. • 인텐트는 어떤 동작의 의도를 나타내는데 일종의 메시징 시스템이다. • “의도”라는 것은 예를 들어, “전화를 건다”, “문자를 보낸다”와 같은 것이다. • 또한, 인텐트는 부가적인 정보를 담는다는 것에서 편지와 비슷하며 안드로이드는 컴포넌트(액티비티, 서비스, 브로드캐스트 리시버)들 사이에 인텐트를 이용해서 메시지를 주고 받는다
4.1.1 명시적 인텐트와 암시적 인텐트 • res/layout/intent_test.xml • <?xml version="1.0" encoding="utf-8"?> • <LinearLayout • xmlns:android="http://schemas.android.com/apk/res/android" • android:orientation="vertical" • android:layout_width="match_parent" • android:layout_height="match_parent"> • <Button • android:text="Explicit Intent" • android:onClick="onClickExplicitIntent" • android:layout_width="wrap_content" • android:layout_height="wrap_content" /> • <Button • android:text="Implicit Intent (ACTION_DIAL)" • android:onClick="onClickImplicitIntent" • android:layout_width="wrap_content" • android:layout_height="wrap_content" /> 인텐트는 어떤 동작의 의도를 나타내는데 일종의 메시징 시스템이다.
4.1.1 명시적 인텐트와 암시적 인텐트 res/layout/intent_test.xml <Button android:text="Intent with Extras" android:onClick="onClickIntentWithExtra" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:text="Intent with Result" android:onClick="onClickIntentWithResult" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:text="Intent with Extras and Result" android:onClick="onClickIntentWithExtraAndResult" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
4.1.1 명시적 인텐트와 암시적 인텐트 src/androidbook/ch04/IntentTestActivity.java package androidbook.ch04; import androidbook.ch04.R; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class IntentTestActivity extends Activity { private static final int REQUEST_CODE_1 = 101; private static final int REQUEST_CODE_2 = 102; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intent_test); } public void onClickExplicitIntent(View v) { Intent intent = new Intent(this, TargetActivity.class);·································································· (1) startActivity(intent); }
4.1.1 명시적 인텐트와 암시적 인텐트 TargetActivity액티비티를 생성하여 아래의 코드를 추가하자. src/androidbook/ch04/TargetActivity.java package androidbook.ch04; import android.app.Activity; import android.os.Bundle; import android.view.View; import androidbook.ch04.R; public class TargetActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.target); } public void onClickBackToPrevious(View v) { onBackPressed(); } }
4.1.1 명시적 인텐트와 암시적 인텐트 src/androidbook/ch04/IntentTestActivity.java package androidbook.ch04; import androidbook.ch04.R; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class IntentTestActivity extends Activity { private static final int REQUEST_CODE_1 = 101; private static final int REQUEST_CODE_2 = 102; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intent_test); } public void onClickExplicitIntent(View v) { Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); } public void onClickImplicitIntent(View v) { Uri number = Uri.parse("tel:01012345678");······················································································· (1) Intent dial = new Intent(Intent.ACTION_DIAL, number); startActivity(dial); } }
4.1.2 인텐트를 통해 값 전달하기 • 인텐트는메시징 시스템이라고 했다. 그러면, 단순히 액티비티를 전환하는 것 뿐만 아니라 데이터를 전달하는 방법도 있어야 할 것이다. • 다음 그림은 IntentTestActivity액티비티에서WithExtraActivity액티비티로데이터를 전달하는 방법이다.
4.1.2 인텐트를 통해 값 전달하기 IntentTestActivity를 위와 같이 수정해 보자. src/androidbook/ch04/IntentTestActivity.java package androidbook.ch04; import androidbook.ch04.R; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class IntentTestActivity extends Activity { private static final int REQUEST_CODE_1 = 101; private static final int REQUEST_CODE_2 = 102; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intent_test); }
4.1.2 인텐트를 통해 값 전달하기 public void onClickExplicitIntent(View v) { Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); } public void onClickImplicitIntent(View v) { Uri number = Uri.parse("tel:01012345678"); Intent dial = new Intent(Intent.ACTION_DIAL, number); startActivity(dial); } public void onClickIntentWithExtra(View v) { Intent intent = new Intent(this, WithExtraActivity.class); intent.putExtra("name", "Bob"); intent.putExtra("age", 21); startActivity(intent); } }
4.1.2 인텐트를 통해 값 전달하기 src/androidbook/ch04/WithExtraActivity.java package androidbook.ch04; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; public class WithExtraActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.with_extra); Intent intent = getIntent(); String name = intent.getStringExtra("name"); int age = intent.getIntExtra("age", 0); TextViewnameTextView = (TextView) findViewById(R.id.name); TextViewageTextView = (TextView) findViewById(R.id.age); nameTextView.setText("name=" + name); ageTextView.setText("age=" + age); } }
4.1.3 인텐트로 값 리턴하기 • 인텐트는 이와 같이 호출할 때 값을 전달하는 데에도 사용되지만, • 값을 리턴하는 데에도 사용된다. • 호출하고 리턴하는 것은 함수와 비슷하다.
4.1.3 인텐트로 값 리턴하기 src/androidbook/ch04/IntentTestActivity.java package androidbook.ch04; import androidbook.ch04.R; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class IntentTestActivity extends Activity { private static final int REQUEST_CODE_1 = 101; private static final int REQUEST_CODE_2 = 102; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intent_test); } public void onClickExplicitIntent(View v) { Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); }
4.1.3 인텐트로 값 리턴하기 public void onClickImplicitIntent(View v) { Uri number = Uri.parse("tel:01012345678"); Intent dial = new Intent(Intent.ACTION_DIAL, number); startActivity(dial); } public void onClickIntentWithExtra(View v) { Intent intent = new Intent(this, WithExtraActivity.class); intent.putExtra("name", "Bob"); intent.putExtra("age", 21); startActivity(intent); } public void onClickIntentWithResult(View v) { Intent intent = new Intent(this, WithResultActivity.class); startActivityForResult(intent, REQUEST_CODE_1); }
4.1.3 인텐트로 값 리턴하기 @Override protected void onActivityResult(intrequestCode, intresultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK){ if (requestCode == REQUEST_CODE_1) { intresultInt = data.getIntExtra("result", 0); Toast.makeText(this, "RESULT=" + resultInt, Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "Canceled", Toast.LENGTH_SHORT).show(); } } } 이렇게 startActivityForResult메소드를 사용하면 호출당한 액티비티에서 설정한 리턴값을 받을 수 있다. startActivity메소드로 호출하면 호출 당한 액티비티에서리턴값을 설정하더라도 결과가 호출했던 액티비티로 전달되지 않는다.
4.1.3 인텐트로 값 리턴하기 src/androidbook/ch04/WithResultActivity.java package androidbook.ch04; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class WithResultActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.with_result); } public void onClickOk(View v) { Intent intent = new Intent(); intent.putExtra("result", 12345); setResult(Activity.RESULT_OK, intent); finish(); } public void onClickCancel(View v) { setResult(Activity.RESULT_CANCELED); finish(); } }
4.1.3 인텐트로 값 리턴하기 res/layout/with_result.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:text="Ok" android:onClick="onClickOk" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:text="Cancel" android:onClick="onClickCancel" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> onClickOk메소드의 코드를 보면 인텐트를 생성하는 것을 볼 수 있다. 이와 같이 인텐트를 생성하고, 호출할 때 하던 방법과 마찬가지로 putExtra메소드를 사용해서 전달할 데이터를 넣는다.
4.1.3 인텐트로 값 리턴하기 src/androidbook/ch04/IntentTestActivity.java package androidbook.ch04; import androidbook.ch04.R; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class IntentTestActivity extends Activity { private static final int REQUEST_CODE_1 = 101; private static final int REQUEST_CODE_2 = 102; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intent_test); }
4.1.3 인텐트로 값 리턴하기 public void onClickExplicitIntent(View v) { Intent intent = new Intent(this, TargetActivity.class); startActivity(intent); } public void onClickImplicitIntent(View v) { Uri number = Uri.parse("tel:01012345678"); Intent dial = new Intent(Intent.ACTION_DIAL, number); startActivity(dial); } public void onClickIntentWithExtra(View v) { Intent intent = new Intent(this, WithExtraActivity.class); intent.putExtra("name", "Bob"); intent.putExtra("age", 21); startActivity(intent); } public void onClickIntentWithResult(View v) { Intent intent = new Intent(this, WithResultActivity.class); startActivityForResult(intent, REQUEST_CODE_1); }
4.1.3 인텐트로 값 리턴하기 public void onClickIntentWithExtraAndResult(View v) { Intent intent = new Intent(this, WithExtraAndResultActivity.class); intent.putExtra("name", "John"); intent.putExtra("age", 23); startActivityForResult(intent, REQUEST_CODE_2); } @Override protected void onActivityResult(intrequestCode, intresultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK){ if (requestCode == REQUEST_CODE_1) { intresultInt = data.getIntExtra("result", 0); Toast.makeText(this, "RESULT=" + resultInt, Toast.LENGTH_SHORT).show(); } else if (requestCode == REQUEST_CODE_2) { String resultString = data.getStringExtra("result"); Toast.makeText(this, "RESULT=" + resultString, Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "Canceled", Toast.LENGTH_SHORT).show(); } } }
4.1.3 인텐트로 값 리턴하기 src/androidbook/ch04/WithExtraAndResultActivity.java package androidbook.ch04; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; public class WithExtraAndResultActivity extends Activity { private TextViewmNameTextView; private TextViewmAgeTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.with_extra_and_result); String name = getIntent().getStringExtra("name"); int age = getIntent().getIntExtra("age", 0); mNameTextView = (TextView) findViewById(R.id.name); mAgeTextView = (TextView) findViewById(R.id.age); mNameTextView.setText(name); mAgeTextView.setText(Integer.toString(age)); }
4.1.3 인텐트로 값 리턴하기 public void onClickOk(View v) { String result = mNameTextView.getText().toString() + "/" + mAgeTextView.getText().toString(); Intent intent = new Intent(); intent.putExtra("result", result); setResult(Activity.RESULT_OK, intent); finish(); } public void onClickCancel(View v) { setResult(Activity.RESULT_CANCELED); finish(); } }
4.1.3 인텐트로 값 리턴하기 res/layout/with_extra_and_result.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/name" android:text="name" android:padding="10dip" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/age" android:text="age" android:padding="10dip" android:layout_width="wrap_content" android:layout_height="wrap_content" />
4.1.3 인텐트로 값 리턴하기 <Button android:text="Ok" android:onClick="onClickOk" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:text="Cancel" android:onClick="onClickCancel" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 인텐트를 생성해서 “name”에 “John”을 넘겨주고, “age”에 23을 넘겨준다. 그 후에 WithExtraAndResultActivity 클래스에서 넘겨받은 데이터를 텍스트 뷰에 표시한다. 그 후에 [Ok] 버튼을 누르면 인텐트를 생성해서 두 문자열을 합한 것을 리턴해주게 된다.
4.2.1 인텐트 필터 • 이클립스에서 앞서 사용했던 프로젝트를 열어 INtent.ACTION_DIAL의 위치에 마우스를 위치하면 풍선 도움말이 나타난다.
4.2.1 인텐트 필터 • 안드로이드는아이폰과 다르게 여러 가지 애플리케이션이 서로 상호작용하면서 동작할 수 있도록 설계되었다. • 개발자가 직접 홈 화면을 만들어서 기존의 홈 화면 대신 사용하거나 전화거는 애플리케이션을 새로 만들어서 기존의 전화 애플리케이션 대신 사용할 수도 있다. • 이러한 것들을 모두 가능하게 하는 것이 암시적 인텐트와인텐트 필터의 조합이다.
4.2.1 인텐트 필터 AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="androidbook.ch04" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".IntentTestActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".TargetActivity" /> <activity android:name=".WithExtraActivity" /> <activity android:name=".WithResultActivity" /> <activity android:name=".WithExtraAndResultActivity" /> </application> <uses-sdkandroid:minSdkVersion="8" /> </manifest>
4.2.2 액션과 카테고리 인텐트 필터를 정의할 때에 주로 필터링하는 항목은 action, data, category 세 가지이다. 1) Action : 서비스되는 액션의 이름이다. 액션은 유일한 문자열이어야 하므로 “android.Intent.action.DIAL”과 같은 식으로 자바 패키지 네이밍 규약을 따른다. 2) Category : 액션이 서비스되어야 하는 상황을 지정한다. 여러 개의 카테고리가 가능하다. 3) data : 실행할 수 있는 데이터에 대한 명세이다. 여러 개의 데이터 지정이 가능하며 MIME 타입이나 호스트 이름,포트 이름, URI에 대한 경로, 스킴(예: http) 등을 사용한다.
4.2.3 인텐트레졸루션 • 인텐트URI 실행시 실행할 수 있는 액티비티가 여러 개 존재하면 • 그 중에 가장 적합한 것이 실행되는데, 이것을 인텐트레졸루션이라고 한다. • 설치된 패키지로부터 사용 가능한 모든 인텐트 필터의 목록을 구성한다. • 그 중에서 action이나 category에 맞지 않는 것은 제외하고 필터의 data부분이 정의되어 있으면 비교한다. • 이 과정에서 우선 순위가 매겨지고, 가장 높은 순위의 컴포넌트가 선택된다.
4.3 브로드캐스트 리시버 • 인텐트 필터는 전화를 거는 동작을 했을 때 해당 기능이 있는 애플리케이션 • 컴포넌트(액티비티, 서비스 등) 중에서 선택하는 창이 뜨게 된다. • 하지만, 배터리가 별로 남지 않아 다른 모든 애플리케이션에게 메시지를 • 보내야 할 때에는 적절하지 않다. • 이렇게 한 가지 메시지를 모든 애플리케이션에 보내는 것이 브로드캐스트(Broadcast)이고, 이 메시지를 처리하는 것이 브로드캐스트 리시버(BroadcastReceiver)이다.
4.3 브로드캐스트 리시버 브로드캐스트를 처리하기 위해서는 AndroidManifest.xml에 리시버의 이름을 등록해야 한다. AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="androidbook.ch04" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".IntentTestActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".TargetActivity" /> <activity android:name=".WithExtraActivity" /> <activity android:name=".WithResultActivity" /> <activity android:name=".WithExtraAndResultActivity" /> <receiver android:name=".BroadcastReceiverSample" android:enabled="true"> <intent-filter> <action android:name="androidbook.ch04.action.BROADCAST_TEST“> </action> </intent-filter> </receiver> </application> <uses-sdkandroid:minSdkVersion="8" /> </manifest>
4.3 브로드캐스트 리시버 BroadcastReceiverSample액티비티를 생성하여 아래의 코드를 추가해 보자. src/androidbook/ch04/BroadcastReceiverSample.java package androidbook.ch04; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class BroadcastReceiverSample extends BroadcastReceiver { public static final String ACTION = "androidbook.ch04.action.BROADCAST_TEST"; @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ACTION)) { Toast.makeText(context, "Broadcast Test", Toast.LENGTH_SHORT).show(); } } }
4.3 브로드캐스트 리시버 AndroidManifest.xml, main.xml과 MainActivity액티비티를 열어 아래와 같이 코드를 추가한다. [ch04_2] AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android” Package="androidbook.ch04_2" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <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> </application> <uses-sdkandroid:minSdkVersion="9" /> </manifest>
4.3 브로드캐스트 리시버 [ch04_2] res/layout/main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClickBroadcastTest" android:text="Broadcast Test"/> </LinearLayout>
4.3 브로드캐스트 리시버 [ch04_2] src/androidbook/ch04_2/MainActivity.java package androidbook.ch04_2; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void onClickBroadcastTest(View v) { Intent intent = new Intent(); intent.setAction("androidbook.ch04.action.BROADCAST_TEST"); sendBroadcast(intent); } }