태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

인텐트(Intent) 입문- (2) 액티비티간 데이터 주고받기

2009/03/14 06:52

인텐트를 다루는 두 번째 시간이 돌아왔습니다.  (와우!)
이번 강좌는 저도 인텐트를 쪼~까 공부하느라 뭔가 깔끔하지 못할 지도 모르겠네요(...)
그래도 최대한 자세하게 다뤄보도록 할테니! 걱정은 마시고!! 따라오시면 될겁니다. (아마도요...펑...)

지난 시간에는 다른 액티비티를 단순히 "호출"하는 것만 배웠습니다. 그런데, 실제 어플리케이션을 개발하다보면 액티비티를 호출하는 것은 어찌보면 당연한 것이고, 액티비티간에 데이터를 주고받아야 할 일이 생깁니다. 그럴 땐 어떻게 해야 할까요? => 바로, 이 때도 인텐트를 사용하면 됩니다(...)

인텐트는, 액티비티를 호출하는 수단 뿐 아니라 인텐트 자체에 액티비티간 주고받아야 할 정보들을 실어줄 수 있습니다. 예를 들자면 심부름꾼(???) 이라고 할까나요??

A라는 사람이 B에게 물건을 가져오라고 심부름꾼에게 시키면, 심부름꾼은 B에게 가서 물건을 받아 A에게 전달해주게 됩니다. 마찬가지로, 액티비티 A가 B로부터 어떠한 정보를 받고 싶다면, 인텐트를 사용하여 B를 호출한 다음, 인텐트에 원하는 정보를 실어서 그 정보를 다시 돌려받으면 됩니다.

일단, 호출하는 액티비티 (InformationInput)호출당하는 액티비티(InformationProc)의 코드를 보도록 하겠습니다.


(주의)
액티비티를 추가하는 방법을 모르신다면, 2009/03/01 - [안드로이드/안드로이드 입문] - [강좌] [수정] 이클립스에서 안드로이드 액티비티 추가하기 를 읽고 액티비티 추가 방법에 대해 숙지하신 후 이 강좌를 읽어주세요.


[InformationInput.java]

package com.androidhuman.IntentTest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class InformationInput extends Activity {	
	/** Called when the activity is first created. */
	@Override    public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		final Button requestInfo  = (Button)findViewById(R.id.requestInfo);
		requestInfo.setOnClickListener(new Button.OnClickListener(){ // 버튼을 클릭할 경우
			public void onClick(View v){
				Intent intent = new Intent(InformationInput.this,InformationProc.class);
				startActivityForResult(intent, 1); // Sub_Activity 호출
				}
			});
		}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data){
		super.onActivityResult(requestCode, resultCode, data);
		TextView name_view = (TextView)findViewById(R.id.name_view);
		TextView digit_view = (TextView)findViewById(R.id.digit_view);
		if(resultCode==RESULT_OK) // 액티비티가 정상적으로 종료되었을 경우
			{
			if(requestCode==1) // InformationInput에서 호출한 경우에만 처리합니다.
				{				// 받아온 이름과 전화번호를 InformationInput 액티비티에 표시합니다.
				name_view.setText(data.getStringExtra("data_name"));
				digit_view.setText(data.getStringExtra("data_digit"));
				}
			}
		}
	}


[main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_height="fill_parent" 
android:layout_width="fill_parent" 
android:orientation="vertical" 
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_height="wrap_content" 
android:layout_width="fill_parent" 
android:text="@string/name" />
<TextView android:layout_height="wrap_content" 
   android:layout_width="fill_parent" 
   android:text="-이름이 입력되지 않음-" 
   android:id="@+id/name_view"/>

<TextView android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:text="@string/digit"/>

<TextView android:layout_height="wrap_content" 
   android:layout_width="fill_parent" 
    android:text="-전화번호가 입력되지 않음-" 
    android:id="@+id/digit_view"/>

<Button android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:text="@string/button_launch" 
    android:id="@+id/requestInfo"  
    android:layout_gravity="center_horizontal"/>
</LinearLayout>



[InformationProc.java]

package com.androidhuman.IntentTest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class InformationProc extends Activity {	
	/** Called when the activity is first created. */	
	@Override	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.informationproc);
		Button input_info = (Button)findViewById(R.id.inputinfo);
		input_info.setOnClickListener(new OnClickListener(){
			
		public void onClick(View v) { //버튼을 클릭하면
			Intent intent = getIntent(); // 이 액티비티를 시작하게 한 인텐트를 호출
			EditText name_input = (EditText)findViewById(R.id.name_input);
			EditText digit_input = (EditText)findViewById(R.id.digit_input);
			intent.putExtra("data_name",name_input.getText().toString());
			intent.putExtra("data_digit", digit_input.getText().toString());
			setResult(RESULT_OK,intent); // 추가 정보를 넣은 후 다시 인텐트를 반환합니다.
			finish(); // 액티비티 종료
			}
		});
	}



[informationproc.xml]



 


<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:orientation="vertical" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/overview_layout">

<TextView android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:text="@string/text_information"/>

<LinearLayout android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:orientation="horizontal" 
    android:id="@+id/name_layout">

<TextView android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:text="@string/name"/>

<EditText android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:id="@+id/name_input" 
    android:hint="ex)안드로이드"/>
