본문 바로가기

프로젝트형 IoT 서비스 개발 4회차/3. 게이트웨이 디바이스 제어

[Day70] 2022-05-06(금) Android8 - Intent1(Activity1) - 김서연 강사님

728x90

[1] Intent(Activity)

<열혈코딩 안드로이드 스튜디오로 만나는 코틀린 - 박성완 - p279~285>

  1. Activity 호출 기본 예제

    - 버튼을 클릭했을 때 지정한 activity가 호출되어 화면이 변경됨

    - activity가 호출될 때 data를 같이 가지고 넘어가서 호출된 activity에서 활용 가능

    1) 메인 화면

acivity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="액티비티실행하기" />

</LinearLayout>

MainActivity.kt

package com.example.intent

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 인텐트는 액티비티 간에 정보를 전달하기 위해서 제공되는 객체
        // 1. 암시적인텐트
        // 2. 명시적인텐트
        //   - 정확하게 어떤 액티비티에게 정보를 전달할지 명시하고 작업
        //   - context 객체와 실행할 액티비티의 클래스명
        //                  -------------------------
        //                    └-> 안드로이드내부에서 코틀린클래스가 자바클래스로 변환
        //                   ( .kt -> .java -> .class(바이트코드 or 클래스파일 - 머신 내부에서 실행되는 파일)
        //   1) 인텐트 객체에 실행할 구성요소에 대한 정보를 세팅
        //   2) 안드로이드OS에 실행요청을 하며 인텐트객체를 넘긴다.
        //   3) 안드로이드OS에서 인텐트에 명시된 정보를 보며 실행할 객체를 파악한다.
        //   4) 인텐트에 명시된 컴포넌트를 실행하고 인텐트 객체를 실행되는 컴포넌트 쪽으로 넘겨준다.
        //      => 실행될 컴포넌트에 넘겨줄 데이터를 공유할 수 있다.
        //      => Intent.putExtra 메소드를 이용해서 데이터 공유
        button.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java).apply{
                putExtra("info", "첫 번째 액티비티가 넘기는 메시지")
                putExtra("num", 10000)
            }
            // 실행될 액티비티에 넘겨줄 데이터를 인텐트에 저장
            //객체 생성시 .apply 써서 저장해도 되고, 아래와 같이 객체를 이용해도 됨
            /*intent.putExtra("info", "첫 번째 액티비티가 넘기는 메시지")
            intent.putExtra("num", 10000)*/
            startActivity(intent)
        }
    }
}

    2) 두 번째 화면

second.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:layout_width="match_parent"
	  	 android:layout_height="wrap_content"
	  	 android:text="두 번째 액티비티 화면입니다. 아래 버튼을 누르면 액티비티가 종료됩니다."
	  />
	  <Button
	  	 android:id="@+id/bt2"
	  	 android:layout_width="match_parent"
	  	 android:layout_height="wrap_content"
	  	 android:text="액티비티 종료"
	  />
</LinearLayout>

SecondActivity.kt

package com.example.intent

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.second.*

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.second)
        // 안드로이드OS가 넘겨준 인텐트객체를 가져온다.
        val intent = intent // getIntent()
        // 인텐트에 공유된 데이터 꺼내기 - getXXXExtra("공유명")
        val msg = intent.getStringExtra("info")
        val data = intent.getIntExtra("num", 0)
        Toast.makeText(this, "추출한값:$msg, $data", Toast.LENGTH_LONG).show()
        bt2.setOnClickListener {
            // 버튼을 누르면 액티비티 종료하기
            finish()
        }
    }
}

 

2. 호출됐던 Activity에서 데이터 전달 예제1

  - 1.번 예제에서는 호출한 activity(첫 번째 화면)에서 호출된 activity(두 번째 화면)로만 데이터가 전달 가능했음

  - 반대로 호출된 activity에서 호출한 activity로 데이터 전달하기 위한 예제

  1) 메인 화면

first2.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/intent_info"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:text="첫 번째 액티비티"/>

	<Button
	android:text="기본 액티비티 호출"
		android:id="@+id/call1"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"/>

	<Button
		android:text="result Value 액티비티 호출1"
		android:id="@+id/call2"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"/>
	<Button
		android:text="result Value 액티비티 호출2"
		android:id="@+id/call3"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"/>
	<Button
		android:text="종료"
		android:id="@+id/btnExit"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"/>
</LinearLayout>

ReturnDataFirstActivity.kt

package com.example.intent

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.first2.*

// request_code 상수로 정의
const val FIRST_BUTTON = 10
const val SECOND_BUTTON = 20

