관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 인텐트 기본 사용방법 (intent) 본문

안드로이드/자바 & Previous

[안드로이드] 인텐트 기본 사용방법 (intent)

막무가내막내 2019. 3. 1. 12:50
728x90

인텐트는 애플리케이션 구성 요소 간에 작업 수행을 위한 정보를 전달하는 역할을 한다.

Intent는 일종의 메시지 객체입니다. 이것을 사용해 다른 앱 구성 요소로부터 작업을 요청할 수 있습니다. 인텐트가 여러 구성 요소 사이의 통신을 용이하게 한다.

 

인텐트의 자세한 사항은 안드로이드 개발자문서를 참고하면된다.

 

인텐트 문서 : https://developer.android.com/guide/components/intents-filters?hl=ko

 

 

 

  인텐트:액션+데이터

액티비티A  =================>       액티비티B

   <=================

    결과 (선택적)

 

 

액티비티A--------------------------------------------------------------------------------------------------액티비티B

(1)startActivityForResult()======== 인텐트: 액션+데이터, requestCode====>

(3)onActivityResult()  <=====requestCode, resultCode, optional data======  (2) setResult

 

가장 기본적인 사용법중 하나인 화면전환과 데이터전달에 대해 정리해봤다. 인텐트의 여러가지 쓰임새 중 액티비티화면을 전환해주고 데이터를 주고받는 것으로 예제를 들어보겠다.

먼저 startActivityForResult 와 startActivity의 차이점은 A 액티비티가 B액티비티로를 intent로 호출하고 다시 A액티비티로 돌아올때 B액티비티로 부터 받을 데이터가 있을 경우는 전자 아니면 후자를 사용한다.

 

사용방법은 인텐트를 생성해서 첫번쨰매개변수에 액션 두번째 매개변수에 데이터를 넣으면 되는데 여기서 예제는 다른 액티비티를 띄워주는 것이므로 첫번째 매개변수에 자신의 context, 두번째에 띄울 액티비티를 넣어주면 된다.

 

<p.s>

액티비티가 아닌 카메라 갤러리 전화등도 호출할 수 있다. 전화를 예로들면 을 띄울려면 new Intent("Intent.ACTION_VIEW, Uri.parse("tel:010-1111-2222")); 이런식으로 하면된다. 그럼 해당 번호로 전화걸기 화면이 띄워진다.

 

이어서 이런식으로 인텐트를 생성하고 띄울 액티비티에 전달할 값이 있다면 intent.putExtra("key", value); 이런식으로 보내주고 startActivty()나 startActivityForResult()로 화면을 띄워주면 된다.

 

그 다음 띄워지는 액티비티에서는 getIntent()로 인텐트를 전달받아 intent.getExtras().getInt("key")이런식으로 타입에맞게 값을 받으면 된다. 

 

참고로 부가데이터를 주고받는건 여러 방식이 있는데 다음 사이트에서 참고하면 좋을 것 같다.

https://youngest-programming.tistory.com/50

 

또 한 setResult(Activity.RESULT_OK, intent) 이런식으로 데이터를 전달을 잘 받았다고 띄워준 액티비티에게 결과를 전달 할 수 있다. 또 intent에 부가데이터를 넣어서 띄워준 액티비티에게 전달하는것도 할 수 있다. 

단, startActivityForResult()로 띄웠을때만 띄워진 액티비티로부터 데이터나 결과를 받을 수 있다. startActivty()는 일방적으로 띄워주는 역할만 할 수 있어 응답결과를 받지 않는다고 이해하면 된다. 그래서 이 두개의 함수를 상황에 맞게 사용해야한다.

 

띄워진 액티비티로부터의 응답결과는 띄운 액티비티의 

onActivityResult()를 override해서 받으면 된다.

 

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

말로 설명하는 것보다 코드로 한번 살펴보는게 좋을것 같다. 주석에 설명을 살짝 곁들어놨다.

 

띄우는 액티비티는 메인액티비티

띄워지는 액티비티는 메뉴액티비티라 하겠다. 

 

메인액티비티

import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
//응답을 받을 경우는 startActivityForResult를 사용한다.
//아니면 그냥 StartActivity(intent)라 하면된다.
//즉 둘다 액티비티를 화면에 띄우고 인텐트를 전달해주는 역할
                startActivityForResult(intent, 101);
            }
        });
    }

//세번째 매개변수에서 메뉴엑티비티에서 보낸 intent를 전달받음
//리퀘스트코드는 메뉴화면을 띄울떄 전달한 101코드가 메뉴화면으로갓다가 다시 여기로 requestCode로 전달됨.
//즉 requestCode로 어떤화면으로부터 왔는지 알 수 있음
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 101){

            if(resultCode == RESULT_OK){ //resultCode는 띄어진화면(메뉴액티비티)에서 setResult결과를 전달받은거다.
                String name = data.getStringExtra("name");
                Toast.makeText(getApplicationContext(), "메뉴화면으로부터 응답 : " + name, Toast.LENGTH_LONG).show();
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        android:text="메뉴화면 띄우기"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

 

 

 

메뉴액티비티

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MenuActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);

        Button button = findViewById(R.id.button2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
//해시처럼 키와 벨류값을 설정 (이 액티비티를 불러준 곳에 데이터를 전달할 용도)
                intent.putExtra("name", "mike");
//Result_OK는 일종의신호이다. 이상이없는 신호라는걸 의미함
                setResult(Activity.RESULT_OK, intent); //이 액티비티가 종료되기전에 이 메소드를 호출함으로써 메인액티비티에 응답을 보낼 수 있다.

                finish();
            }
        });
    }
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MenuActivity">

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="148dp"
        android:layout_marginLeft="148dp"
        android:layout_marginTop="144dp"
        android:layout_marginEnd="148dp"
        android:layout_marginRight="148dp"
        android:layout_marginBottom="232dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:text="메뉴화면"
        android:textSize="40dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

 

 