</LinearLayout>

<LinearLayout android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:orientation="horizontal" 
    android:id="@+id/digit_layout">

<TextView android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:text="@string/digit"/>

<EditText android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:id="@+id/digit_input" 
    android:hint="ex)011-123-4567"/>

</LinearLayout>

<Button android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:text="@string/input" 
    android:id="@+id/inputinfo" 
    android:layout_gravity="center_horizontal"/>
</LinearLayout>


단순히 액티비티를 호출할 때에는 startActivity(Intent)를 사용했었지만, 액티비티를 호출한 후 결과값을 받기 위해서는 다른 메소드를 사용해야 합니다. 바로 startActivityForResult(Intent intent, int requestCode)입니다.


public void startActivityForResult(Intent intent, int requestCode)
호출당하는 액티비티로부터 데이터를 넘겨받기 위해 사용합니다.
intent - 인텐트
requestCode - 이 액티비티를 호출하는 액티비티가 여러 개가 있을 경우, 어떤 액티비티가 호출했는지를 알기 위해 사용


requestCode는 별로 특이한 것은 아니고, 한 액티비티를 여러 액티비티가 호출해야 할 경우, 호출이 어디에서 일어났는지를 알려주는 인자값입니다.
일단, InformationInput 액티비티를 봅시다. 버튼을 클릭하면 InformationInput 액티비티가 InformationProc 액티비티를 호출해야 하므로, 일단 intent를 생성하고, startActivityForResult()를 통해 InformationProc 액티비티를 실행시킵니다.



InformationProc 액티비티가 실행되면, 사용자로부터 이름과 전화번호를 입력받게 됩니다.
입력이 끝나고, 입력 버튼을 누르면, 입력받은 데이터를 인텐트에 집어넣게 됩니다.
Intent intent = getIntent(); // 이 액티비티를 시작하게 한 인텐트를 호출	
     EditText name_input = (EditText)findViewById(R.id.name_input);	
     EditText digit_input = (EditText)findViewById(R.id.digit_input);
     intent.putExtra("data_name",name_input.getText().toString());	
     intent.putExtra("data_digit", digit_input.getText().toString());	
     setResult(RESULT_OK,intent); // 추가 정보를 넣은 후 다시 인텐트를 반환합니다.	
finish(); // 액티비티 종료

차근차근 하나씩 보도록 하겠습니다.
일단, 첫번째, 인텐트를 생성하는 것을 볼 수 있습니다. 보통, 인텐트를 생성할 때 new 생성자를 써서 인텐트를 생성했던 것에 반해, 여기에서는 getIntent()를 사용하여 인텐트를 불러오고 있습니다. getIntent()메소드는 현재 자신을 호출했던 인텐트를 반환해줍니다.

여기서, 자신을 호출한 인텐트를 받아오는 것은, 아까 예로 들었던 심부를꾼을 생각해보면 쉽게 이해할 수 있습니다. A라는 심부름꾼에게서 물건을 받았는데, B라는 심부름꾼에게 물건을 주면 안되겠죠? 인텐트도 마찬가지입니다. :)

이렇게 해서 인텐트를 생성하면, 이제 EditText로부터 입력한 값들을 받아와야 합니다. findViewById()를 이용하여 레이아웃 객체와 코드상의 객체를 연결한 후, putExtra()메소드를 이용해 정보를 실어줍니다.

intent.putExtra(String name, _value)
name이라는 이름을 가지는 데이터를 인텐트에 첨가합니다.

인텐트에 들어가는 데이터는 "키"의 역할을 하는 name과 그에 해당하는 값인 _value가 짝을 이루어 저장됩니다.
이렇게 저장이 되었다면, 호출된 액티비티가 정상적으로 끝났는지, 비정상적으로 끝났는지 (물건을 제데로 받았는지, 심부름꾼이 왔는지 등등...으로 비유할 수 있겠습니다) 자신을 호출한 액티비티에게 알려주기도 해야 하고, 요청한 데이터도 같이 주어야 합니다.

일단, 호출당한 액티비티가 정상적으로 끝났음을 알리기 위해, setResult(RESULT_OK, intent) 메소드를 사용합니다. RESULT_OK로 액티비티가 정상적으로 끝났음을 전달하게 됩니다. RESULT_OK를 반환하지 않고 중간에 비정상적으로 종료되었다면 저 코드를 반환받지 못하므로 뭔가 문제가 있구나 알게 되겠죠? 제데로 종료가 된다면, 아까 우리가 추가로 입력한 데이터를 담은 인텐트도 함께 반환하게 됩니다.

이렇게.. 여기까지 정상적으로 돌아간 후, 호출당한 액티비티(InformationProc)가 finish()메소드에 의해 종료되게 되면, OnActivityResult() 메소드가 호출되게 됩니다. 결과를 기다리고 액티비티를 호출했으니, 액티비티가 종료되었으니 그 결과를 확인해야겠죠??


void onActivityResult(int requestCode, int resultCode, Intent data)
startActivityForResult로 호출한 액티비티가 종료되었을 때 호출됩니다.



