CHAPTER 11 액티비티 간 정보전달

1. 액티비티개요

  • 액티비티(Activity)는 안드로이드폰에 나타나는 화면 하나하나를 말함
  • .java가 액티비티에 해당됨
  • 일반적으로 Activity하나 당 XML파일 하나를 만들어 사용

2. 인텐트

  • 인텐트(Intent)는 안드로이드 4대 컴포넌트가 상호 간에 data를 주고 받기 위한 메시지 객체
참고) 안드로이드 4대 컴포넌트

액티비티(Activity), 서비스(Service), 브로드캐스트 리시버(Broadcast Receiver), 컨텐트 프로바이더(Content Provider)

1) Service
눈에 보이는 화면(Activity)와 상관없이 백그라운드에서 동작하는 컴포넌트

2) Baordcast Receiver
문자메시지 도착, 배터리방전, 네트워크 환경 변화 등이 발생하면 전체 응용 프로그램이 들을 수 있도록 방송(Broadcasting) 신호를 보냄
Baordcast Receiver는 이런 방송 신호가 발생하면 반응함

3) Content Provider
응용 프로그램 사이에서 데이터를 상호 공유하기 위한 컴포넌트
정보를 제공하는 방법으로 URI(Uniform Resource Identifier)가 있음

h2.

  • 명시적 인텐트와 암시적 인텐트로 구분
  • 명시적 인텐트 : 다른 액티비티의 이름을 명확이 지정할 때 사용하는 방법

Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
startActivity(intent);

  • 암시적 인텐트 : 약속된 Action을 지정하여 안드로이드에서 제공하는 기존 응용 프로그램을 실행하는 것
구분소스AndroidMahnifest.xml 권한 추가
전화걸기Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:119"));
startActivity(intent);
<uses-permission android:name="android.permission.CALL_PHONE"/>
홈페이지열기Uri uri = Uri.parse("http://www.naver.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
구글 맵 열기Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:"));
startActivity(intent);
구글검색하기Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtre(SearchManager.QUERY, "android");
startActivity(intent);
문자보내기Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("sms_body", "Hi!~");
intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);
<uses-permission android:name="android.permission.WRITE_SMS"/>
사진보기Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(new File("/sdcard/a.jpg"));
intent.setDataAndType(uri, "image/jpeg");
startActivity(intent);

h2.

2.1 실습 11-1 / 새로운 액티비티 추가하기

(main 액티비티에서 second 액티비티로 화면이동)
scenario : 메인 화면의 버튼을 클릭하면 서버 화면이 나오는 응용 프로그램

#1. 화면 디자인 및 편집
main.xml 편집, second.xml 추가

#2. Java코드 작성 및 수정
MainActivity 수정, SecondActivity 추가

#3. AndroidMainfest.xml에 신규 액티비티 등록

h2.

  • 화면 디자인 및 편집

main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
	>
    <Button 
        android:id="@+id/btn1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="새 화면 열기(명시적 intent)"
        />	
    <Button 
        android:id="@+id/btn2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="전화걸기(암시적 intent)"
        />	
</LinearLayout>

second.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:background="#cccccc"
    >
    <Button 
        android:id="@+id/btn1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="돌아가기"
        />	
</LinearLayout>

  • Java코드 작성 및 수정

MainActivity


public class MainActivity extends Activity {

	Button btn1, btn2;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		setTitle("메인 액티비티");
		
		//명시적 INTENT 사용 : 다른 화면으로 이동
		btn1 = (Button)findViewById(R.id.btn1);
		btn1.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				//intent 생성
				Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
				//SecondActivity 화면에 출력
				startActivity(intent);
			}
		});
		
		//암시적 INTENT 사용 : 전화걸기
		btn2 = (Button)findViewById(R.id.btn2);
		btn2.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Uri uri = Uri.parse("tel:119");
				Intent intent = new Intent(Intent.ACTION_DIAL, uri);
				startActivity(intent);
				
			}
		});
		
	}
}

SecondActivity


public class SecondActivity extends Activity {

	Button btn1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second);
		
		setTitle("Second 액티비티");
		
		btn1 = (Button)findViewById(R.id.btn1);
		btn1.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				//activity 종료
				finish();
			}
		});
	}
}

  • AndroidMainfest.xml에 신규 액티비티 등록

AndroidMainfest.xml


<uses-permission android:name="adroid.permission.CALL_PHONE" />

<activity android:name=".SecondActivity" android:label="Second 액티비티">

h2.

  • 데이터 전달
2.2 실습 11-2 / 명화 선호도 투표 앱 만들기

(main 액티비티에서 intent에 data를 실어 넘긴후, second 액티비티에서 받은 data를 처리함)
scenario : 그림에 대한 선호도를 투표하고, 결과를 rating bar로 보여주는 앱

#1. 화면 디자인 및 편집
main.xml 편집, result.xml 추가

첨부) 이미지