결과화면

 

 

 

 

 

주의할점

 

 

만약 위와 같은 방법으로 하면 괜찮으나 (액티비티와 xml 같이 생성해주고 manifest에 등록해준다.) 그냥 자바소스파일에 클래스생성으로 액티비티를 만들고 xml도 layout에 우클릭해서 만드는 경우 manifest에 등록되지않으므로

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.a82107.myintent">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MenuActivity"
            android:label="메뉴 화면"
            android:theme="@style/Theme.AppCompat.Light.Dialog"></activity>
    </application>

</manifest>

다음과 같이 추가한 액티비티를 manifest에 등록을 해주어야 해당 액티비티를 사용할 수 가 있다.

 

 

 

=============================================

위의 예제는 메인액티비티에서는 데이터를 전달하지않고 띄어주기만하고 메뉴액티비비티에서 데이터를 전달하는것을 받기만 해주는데

메인액티비티에서 데이터를 보내는 예제만 추가로 정리해봤다.

사용했던 코드를 그대로 복사해온건데 이렇게 데이터를 넣고 전달하고 전달받는구나를 알 수는 있을 것이다.

 

메인액티비티---> 메뉴액티비티

 

보내는쪽, 띄우는 액티비티 (ex 메인액티비티)

Intent intent = new Intent(getApplicationContext(), ViewAllActivity.class);
//getCount를 for문에 하면 계속 참조하므로 밖에 뺴준다.
int count = GundoInfoFragment.adapter.getCount();
ArrayList<CommentItem> commentItems = new ArrayList<CommentItem>(count);
intent.putExtra("ratingAverage", (float) ((Math.round(GundoInfoFragment.ratingAverage*10))/10.0));
intent.putExtra("ratingTextAverage",((((Math.round(GundoInfoFragment.ratingAverage*10))/10.0))*2)+"");

for(int i =0; i <count; i++){
    commentItems.add((CommentItem) GundoInfoFragment.adapter.getItem(i));
}
//prarcelable을 구현한 객체를 담은 ArrayList 데이터를 보냄
//객체만 보낼떈 그냥 putExtra로함 =
//ex) intent.puExtra("ex", new CommentItem(new CommentItem(R.drawable.user1, 5,"wow123", "너무 재밌어요");
intent.putParcelableArrayListExtra("commentItems", commentItems);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivityForResult(intent, 102);

 

받는쪽, 띄워진 액티비티(ex 메뉴엑티비티)

Intent passedIntent = getIntent();
if (passedIntent != null) {

    //별점과 별점수텍스트 받아오고 뷰에 세팅해줌
    float ratingAverage = passedIntent.getExtras().getFloat("ratingAverage");
    String ratingScoreText = passedIntent.getExtras().getString("ratingTextAverage");
    Log.i("TAGNAME", ratingScoreText+"");
    ratingBar.setRating(ratingAverage);
    textViewRating.setText(ratingScoreText);


    //paracelable구현한 객체 리스트들 데이터받아옴
    commentItems = passedIntent.getParcelableArrayListExtra("commentItems");

    //어뎁터에 받은 데이터 다넣어줌
    adapter = new CommentAdapter();
    for (int i = 0; i < commentItems.size(); i++) {
        adapter.addItem(commentItems.get(i));
    }
    //리스트뷰에 어뎁터 연결
    listView.setAdapter(adapter);
    adapter.notifyDataSetChanged();


}

 

이런식으로 띄어진액티비티는(메뉴액티비티) 자신을 띄운 액티비티로부터 getIntent()로 인텐트를 받고 데이터를 전달받을 수 있다.   

다시 자신을 부른 액티비티에게 데이터를 전달하는거는 처음 맨위에서 포스팅한거와 같으므로 생략한다.

 

 

 

 

 


[2021]

최근에 startActivityForResult() 가 deprecated 되었습니다.

이제부터는 다음 방법을 사용하길 권장드립니다.

developer.android.com/training/basics/intents/result?hl=ko

 

활동에서 결과 가져오기  |  Android 개발자  |  Android Developers

개발자 앱 내의 활동이든 다른 앱의 활동이든 다른 활동을 시작하는 것이 단방향 작업일 필요는 없습니다. 다른 활동을 시작하고 다시 결과를 받을 수도 있습니다. 예를 들어, 앱에서 카메라 앱

developer.android.com

 

 

댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!

728x90
Comments