protected void onActivityResult(int requestCode, int resultCode, Intent data)
{		super.onActivityResult(requestCode, resultCode, data);
		TextView name_view = (TextView)findViewById(R.id.name_view);
		TextView digit_view = (TextView)findViewById(R.id.digit_view);
		if(resultCode==RESULT_OK) // 액티비티가 정상적으로 종료되었을 경우
		{
			if(requestCode==1) // InformationInput에서 호출한 경우에만 처리합니다.
			{
				// 받아온 이름과 전화번호를 InformationInput 액티비티에 표시합니다.
				name_view.setText(data.getStringExtra("data_name"));
				digit_view.setText(data.getStringExtra("data_digit"));
			}
		}
	}



위의 onActivityResult에서, resultCode가 아까 setResult()에서 액티비티가 정상 종료되었는지를 판단하는 인자값, RESULT_OK를 받게 됩니다. 그래서, 이걸 가지고 적절히 예외 처리를 해 줄 수 있는 거죠.
requestCode는 아까 startActivityForResult()를 호출할 때, InformationInput이 호출한 것임을 표시하기 위해 '1'으로 설정하였으므로, 여기에서 또한 그 코드를 맞춰주어야 제데로 결과값을 받을 수 있습니다.

즉, 정상적으로 액티비티가 종료되었다면 requestCode의 값은 RESULT_OK, resultCode는 1이 됩니다.

이렇게 해서, 모두 정상이라면 인텐트에서 받아온 데이터를 꺼내 화면에 표시합니다.

putExtra() 메소드가 어떤 타입이든 상관없었던 것에 비해, 불러올 때에는 getStringExtra()메소드를 사용하여 문자열 값을 불러오면 됩니다. getStringExtra()뿐 아니라 getIntExtra(), getBooleanExtra() 등 여러 가지가 있으므로 상황에 맞추어 사용하면 됩니다.

이렇게 해서, 화면에 표시되는 TextView의 텍스트 값들이 아까 호출한 액티비티의 값들로 바뀌게 됩니다. :)


이렇게 해서, 인텐트를 통해 액티비티간에 데이터를 주고받는 것에 대해서 알아보았습니다. 이번 강좌는 다른 강좌들과는 다르게 세세한 부분에 대한 설명은 대부분 생략하였습니다. 이 강좌쯤을 보시는 분들은 어느 정도 기초가 되어 있으리라 믿기에, 일부러 안 적었습니다. 게다가 그걸 다 적으면 강좌가 한도끝도 없이 길어지기만 하죠 -_-

현재, 이 코드는 모든 문자열 값을 strings.xml에 넣어서 그 쪽에 있는 값들을 참조하는 형식으로 구성되어있습니다. 이 부분에 대해 궁금하신 분은 제가 2009/03/14 - [안드로이드/안드로이드 입문] - [강좌] 외부 리소스 사용하기 (문자열) 에 정리해놓았으니, 이걸 보시면 되겠습니다. :)



저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License