class ReturnDataFirstActivity : AppCompatActivity(), View.OnClickListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.first2)
        call1.setOnClickListener(this)
        call2.setOnClickListener(this)
        call3.setOnClickListener(this)
        btnExit.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when(v?.id){
            R.id.btnExit -> finish()
            R.id.call1 -> {
                val intent = Intent(this, ReturnDataSecondActivity::class.java).apply{
                    putExtra("info", "첫 번째 액티비티가 넘기는 메시지")
                }
                startActivity(intent)   // 실행되는 액티비티가 넘겨주는 데이터를 가지고 올 수 없다. 오직 액티비티를 실행할 목적
            }
            R.id.call2 -> {
                val intent = Intent(this, ReturnDataSecondActivity::class.java).apply{
                    putExtra("code", "call2")
                    putExtra("data", "첫 번째 액티비티가 넘기는 메시지-call2")
                }
                // 두 번재 액티비티를 실행하고 다시 되돌아올 때 값을 가지고 오는 경우 - startActivityForResult
                // 인텐트객체와 함께 request_code를 같이 넘긴다.(request_code는 사용자가 정의)
                // request_code는 이 액티비티 안에서 어떤 위젯이 요청한 것인지 구분하기 위한 코드
                startActivityForResult(intent, FIRST_BUTTON)
            }

            R.id.call3 -> {
                val intent = Intent(this, ReturnDataSecondActivity::class.java).apply{
                    putExtra("code", "call3")
                    putExtra("data", "첫 번째 액티비티가 넘기는 메시지-call3")
                }
                // 두 번재 액티비티를 실행하고 다시 되돌아올 때 값을 가지고 오는 경우 - startActivityForResult
                // 인텐트객체와 함께 request_code를 같이 넘긴다.(request_code는 사용자가 정의)
                // request_code는 이 액티비티 안에서 어떤 위젯이 요청한 것인지 구분하기 위한 코드
                startActivityForResult(intent, SECOND_BUTTON)
            }
        }
    }

    /*
        setResult를 호출하고 첫 번째 액티비티로 되돌아오는 경우, onActivityResult를 자동으로 호출한다.
        requestCode : 요청했던 위젯을 구분하기 위한 코드
        resultCode : 결과코드( 두 번째 액티비티에서 세팅한 결과 코드)
        data : Intent객체(두 번째 액티비티에서 넘긴 인텐트객체)
    */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.d("myintent", data?.getStringExtra("second").toString())
        if(data?.getStringExtra("second") != null){
            when(requestCode){
                FIRST_BUTTON -> intent_info.text = data?.getStringExtra("second")
                SECOND_BUTTON -> Toast.makeText(this, data?.getStringExtra("second"), Toast.LENGTH_LONG).show()
            }
        }

    }
}

2) 두 번째 화면

second2.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/secondTxt"
	android:text="호출된 액티비티"	
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"/>
<Button 
	android:text="액티비티 닫기" 
	android:id="@+id/btnClose1"
	android:layout_width="wrap_content" 
	android:layout_height="wrap_content"/>
</LinearLayout>

ReturnDataSecondActivity.kt

package com.example.intent

import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.second2.*

class ReturnDataSecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.second2)

        val intent = intent
        val code = intent.getStringExtra("code")
        val data = intent.getStringExtra("data")

        btnClose1.setOnClickListener {
            secondTxt.text = data
            // intent.putExtra("second", "두 번째 액티비티에서 실행완료")
            when(code){
                "call2" -> {
                    intent.putExtra("second", "첫 번째 액티비티 두 번째 버튼:$code - $data")
                }
                "call3" -> {
                    intent.putExtra("second", "첫 번째 액티비티 세 번째 버튼:$code - $data")
                }
            }
            // ReturnDataSecondActivity를 호출했던 ReturnDataFirstActivity로 되돌아갈 때, 값을 공유하기 위해서 intent 객체를 다시 넘긴다. - setResult 메소드를 이용해서 처리하기
            // Activity.RESULT_OK 는 정상 완료라는 의미를 담은 액티비티의 상수
            setResult(Activity.RESULT_OK, intent)
            finish()
        }
    }
}

  3. 호출됐던 Activity에서 데이터 전달 예제2

    1) 첫 번째 액티비티

firstexam.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:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이름과 전화번호를 입력하세요."/>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이름: "/>
        <EditText
            android:id="@+id/EditText01"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="홍길동"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="전화번호: "/>
        <EditText
            android:id="@+id/EditText02"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="010-123-4567"/>
    </LinearLayout>
    <Button
        android:id="@+id/Button01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="입력 완료"/>
    <Button
        android:id="@+id/Button02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="객체공유"/>
    <TextView
        android:id="@+id/first_return"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="결과:"
        />
</LinearLayout>

ExamFirstActivity.kt

package com.example.intent

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.firstexam.*

const val PROFILE_CODE = 10

class ExamFirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.firstexam)

        Button01.setOnClickListener {
            val name:String = EditText01.text.toString()
            val tel:String = EditText02.text.toString()
            if(name == "" || tel == ""){
                return@setOnClickListener
            }
            val intent = Intent(this, ExamSecondActivity::class.java)
            intent.putExtra("name", name)
            intent.putExtra("tel", tel)
            startActivityForResult(intent, PROFILE_CODE)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
            PROFILE_CODE -> {
                val result = data?.getIntExtra("result", -1)
                if(result != -1){
                    when(result){
                        1 -> first_return.text = "우수회원설정"
                        0 -> first_return.text = "일반회원설정"
                    }
                }
            }
        }

    }

}

    2) 두 번째 액티비티

secondexam.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ExamSecondActivity">
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="info"/>
    <Button
        android:id="@+id/Button01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="종료"/>
    <CheckBox
        android:id="@+id/Checkbox01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="우수회원"/>
</LinearLayout>

ExamSecondActivity.kt

package com.example.intent

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.secondexam.*

class ExamSecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.secondexam)

        val intent = intent
        val name = intent.getStringExtra("name")
        val tel = intent.getStringExtra("tel")
        TextView01.text = "입력한 id:$name,입력한 pass:$tel"

        Button01.setOnClickListener {
            intent.putExtra("result", when(Checkbox01.isChecked){
                true -> 1
                else -> 0
            })
            setResult(RESULT_OK, intent)
            finish()
        }
    }
}

 

- 끝 -

728x90