ImplicitIntent.zip


Result


    





activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<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"
    android:padding="32dp"
    tools:context=".MainActivity">
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="웹 사이트 열기"
        android:textSize="20sp"
        android:onClick="onClickOpenWebpageButton"/>
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="지도에서 위치 열기"
        android:textSize="20sp"
        android:onClick="onClickOpenAddressButton"/>
 
    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="텍스트를 공유하기"
        android:textSize="20sp"
        android:onClick="onClickShareTextButton"/>
 
</LinearLayout>
cs




MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.tistory.qlyh8.implicitintent;
 
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.ShareCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
 
public class MainActivity extends AppCompatActivity {
 
    private String url = "http://qlyh8.tistory.com";
    private String address = "강남역";
    private String shareText = "공유할 텍스트";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    //버튼을 누르면 지정한 웹 페이지를 보여준다.
    public void onClickOpenWebpageButton(View view) {
        //파라미터로 받은 URL 을 파싱하여 ACTION_VIEW 를 통해 특정 콘텐츠를 볼 수 있다.
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
 
        // 경우에 따라 이 코드가 실행되는 장치에는 지정한 데이터로 작업을 수행하기 위한 활동이 없을 수도 있다.
        // 이 검사가 없으면 앱이 죽는다.
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        }
    }
 
    //버튼을 누르면 해당되는 위치의 지도를 보여준다.
    public void onClickOpenAddressButton(View view) {
        //URI를 생성하는 방법 1. parse() 이용 2. builder 이용 (권장)
        //Builder 를 이용해 URI 를 생성한다.
        //Uri.Builder builder = new Uri.Builder();
        /*
        * geo URI 는 geo scheme, 위도와 경도, 그리고
        * 옵션으로 들어가는 도로명 주소나 회사명을 나타내는 쿼리 파라미터와 줌 레벨로 구성되어 있다.
        * 쿼리 파라미터가 있다면 위도와 경도 path 는 반드시 “0,0”이 되어야 한다.
        * geo:0,0?q=Antwerp,Belgium&z=10 를 예로 들었을 때
        * 벨기에의 Antwerp 라는 도시를 줌 레벨 10으로 보여주는 geo 의 URI 이다.
        * */
        /*Uri addressUri = builder.scheme("geo")
                                .path("0,0")
                                .query(address)
                                .build();*/
        Uri addressUri = Uri.parse("geo:0,0?q=" + address);
 
        //지정된 URL 을 요청하는 인텐트를 생성한다.
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //인텐트에 URI 를 설정한다.
        intent.setData(addressUri);
 
        //인텐트를 시작할 수 있는지 검사한다.
        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivity(intent);
        }
    }
 
    //공유 버튼을 누르면 디바이스에서 해당 타입의 인텐트를 처리할 수 있는 모든 앱을 보여준다.
    public void onClickShareTextButton(View view) {
        /*
        * MIME 형식은 어떤 응용 프로그램이 어떤 내용을 열 수 있는지 컴퓨터가 판단하는 데 도움이 된다.
        * MIME (Multipurpose Internet Mail Extension, 다목적 인터넷 메일 확장자)
        * 예를 들어 .pdf 파일을 두 번 클릭하면 PDF 를 열 수있는 프로그램 목록이 표시된다.
        * MIME 유형을 text/plain 을 지정하면 이 특정 인텐트에서 startActivity 를 호출 할 때
        * 텍스트 콘텐츠를 어떤 방식으로든 처리할 수 있는 모든 앱이 제공된다.
        *
        * top-level type name / subtype name [ ; parameters ]
        * top-level type 과 Sub type, 그리고 옵션 파라미터로 구성된다.
        * type/html; charset=UTF-8 을 예로 들면
        * 데이터의 타입은 HTML 텍스트, UTF-8 문자셋 인코딩으로 구성되어 있다.
        * 일반 텍스트 ex) text/plain
        * png 이미지 파일 ex) image/png
        *
        * 데이터를 공유할 때는 반드시 미디어 타입을 명시해서
        * 안드로이드가 요청을 어떻게 처리할 수 있는지,
        * 또는 처리가 가능한 지 여부를 결정할 수 있게 해줘야 한다.
        * */
        String mimeType = "text/plain";
 
        /*
        * ShareCompat 이라는 헬퍼 클래스와 이것의 내부 클래스 IntentBuilder 는
        * 데이터 타입 또는 파일의 개수 등의 고려할 사안들을 추상화해 일련의 작업을 쉽게 해준다.
        * */
        ShareCompat.IntentBuilder
                /* from 메서드는 공유가 들어오는 컨텍스트를 지정한다. */
                .from(this)
                /* 미디어 타입 */
                .setType(mimeType)
                /* startActivity 를 호출 할 때 나타나는 팝업 제목 */
                .setChooserTitle("Title for Sharing")
                .setText(shareText)
                .startChooser();
    }
}
 
cs



Android Course of Udacity - Lesson 4

ExplicitIntent.zip


Result





Apply Intent to Code


1. Add a New Layout and a New Activity

2. Passing Data Between Activities

3. Start New Activity




activity_main.xml에 EditText와 Button을 추가하여 activity_child에 전달하기 위한 준비를 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity">
 
    <EditText
        android:id="@+id/et_text_entry"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
 
    <Button
        android:id="@+id/b_do_something_cool"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button"/>
 
</LinearLayout>
cs




activity_child.xml를 생성하여 activity_main에서 전달받은 값을 받을 TextView를 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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"
    tools:context=".ChildActivity">
 
    <TextView
        android:id="@+id/tv_display"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is default text."
        android:textSize="30sp"/>
 
</FrameLayout>
cs




ChildActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.tistory.qlyh8.intent1;
 
/*
 * Created by YUNHEE on 2018-01-01.
 */
 
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
 