커니 어플리케이션 구성/인텐트(Intent) , , , , , , , , ,

  1. Blog Icon
    향긋한소리

    음.. 코드가 보기가 어렵군요.. ;;;; 일부러 이렇게 하신건가요?? ;;; 다른건 않그런거 같았는데..;;;

  2. 블로그 글을 이래저래 계속 수정하다 보니 어긋났나보군요. -_-;; 조만간 수정하겠습니다~

  3. Blog Icon
    소안

    오랜만에 들러요 ㅋㅋ 잘봤습니다.

  4. Blog Icon
    느린기차

    좋은 정보 감사합니다~

  5. Blog Icon
    경민

    좋은 정보 감사합니다~
    궁금한게 있는데요
    인텐트를 쓰면 activity A-> B(데이터push)->A(데이터pull) 이렇게 되잖아요
    저는 activity A(데이터push) -> B(데이터pull) 이렇게 하고 싶은데,
    인텐트를 사용가능 한가요?

  6. 방향과는 상관없이 액티비티를 호출할 때 인텐트에 Extra를 추가해준 후 호출받은 액티비티에서 데이터를 가져오면 됩니다 ^^

  7. Blog Icon
    호호

    자료잘보고있습니다.
    궁금한게있는데요. XML 을 새로 만들어서 XML코드를 만들면

    InformationInput]Error in an XML file: aborting build.

    이런 오류가 뜨는데요, 왜 그런거죠? XML도 새로 만들때 다른 절차가 필요한가요?

  8. 레이아웃 코드에 오타가 있나보네요.
    코드 창으로 전환해서 X표시된 곳을 참조하세요.

  9. 참고:
    xml코드 잘못되서 그대로 복사해서 붙여넣기하시면 에러나요... 다시 자신이 xml코드 만드셔서 하세요 테스트하세요

  10. http://androidhuman.tistory.com/notice/203

    여기에 위와 관련된 내용을 적어놨습니다만.....

    예전에 썼던 글들은 너무 많아서 하루아침에는 못고치고 서서히 다시 훑어보면서 잡아보고 있습니다만... 다시 만들어서 테스트하고 올리라니 말씀이 지나치신것 아닌가 싶군요.

    저번에 질문하신 것들도 솔직히 제 블로그 5분만 둘러보셔도 다 찾을 수 있는 것들이고, 위에 검색창에서 쳐보면 바로 나오는 것들인데 그냥 링크 걸어드렸는데.. 이러시면 곤란합니다.

  11. 이건뭐....
    자신이 못돌리는거지 -.-;;

    예제 보는 것만도 감사감사인데,
    왠 명령어 문체인가요.

  12. Blog Icon
    알아서 찿으세요

    정신병자 같네요 ㅋㅋㅋㅋㅋ

  13. 안드로이드 사이트 중에서 운영자의 노력이 많이 보이는 사이트라 많이 애용을 하고 있는 곳인데요.. 운영자님께서 소스분석도 잘해 주시고 아픈곳도 잘 긁어 주시고 포인트도 잘 찝어 주셔서 여느 사이트 보다 배워가는게 더 많은거 같습니다.ㅎ 좀 아쉬운게.. 오타도 있고 버전이 업되면서 호환이 안되거나 문제점이 많이 발생되어 보고 그대로 따라해도 빌드가 안되는 상황이 종종 발생이 되는데요.. 풀소스를 받아 볼수 있게 자료등록 해주시던가 링크 해주시면 더 좋아 질거 같아요~!! 바쁜 와중에도 업글을 하시느라 고생이 많습니다 ㅎㅎ 새해 복 많이 받으시고요~!! 올해도 수고 하셨습니다.

  14. 하나하나씩 업뎃 계획도 잡고 있습니다.
    일단 말씀해주시는 것들은 최대한 빠른시일내에 고치려고 노력중입니다 ^^

    너무 업데이트가 빠르게 되다보니 이런 문제들이 생기네요 ㅠㅠ

  15. Blog Icon
    hwani

    안녕하세요 커니님 안드로이드사이드 강좌에서 보고 왔습니다.
    강좌를 따라해 가며 매번 도움을 받고 있네요^^

    그런데, 어느날 부터 R.java파일에 문제가 발생해서 해결 방법좀 구하러 글을 남깁니다.

    원래 R.java 파일은 저절로 수정 되기 때문에 건드리지 않는 파일로 알고 있습니다.
    그런데 몇몇예제를 하면서 제가 놓친 부분이 있는지 아니면, 다른 이유가 있는지,

    *.java파일의

    findViewById(R.id.requestInfo);

    요런 부분에서(몇개가 나오죠..) requestInfo가 파란색으로 변하지 않네요.
    물론 R.java파일에서도 id에 등록 되지도 않고요. 그전에는 저절로 생성 되었던걸로 기억을 하고 있느데 말이죠;

    궁금합니다. 속시원하게 긁어 주시겠어요~^^

  16. XML 파일에 ID입력이 제데로 되었는지 한번 확인해보세요.
    업데이트가 제데로 안된다면 대부분 그쪽 문제일 가능성이 큽니다 :)

  17. Blog Icon
    hwani

    답변 감사합니다 ^^

    R.java 파일에 id가 생성되지 않는 문제는 해결했습니다.

    컴파일이 되면 자동으로 생성되는건데,
    다른 부분에서 에러가 계속 나서 컴파일이 안되고,
    컴파일이 안되서 id 입력이 안되었던것 같습니다.

    문제는 xml파일에서
    버튼과 텍스트뷰에서
    android:text="@string/digit" 부분이 문제를 일으킨 것이었네요.
    @를 빼고 실행하면 컴파일 문제는 해결됩니다.
    (하지만, 버튼과 텍스트가 뭥미가 되버리네요^^;; )

    다시한번 만저보고, 스스로 해결을 하거나
    못하면 다시 찾아오겠습니다.

    처음 하는 거라 사소한 부분에서 조차 많이 막히네요.
    커니님 강좌 덕분에 정말 매번 배워 갑니다.

    그럼 좋은 하루 되세요!

  18. Blog Icon
    hwani

    다음과 같은 방법으로 해결을 했습니다.
    (제가 중간에 과정중 하나를 빼먹은것 같아요;;; )

    res/values/string.xml 파일을 열어서
    name, digit, button_launch, text_information, input 값을 각각 입력 해보니

    방금위에서 문제되었던

    android:text="@string/name"
    android:text="@string/digit"
    android:text="@string/button_launch"
    android:text="@string/text_information"
    android:text="@string/input"

    에 더이상 에러 메시지가 나질 않네요 ^^

    감사합니다 커니님 수고하세요~

  19. Blog Icon
    comtamer

    저도 화니님과 같은 문제인데요...

    strings.xml에 스트링들 다 추가 해주었는데 informationProc에 있는 id들이 R.java에 자동 생성이 안되요....

    어떻하죠=ㅅ=? 도움 부탁드려요

  20. Blog Icon
    comtamer

    아 추가 하자면 콘솔 부분에

    InformationInput]res\layout\InformationProc.xml: Invalid file name: must contain only [a-z0-9_.]

    이게 뜨네요 =ㅅ=

  21. 오타가 있었군요 -_-
    오류에서 나온 말 그대로 리소스명은 소문자, 숫자, -,_로만 이루어져야 햡니다.

    imformationproc.xml으로 이름을 변경하세요~

  22. Blog Icon
    comtamer

    도움 감사합니다^^

  23. Blog Icon
    sang

    안녕하세요 커니님 덕분에 많은 도움이 되었습니다.
    그런데 intent 로 값을 얻어올때 하나의 data (이름, 전화번호) 만이 아니라
    여러개의 data 묶음을 한번에 가져올 순 없나요?
    예를 들어
    for(i = 0; i <j ; i++){

    intent.putExtra(name,name[i]);
    intent.putExtra(number, number[i]);

    setResult(RESULT_OK,intent);
    finish();
    }
    이런 식으로요. 이럴경우 묶음이 전송되는게 아니라 하나만 전송이 되던데.ㅠ.ㅠ

    제가 안드로이드 초보라 아직 잘 몰라요.ㅠ

  24. http://developer.android.com/reference/android/os/Bundle.html

    여기에서 적절한 메소드를 찾아보는 것이 좋을 듯 합니다.
    Extras는 Key, value 한 쌍으로 이루어져 있으므로 위의 코드처럼 사용하면 name, number에는 맨 마지막 데이터만 들어게 되겠지요 :)

  25. Blog Icon
    cocoya

    첫번째 액티비티에서 버튼을 눌러서 두번째 액티비티를 부를때 Stop unexpectedly ,Please try again 이라는 메세지가 뜹니다.
    그래서 디버거로해서 로그캣을 보니 프로그램 시작할때 아래와 같은 에러가 나네요..
    ERROR/AndroidRuntime(254): ERROR: thread attach failed

    그래도 프로그램은 실행이되고 버튼을 누르면
    02-18 17:47:35.808: WARN/dalvikvm(298): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
    02-18 17:47:35.808: ERROR/AndroidRuntime(298): Uncaught handler: thread main exiting due to uncaught exception
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): java.lang.RuntimeException: Unable to start activity ComponentInfo{kr.android.intent/kr.android.intent.InfoProc}: java.lang.NullPointerException
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.os.Handler.dispatchMessage(Handler.java:99)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.os.Looper.loop(Looper.java:123)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.ActivityThread.main(ActivityThread.java:4363)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at java.lang.reflect.Method.invokeNative(Native Method)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at java.lang.reflect.Method.invoke(Method.java:521)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at dalvik.system.NativeStart.main(Native Method)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): Caused by: java.lang.NullPointerException
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at kr.android.intent.InfoProc.onCreate(InfoProc.java:22)**
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
    02-18 17:47:35.852: ERROR/AndroidRuntime(298): ... 11 more

    위와같은 메세지가 나옵니다.
    그중에서 소스파일에 관련부분은 호출당하는 액티비티쪽에서 아래와 같습니다.
    input_info.setOnClickListener(new OnClickListener(){

    왜 프로그램 시작할때 ERROR/AndroidRuntime(254): ERROR: thread attach failed 과 같은 에러가 나는지 모르겠습니다.

  26. 그건 중요한게 아니고....
    NullPointerException이 문제네요.

    객체 할당을 제데로 해 주었는지 확인해보세요.

  27. Blog Icon
    ㅇ_ㅇ

    자바소스1의 결과값 하나와 자바소스2의 결과값 하나를 불러서 자바소스3에 동시에 나타내고 싶을 때는 어떻게 해야 하나요?ㅜㅜ알려주세요ㅠㅜ

  28. 자바소스라는게 정확하게 어떤걸 말씀하시는건가요??
    단순한 자바 클래스라면 말 그대로 구현하시면 되는거고....
    액티비티의 결과값을 이용하는것이라 할지라도 그리 어렵진 않아뵈이는데요.

    액티비티A -> 액티비티1 호출/ 결과값반환
    액티비티A -> 액티비티2 호출 / 결과값반환

    액티비티A에서는 각각의 결과값을 표시해주면 되구요.

  29. 항상 잘보고 있습니다.. ㅎㅎ 이제와서 인사드리네요 ㅎㅎ
    감사 감사 감사합니다.. ㅎㅎ

    퍼갈게요 ^^ㄹ

  30. Blog Icon
    박두현

    운영자님 질문 있습니다.

    인텐트를 사용해 엨티비티를 실행시켰습니다.

    그리고 엑티비티를 불러준 Main액티비티는 소켓으로 통신을 하고 있어서 내부적으로 스레드가 돌고 있습니다.

    Main 액티비티에서 메시지를 받아서 받은 타이밍에 불려진 엑티비티로 데이터를 주고 싶습니다.

    실시간으로 전송된 데이터가 업데이트 되었으면 좋겠습니다.

    Main에서 Put을 하고 불려진 액티비티에서 get을 해야

    하는데 실시간으로 할려고 하니

    어떻게 해야 할지 감이 잡히지 않습니다. ㅜㅜ

  31. 핸들러 (android.os.Handler)를 사용하시면 됩니다. :)

  32. 쉽게 설명해 주셔서 이해가 잘 되네요~^^
    코드 중 하나 수정할 부분이 있는 것 같아요.
    InformationInput.java의 15라인에 Button.OnClickListener이 없더라구요. 버전이 올라가면서 없어진건지..
    그리고 한가지 궁금한 점은 실제 어플을 만든다면 requestCode 값을 static 변수로 두고 하는게 맞을까요?? 예제에서는 1이라는 값으로 정해서 했는데 Activity가 많아진다면 헷갈리지 않을까 싶어서요.

  33. OnClickListener가 View.OnClickListener가 있고 DialogInterface.OnClickListener 가 있습니다.

    Button.OnCLickListener로 적을 경우 명시적으로 View.OnCLickListener를 사용한다는 의미가 되지요.

    그냥 OnClickListener를 사용하더라도 위의 import 선언에서 View.OnCLickListener를 import 하면 상관이 없습니다.

    그리고 requestCode같은 경우 어차피 "현재 액티비티"에서 다른 액티비티를 호출할 때 사용하는 코드이기 때문에 그리 많은 값들이 필요치 않습니다. 충분히 커버되는 범위 안에서 애플리케이션 작성이 가능하지요.

    만약 한 액티비티에서 호출하는 액티비티가 몇백개가 된다면.. 이것은 애초에 애플리케이션 설계가 잘못된 것이라 할 수 밖에 없습니다.

  34. Blog Icon
    whiteblue

    text_bmi.setText(data.getIntExtra("data_digit", 0));

    이런식으로 int형으로 바꿔서 받고 싶은데 에뮬레이터에서 값을 넣으면 액티비티가 넘어가지 않고 오류가 납니다..

    어떻게 int형으로 받는지 궁금합니다.

  35. String.valueOf를 사용하시면 됩니다.
    getIntExtra()가 int형 데이터를 반환하므로, EditText의 값으로 넣어주려면 String 형으로 변환해야 합니다.



    edit_text.setText(String.valueOf(getIntExtra("key", -1)));

    이 정도로 쓸 수 있겠죠?

  36. Blog Icon
    whiteblue

    EditText name_input = (EditText) findViewById(R.id.EditText01);
    EditText digit_input = (EditText) findViewById(R.id.EditText02);
    EditText tall_input = (EditText) findViewById(R.id.EditText03);
    EditText sex_input = (EditText) findViewById(R.id.EditText04);

    Intent intent = getIntent();

    intent.putExtra("data_name", name_input.getText().toString());
    intent.putExtra("data_digit", digit_input.getText().toString());
    intent.putExtra("data_tall", tall_input.getText().toString());
    intent.putExtra("data_sex", sex_input.getText().toString());
    ------------------------------------------------------------------------------------

    TextView text_name = (TextView) findViewById(R.id.TextView01);
    TextView text_digit = (TextView) findViewById(R.id.TextView02);
    TextView text_tall = (TextView) findViewById(R.id.TextView03);
    TextView text_sex = (TextView) findViewById(R.id.TextView04);
    TextView text_bmi = (TextView) findViewById(R.id.TextView05);

    if(requestCode == REQUEST_CODE)
    {
    if(resultCode == RESULT_OK)
    {
    text_name.setText(data.getStringExtra("data_name";));
    text_digit.setText(data.getStringExtra("data_digit";)+ "kg";);
    text_tall.setText(data.getStringExtra("data_tall";)+ "cm";);
    text_sex.setText(data.getStringExtra("data_sex";));

    text_bmi.setText(String.valueOf(data.getIntExtra("data_digit", -1)));

    -----------------------------------------------------

    말씀하신대로 수정하니 오류는 없어졌는데 실제 값을 넣으니 "data_digit"의 값이 출력되지 않고
    -1이라는 디폴트 값이 출력됩니다..;; 왜이럴까요 ㅜㅜ

  37. 피호출 액티비티에서 액티비티 종료할 때 setResult(int result, Intent data)를 호출하셨나요??
    피호출 액티비티쪽 코드를 확인해보는 것이 좋을 것 같군요.

  38. Blog Icon
    우할할할

    안녕하세요. 님의 강좌를 열렬하게 보고있는 사람인데요

    이 강좌를 따라하던중에 stringㅇㅔ서 나는 오류는 다 해결하구 디버깅을 하는데

    sdk에서 갑자기...ㅠㅠ

    [2011-01-21 18:13:26 - DeviceMonitor]Sending jdwp tracking request failed!

    이런 오류가 나더니 이 소스코드가 실행이 안되요

    왜그런지좀 알려주세요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

  39. 해당 문제는 에뮬레이터나 단말기와의 연결이 끊어졌거나 불안정할때 발생하는 문제입니다.

    에뮬레이터를 재시작하거나 단말기를 다시 연결하면 됩니다 :)

  40. Blog Icon
    MAN

    운영자님 질문 있습니다.
    간단한 SMS 암호화 해서 전송하는 프로그램인데요.... 어플 처음 설치하고나서 제일 처음 메세지를 전송하면 암호화 했던 메세지가 복호화 되서 화면에 날 나타나는데.... 2번째 메세지를 받을때 부터 문제가 발생하더라구요. 브로드 캐스트 리시버에서 잘못 받아왓나 확인해 봤는데 메세지는 확실히 잘 받아왔는데 이상하게도 제일 처음에 읽어 들였던 메세지를 잘못 받아오는거에요?? 이유를 모르겠습니다....

    public class SMSReceiver extends BroadcastReceiver { //브로드캐스트 클래스

    @Override
    public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();

    if(extras != null){
    Object[] pdus = (Object[])extras.get("pdus";);
    SmsMessage[] messages = new SmsMessage[pdus.length];

    for(int i=0; i<pdus.length; i++){
    messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
    }

    for(SmsMessage message : messages){
    String msg = message.getMessageBody();
    String from = message.getOriginatingAddress();


    Toast.makeText(context, from + " : " + msg, Toast.LENGTH_LONG).show();

    Notification notification = new Notification(android.R.drawable.ic_input_add,
    "메세지 수신",System.currentTimeMillis());

    NotificationManager nm = (NotificationManager)context.
    getSystemService(context.NOTIFICATION_SERVICE);

    Intent in = new Intent(context, ReceiveSMS.class);

    //Log.v("number : ",from);
    //Log.v("message : ",msg);


    in.putExtra("sender_number",from);
    in.putExtra("message", msg);
    Log.v("=========브로드캐스트리시버======== : ","=========================";);
    Log.v("number : ",in.getStringExtra("sender_number";));
    Log.v("message : ",in.getStringExtra("message";));

    //context.startActivity(in);
    PendingIntent inten =
    PendingIntent.getActivity(context, 0, in, 0);

    notification.setLatestEventInfo(context, from, msg, inten);
    nm.notify(1234,notification);
    }
    }
    }
    }

    public class ReceiveSMS extends Activity { //메세지 수신 액티비티
    private String sender_number;
    private String message;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v("===========ReceiveSMS==============","=====onCreate()========";);
    setContentView(R.layout.receivesms);


    EditText sender = (EditText)findViewById(R.id.sender_number);
    EditText msg = (EditText)findViewById(R.id.receve_message);
    EditText key = (EditText)findViewById(R.id.receve_key_editbox);
    Button btn = (Button)findViewById(R.id.decoder_button);
    Button exit_btn = (Button)findViewById(R.id.receve_exit);

    // TODO Auto-generated method stub


    Intent data = getIntent();
    sender_number = data.getStringExtra("sender_number";);
    message = data.getStringExtra("message";);

    Log.v("sender_number",data.getStringExtra("sender_number";));
    Log.v("message",data.getStringExtra("message";));

    //복호화영역 - 시작

    char[] arr = message.toCharArray();
    for(int i = 0 ; i < arr.length ; i++)
    arr[i] -=1;
    message = String.valueOf(arr);

    sender.setText(sender_number);
    msg.setText(message);

    ///복호화영역 - 끝
    NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    nm.cancel(1234);
    exit_btn.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
    finish();
    }
    });
    }

    protected void onPause(){
    super.onPause();
    Log.v("===========ReceiveSMS==============","=====onPause()========";);
    }

    protected void onStop(){
    super.onStop();
    Log.v("===========ReceiveSMS=====================","=====onStop()========";);
    }
    protected void onRestart(){
    super.onRestart();
    Log.v("===========ReceiveSMS=====================","=====onRestart()========";);
    }
    protected void onResume(){
    super.onResume();
    Log.v("===========ReceiveSMS=====================","=====onRresume()========";);
    }
    protected void onStart(){
    super.onStart();
    Log.v("===========ReceiveSMS=====================","=====onStart()========";);
    }
    }
    왜그런지 답변좀 부탁드립니다...
    혹시나 보기 힘드시면 파일통째로 보내드리겠습니다..

  41. Blog Icon

    비밀댓글입니다

  42. 말씀해주신 것과 같은 경우에는 액티비티 A에서 액티비티 B를 실행한 후, B에서 입력할 내용을 입력하고 B 액티비티를 종료할 때 넘겨줄 값들을 인텐트에 저장하여 (setResult(Intent, int) 사용) 액티비티 A에 넘겨준 후, 액티비티 A의 onActivityResult() 에서 B의 호출 결과가 RESULT_OK 일 때 액티비티 C를 호출하면서 액티비티티 C를 호출하는 인텐트에 액티비티 B의 결과값을 같이 넣어서 호출하는 방법을 사용하시면 됩니다. :)

  43. Blog Icon

    비밀댓글입니다

  44. Blog Icon

    비밀댓글입니다

  45. Blog Icon
    gaki

    강좌 잘보았습니다. 질문이 있는데영~

    강좌본대로 B 액티비티에서 값을 받아 A 액티비티 리스트뷰안에 값을 넣는건되었습니다.

    추가버튼을 누르면 B 액티비티가 호출되는데영 각각 설정을 하고 완료하면

    리스트뷰안에 설정한값 이 생기고 다시 클릭하면 다시 B액티비티로 이동하여 값이 설정되어 있게 할려고 합니다.

    리스트뷰안에 값들은 클릭시 모두 B액티비티가 나와야되고 각각 설정이 다르면 그 설정에 맞게
    B액티비티 값들이 설정되있어야됩니다.

    힌트 좀 주시면 안될까요? 객체저장하고 인텐트 쪽을 이용해야될듯한데 초짜라 좀 막막하군요

    참고루 안드로이드 기본내장 알람어플과 비슷하게 구현중입니다.

  46. Blog Icon
    촌간지

    정말 이런 좋은 자료를 제공해주셔서 정말 감사드립니다.
    다른 어플을 호출할 일이 있습니다.
    그런데 타 어플을 사용자가 "OK"를 눌러서 제대로 실행했는지 그저 백키를 누르던가 "Cancel"을 눌렀는지 확인해야할 필요가 있어서 startActivityForResult()를 사용해서 어플이 내려간 상태도 알수는 있게 되었습니다.

    문제는 Activity에서는 startActivityForResult()를 사용할 수 있는데,
    Service에서 타어플 호출 시 startActivityForResult()를 사용할 수 없다는 문제가 있네요.

    혹시 Service에서 응용가능한 방안이 있을까요?

  47. Blog Icon
    전기박사

    자료 공계해주셔서 감사합니다.
    도서실에서 잠깐 본 책이였는데... 구매해서 봐야 겠어요...게시글 보고 많이 공부 하였습니다.

  48. Blog Icon
    oO위드Oo

    전 실행을하면 오류떠서 제대로 실행이 안되요...이럴땐 어떻게 해야하나요???ㅠㅠ

  49. 어떤 오류가 뜨는건지 확인해보세요. LogCat 로그를 확인하면 어떤 것 때문에 오류가 발생했는지 알 수 있습니다.

  50. Blog Icon
    냠냠

    커니님, 강의 잘봤습니다.
    근데 텍스트가 아닌 이미지뷰의 이미지는 어떻게 넘겨주는지 궁금해요...

  51. Blog Icon
    힝힝

    좋은 거 배우고 갑니다.
    여쭤 볼께 있는데요.. 데이터 주고 받는 거 성공 했거든요?
    입력한 값을 꼭 onAcitivityResult 메소드에서 받아야 되나요?
    데이터 값을 다른 메서드에 사용하고 싶은데... 좀 가르켜 주세요

  52. 다른 액티비티에서 받은 결과값은 onActivityResult()에서만 받을 수 있습니다.

    다른 메서드에서 이를 사용하려 한다면 단순히 onActivityResult()에서 다른 메서드를 호출하면 될 듯 하네요.

    결과를 직접 받은 액티비티가 아닌 다른 곳에 구현되어 있는 메서드를 실행하는 것이라면 리스너 인터페이스를 활용하시면 될듯 하구요,

  53. Blog Icon
    ㅠㅠ

    2009년에 여길 알았다면 좀더 빨리 배웠을텐데...
    삽질하면서 머릿속으로 대충 이런건가?싶으면서 넘어간것들에 대해서 잘 배워갑니다^^

  54. Blog Icon
    ㅇㄹㅇㄹㅇㄴ

    이 블로그가 안드로이드 강좌 중에서 최강인듯 하네요
    그러나 책 사려고 알라딘 갔떠니 품절 orz

  55. Blog Icon
    kimeana

    안드로이드를 개발하는데 이번에 허니콤에서 개발하는데 fragment를 사용하여서
    화면을 분할해서 왼쪽에는 리스트 그리고 오른쪽에는 그에 따른 db데이터를 보여주려고 하는데요
    전 버전으로 개발해 놓은것이있어서 살짝 응용만 하려고 하는데 옆에 리스트 1댑스에서 클릭했을때 2depth를 보여주고 싶은데 이건 어떤 api를 참조 하면 좋을까요 왼쪽에 리스트들을 전부다 넣고 싶어서요 그런 기능이 가능할까요?

  56. Blog Icon
    조제우

    startActivityForResult() 가 OnClickListener()에 정의돼있지 않다고 하는데..
    어떻게 해결하나요 ??;;
    getIntent() 이런것도 안돼고..
    gridview를 이용해서 버튼을 여러개 생성하고
    buttonadapter에서 버튼 클릭시 activity를 호출 하고,(startActivity()로) 호출된 activity에서 값을 전달한후 그 값을 처리 하는건데.
    null 값만 옵니다.. 어떻게 해야하나요 ?

  57. Blog Icon
    wk

    좋은 정보 감사합니다. 덕분에 개념을 잡게 되었네요. (꾸벅)

  58. Blog Icon
    pooh오빠

    음 근데 이게 일반 java 개발에서 데이터 class를 만들어서, set,get하는것과 무슨 차이가 있는거죠??

    장점이??

  59. 일반 클래스랑 인텐트랑은 아예 개념 자체가 다르다 보는게 편합니다.
    인텐트는 데이터를 전달하는 매개체로 쓰임과 동시에 다른 컴포넌트를 실행시키는 역할까지 하는 것이니까요.

  60. Blog Icon
    pooh오빠

    ㄴ그렇네요....아직도 잡힐까 말까하네요..개념이....ㅠㅠ

  61. 커니님, 오타가 있는 것 같아 댓글로 제보해봅니다.

    "위의 onActivityResult에서, requestCode가 아까 setResult()에서 액티비티가 정상 종료되었는지를 판단하는 인자값, RESULT_OK를 받게 됩니다. 그래서, 이걸 가지고 적절히 예외 처리를 해 줄 수 있는 거죠."

    위 문장에서 requestCode가 아닌 resultCode가 아닌지 의문이네요. RESULT_OK를 받는 것은 resultCode여서 맞는 것 같습니다. 게다가 위 문장 바로 아래에 또 requestCode를 설명해주셔서 착오가 있었던 것 같습니다.

    최근 들어 많은 도움을 받고 있네요. 이 자릴 빌어 정말 고맙다는 말씀 드립니다. :)

  62. 수정했습니다. 제보 감사드립니다 :)

  63. Blog Icon
    SPOCK

    메인액티비티가 뉴 액티비티에 값을 던질 수는 없나요??
    그에 대한 여지가 Startforresult에서 requestcode가 될 수 있을 것 같은데 잘 안되는것 같네여 ㅠㅠ

  64. Intent에 값을 넣어 호출하면 전달 가능합니다.
    예 )
    Intent intent = new Intent(...);
    intent,putExtra([태그], [데이터]);