^pic1.png, ^pic2.png, ^pic3.png, ^pic4.png, ^pic5.png, ^pic6.png, ^pic7.png, ^pic8.png, ^pic9.png

#2. Java코드 작성 및 수정
MainActivity 수정, ResultActivity 추가

#3. AndroidMainfest.xml에 신규 액티비티 등록

h2.

  • 화면 디자인 및 편집

main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
	android:orientation="vertical"
	>
	
    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="3"
        >
        <ImageView 
            android:id="@+id/iv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:src="@drawable/pic1"
            android:layout_weight="1"
            />
    .................. 
    ..... 3행 3열로 반복

    <Button 
        android:id="@+id/btnResult"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="투표종료"
        />
</LinearLayout>

result.xml


<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical"
    android:stretchColumns="0"
    >
    
    <TableRow >
        <TextView 
            android:id="@+id/tv1"
            android:layout_gravity="center_vertical"
            android:text="그림1"
            android:textSize="15sp"
            />
        <RatingBar 
            android:id="@+id/rbar1"
            style="?android:attr/ratingBarStyleIndicator"
            android:layout_gravity="right"
            />
    </TableRow>
    .................. 
    ..... 8번 반복

    <TableRow >
        <Button 
            android:id="@+id/bntReturn"
            android:layout_span="2"
            android:text="돌아가기"
            />
    </TableRow>
</TableLayout>

  • Java코드 작성 및 수정

MainActivity.java


public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		setTitle("명화 선호토 투표");
		
		//초기값 설정 ------------------------------------------------------
		final int[] voteCount = {0,0,0,0,0,0,0,0,0};
		//ImageView 위젯을 담을 객체선언
		ImageView[] image = new ImageView[9];
		Integer[] imageID = {
			R.id.iv1, R.id.iv2, R.id.iv3, R.id.iv4, R.id.iv5, R.id.iv6, R.id.iv7, R.id.iv8, R.id.iv9
		};
		final String[] imgName = {
			"독서하는 소녀",	
			"꽃장식 모자 소녀",	
			"부채를 든 소녀",	
			"이레느깡 단 베르양",	
			"잠자는 소녀",	
			"테라스의 두 자매",	
			"피아노 레슨",	
			"피아노 앞의 소녀들",	
			"해변에서",	
		};
		//#초기값설정 ------------------------------------------------------
		
		//각 이미지뷰에 ClickListener 정의
		for(int i=0; i < imageID.length; i++) {
			final int idx = i;	//내무 클래스 사용위해 final 선언
			image[i] = (ImageView)findViewById(imageID[i]);
			image[i].setOnClickListener(new View.OnClickListener() {
				
				@Override
				public void onClick(View v) {
					voteCount[idx]++;	//투표수 counting
					//토스트 메시지 출력
					Toast.makeText(getApplicationContext(), imgName[idx] +"총 " + voteCount[idx] + " 표", Toast.LENGTH_SHORT).show();
				}
			});
		}
		
		//버튼에  ClickListener 정의
		Button btnResult = (Button)findViewById(R.id.btnResult);
		btnResult.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//intent 선언
				Intent intent = new Intent(getApplicationContext(), ResultActivity.class);
				//데이터 설정
				intent.putExtra("voteCount", voteCount);
				intent.putExtra("imgName", imgName);
				//ResultAcitivy 화면 출력
				startActivity(intent);
				
			}
		});
		
	}
}

ResultActivity.java


public class ResultActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.result);
		
		setTitle("투표 결과");
		
		//mainActivity에서 전달한 데이터 수령
		Intent intent = getIntent();
		int[] voteResult = intent.getIntArrayExtra("voteCount");
		String[] imageName = intent.getStringArrayExtra("imgName");
		
		//초기값 설정 ------------------------------------------------------
		TextView[] tv = new TextView[imageName.length];
		RatingBar[] rbar = new RatingBar[imageName.length];
		
		Integer[] tvID = {
			R.id.tv1, R.id.tv2, R.id.tv3, R.id.tv4, R.id.tv5, R.id.tv6, R.id.tv7, R.id.tv8, R.id.tv9 
		};
		Integer[] rbarID = {
			R.id.rbar1, R.id.rbar2, R.id.rbar3, R.id.rbar4, R.id.rbar5, R.id.rbar6, R.id.rbar7, 
			R.id.rbar8, R.id.rbar9 
		};
		
		for( int i = 0; i < voteResult.length; i++ ) {
			tv[i] = (TextView)findViewById(tvID[i]);
			rbar[i] = (RatingBar)findViewById(rbarID[i]);
		}
		//#초기값설정 ------------------------------------------------------
		
		//이미지명, 카운트 값 설정
		for( int i = 0; i < voteResult.length; i++ ) {
			tv[i].setText(imageName[i]);
			rbar[i].setRating((float)voteResult[i]);
		}
		
		//버튼에 ClickListener 정의
		Button btnReturn = (Button)findViewById(R.id.bntReturn);
		btnReturn.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
	}
}

  • AndroidMainfest.xml에 신규 액티비티 등록