public class ChildActivity extends AppCompatActivity {
 
    private TextView mDisplayText;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);
 
        mDisplayText = findViewById(R.id.tv_display);
 
        //특정 액티비티를 시작한 인텐트를 제공한다.
        Intent intentThatStartedThisActivity = getIntent();
 
        /*
         * 특정 액티비티를 시작하는 인텐트가 항상 있지만,
         * 받으려는 Extra가 잘 전달되었다고 보장 할 수는 없다.
         * 따라서 인텐트를 만들 때 지정한 Extra가 인텐트에 포함되어 있는지 확인해야 한다.
         * 이 액티비티가 다른 메소드에 의해 시작된 경우, 이 Extra는 인텐트에 존재하지 않을 수 있다.
         * */
        if (intentThatStartedThisActivity.hasExtra(Intent.EXTRA_TEXT)) {
 
            //전달받은 값을 꺼낸다.
            String textEntered = intentThatStartedThisActivity.getStringExtra(Intent.EXTRA_TEXT);
            mDisplayText.setText(textEntered);
        }
    }
}
 
cs




MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.tistory.qlyh8.intent1;
 
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
 
public class MainActivity extends AppCompatActivity {
 
    private EditText mNameEntry;
    private Button mDoSomethingCoolButton;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mDoSomethingCoolButton = findViewById(R.id.b_do_something_cool);
        mNameEntry = findViewById(R.id.et_text_entry);
 
        mDoSomethingCoolButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //인텐트를 사용하면 새로운 액티비티가 사용할 정보를 전달할 수 있다.
                Intent startChildActivityIntent = new Intent(MainActivity.this, ChildActivity.class);
                //전달하고자 하는 데이터를 인텐트에 넣어준다.
                startChildActivityIntent.putExtra(Intent.EXTRA_TEXT,  mNameEntry.getText().toString());
                //두 액티비티 간의 이동을 하는 인텐트를 파라미터로 받는 메소드
                startActivity(startChildActivityIntent);
            }
        });
    }
}
 
cs




AndroidManifest.xml에 ChildActivity를 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tistory.qlyh8.intent1">
 
    <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=".ChildActivity"/>
    </application>
 
</manifest>
cs



Android Course of Udacity - Lesson 4

Intents Framework


인텐트라 불리는 메시징 객체를 사용해 상호 통신을 쉽게 만들어준다.

앱은 인텐트를 사용해 특정 액션이 일어나게 요청을 할 수 있다.


각 인텐트는 기본 자료형 튜플인 Extra로 패키징되어, 어느 컴포넌트에 전달할 지에 관한 정보를 포함하고 있다.

애플리케이션 컴포넌트는 인텐트를 수신하고 열어서 이 데이터를 읽는다.



What are Implicit Intents?

어디에 요청을 보내야 할 지 모르거나 어디에 요청을 보내던 상관없는 경우에 사용한다.


두개 이상의 앱이 있다면 안드로이드는 사용자가 특정 요청에 대해 어떤 앱을 사용할지 선택하게 하고

앞으로도 해당 요청에 대해 계속 선택한 앱을 사용할지 물어본다.


전화, 지도, 공유 등이 암시적 인텐트이다.



Creating Implicit Intents


대부분의 암시적 인텐트는 액션과 데이터를 포함하고 있다.

액션은 어떤 작업을 하려는지를 나타내고, 데이터는 그 액션에 넘겨주고자 하는 내용이다.

인텐트는 모든 데이터를 URI로 받는데, 이는 액션에 넘겨주고자 하는 데이터를 가리키는 주소이다.



Understanding URIs


URI (Uniform Resource Identifier, 통합 자원 식별자)는 자원을 식별하는 일련의 문자이다.

URL (Uniform Resource Locator)는 웹 또는 네트워크의 자원을 식별하는 URI이다.


URI의 전체 형식은 아래와 같다.

scheme : [// [user:password @] host [:port] ] [/] path [?query] [#fragment]

[ ]는 옵션이다.


scheme

scheme은 어떤 타입의 자원을 가리키는지 나타낸다.

웹에서 유명한 scheme은 HTTP, HTTPS, mailto, FTP, file, geo 등이 있다.

scheme에 따라 이 뒤에는 슬래시(/) 2개와 authority 부분이 따라 올 수도 있다.


authority

authority는 로그인을 하기 위해 유저 이름과 아이디를 넣는 옵션과,

도메인 네임 또는 IP 주소가 될 수 있는 호스트 네임, 그리고 옵션인 포트가 있다.

따로 명시되지 않는 이상 브라우저는 HTTP 요청에 대해 80번 포트를 가정한다.


path

authority 부분 다음에는 자원에 대한 path(경로)가 나온다.

만약 authority 부분이 있다면 authority와 path 사이에는 반드시 ‘/’가 있어야 한다.


http://qlyh8.tistory.com/category/Android 를 예로 들었을 때

qlyh8.tistory.com 을 호스트로 갖고있는 authority 부분이 있고, category/Android인 path 부분이 있다.


mailto는 authority 부분이 필요하지 않은 scheme이고 path만 있어도 작동한다.

이 경우에 path는 이메일을 보내고자 하는 대상이다.


query

query는 물음표로 시작한다는 것 외에 필수적인 규약이 없다.

key-value 쌍으로 데이터를 표시하는 것이 일반적이긴 하지만 꼭 그래야하는 것은 아니다.

geo:0,0?q=Montreal,Canada의 query는 Montreal,Canada이다.


fragment

자원 경로의 부차적인 위치를 가리키는 fragment는 ‘#’(hash)로 시작한다.

경로와 브라우저는 실행되는 애플리케이션에 따라 다르다.



Android Course of Udacity - Lesson 4

+ Recent posts