AndroidMainfest.xml


<activity android:name=".ResultActivity" android:label="Result 액티비티">

h2.

2.3 연습 11-3 / 명화 선호도 투표 앱 만들기 (main.xml을 GridView로 변경해서 프로젝트를 작성)

h2.
h2.
h2.

3. 양방향 액티비티

3.1 실습 11-3 / 계산기

scenario : main activity의 editbox의 두 수를 second activity에서 계산한 후, 다시 main activity로 돌려줌

#1. 화면 디자인 및 편집
main.xml 편집, second.xml 추가

#2. Java코드 작성 및 수정
MainActivity 수정, SecondActivity 추가

#3. AndroidMainfest.xml에 신규 액티비티 등록

h2.

  • 화면 디자인 및 편집

main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
	android:orientation="vertical"
	>
    <EditText 
        android:id="@+id/edtNum1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="number"
        />
    <EditText 
        android:id="@+id/edtNum2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="number"
        />
	
    <RadioGroup 
        android:id="@+id/rdoGroup"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
        <RadioButton 
	        android:id="@+id/add"
	        android:text="더하기"
	        android:checked="true"
            />
        <RadioButton 
	        android:id="@+id/minus"
	        android:text="배기"
            />
        <RadioButton 
	        android:id="@+id/multi"
	        android:text="곱하기"
            />
        <RadioButton 
	        android:id="@+id/division"
	        android:text="나누기"
            />
    </RadioGroup>
    <Button 
        android:id="@+id/btnCalc"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="계산하기"
        />
</LinearLayout>

second.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <Button 
        android:id="@+id/btnBack"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="돌아가기"
        />    
</LinearLayout>

  • Java코드 작성 및 수정

MainActivity.java


public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		setTitle("Main Activity");
		
		Button btnCalc;
		
		//계산하기 버튼에 ClickListener 정의
		btnCalc = (Button)findViewById(R.id.btnCalc);
		btnCalc.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//입력 값
				EditText edtNum1 = (EditText)findViewById(R.id.edtNum1);
				EditText edtNum2 = (EditText)findViewById(R.id.edtNum2);
				//라디오 그룹
				RadioGroup rdoGroup = (RadioGroup)findViewById(R.id.rdoGroup);

				//intent 선언
				Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
				//넘겨줄 데이터 정의
				intent.putExtra("num1", Integer.parseInt(edtNum1.getText().toString()) );
				intent.putExtra("num2", Integer.parseInt(edtNum2.getText().toString()) );
				intent.putExtra("rdoGroup", rdoGroup.getCheckedRadioButtonId() );
				
				//SecondActivity 화면에 출력
				startActivityForResult(intent, 0);
			}
		});
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		//리턴되는 값이 존재
		if(resultCode == RESULT_OK) {
			//리턴값
			double result = data.getDoubleExtra("result", 0);
			Toast.makeText(getApplicationContext(), "합계 : " + result, Toast.LENGTH_SHORT).show();
		}
	}
}

SecondActivity.java


public class SecondActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second);
		
		setTitle("Second Activity");
		
		//넘어온 데이터 정의
		Intent intent = getIntent();
		final int num1 = intent.getIntExtra("num1", 0);
		final int num2 = intent.getIntExtra("num2", 0);
		final Integer rdoGroup = intent.getIntExtra("rdoGroup", 0);
		
		//돌아가기 버튼에 ClickListener정의
		Button btnBack = (Button)findViewById(R.id.btnBack);
		btnBack.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				//계산 유형 
				double result = 0;
				switch( rdoGroup ) {
					case R.id.add:
						result = (double)(num1 + num2);
						break;
					case R.id.minus:
						result = (double)(num1 - num2);
						break;
					case R.id.multi:
						result = (double)(num1 * num2);
						break;
					case R.id.division:
						result = (double)num1 / (double)num2;
						break;
				}
				
				//intent 선언
				Intent intent = new Intent(getApplicationContext(), MainActivity.class);
				intent.putExtra("result", result);
				//setResult()로 mainActivity로 데이터 전달; main의 onActivityResult()가 실행됨
				setResult(RESULT_OK, intent);
				finish();	//현 activity 닫음
			}
		});
	}
}

  • AndroidMainfest.xml에 신규 액티비티 등록

SecondActivity.java


<activity android:name=".SecondActivity" android:label="Second 액티비티">

4. 액티비티 생명주기

참고) LogCat

안드로이드는 android.util.Log 클래스를 제공해서 log를 남기고, LogCat이라는 화면을 제공해서 log를 확인함

메소드설명
android.util.Log.d("태그", "메시지")Debugging
android.util.Log.e("태그", "메시지")Error
android.util.Log.i("태그", "메시지")Information
android.util.Log.v("태그", "메시지")Verbose: 상세한 기록을 남기기 위한 로그
android.util.Log.w("태그", "메시지")Warning

5. Fragment 생명주기