第十一章 Intent

      在〈第十一章 Intent〉中尚無留言

Android的每一個畫面都是一個Activity元件, 多個畫面就需要有多個Activity元件.

主畫面設定檔

應用程式啟動後, 第一個出現的畫面叫主畫面. 在AndroidManifest.xml 設定檔的架構如下

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    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>
</application>

<category android:name=”android.intent.category.LAUNCHER” /> 為應用程式啟動後第一個執行的畫面, 此設定固定不變

切換新增Activity元件

假如今天有A這個主畫面, 然後想到切換到B的畫面, 就需要使用Intent的方式來執成. 底下的說明步驟實際演練一次.

1. 開啟res/layout/activtiy_main.xml, 改為LinearLayout, 放置一個EditText : editTel, 及一顆按鈕 : btnFirst, Text改為 “切換”

<?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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.MainActivity"
    android:orientation="vertical">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:id="@+id/editTel"
        android:inputType="phone" />
    <Button
        android:text="切換"
        android:onClick="btnFirst_click"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnFirst"/>
</LinearLayout>

2. 在專案按右鍵/new/Activity/Empty Activity, Activity name : SecondActivity, Layout name : activity_second.xml
3.  開啟activity_second.xml, Layout改為LinearLayout, 然後放置一顆按鈕, id為btnSecond, Text改為”返回”

<?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:id="@+id/activity_second"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.SecondActivity"
    android:orientation="vertical">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:text="電話 : "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView1"/>
        <TextView
            android:text="TextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/txtTel"/>
    </LinearLayout>
    <Button
        android:text="返回"
        android:onClick="btnSecond_click"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnSecond" />
</LinearLayout>

4. 開啟AndroidManifest.xml設定檔, 將設定檔改為如下

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    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=".SecondActivity"
        android:label="第二個畫面">
    </activity>
</application>

5. MainActivity.java如下

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void btnFirst_click(View view){
        Intent intent=new Intent(this, SecondActivity.class);
        startActivity(intent);
    }
}

AndroidManifest.xml設定檔

每新增一個Activity元件, 就需要在設定檔新增<activity>標簽. <activity>標簽常用設定如下
android:name : 元件類別名稱
android:screenOrientation : 有portrait, landscape, locked

<activity
    android:name=".SecondActivity"
    android:screenOrientation="landscape"
    android:label="第二個畫面">
</activity>

Intent

Intent類別用來啟動另一個Activity元件, Service元件, 或是發送廣播. 其建構子有三種
Intent(Context, Class) : 由目前的Context轉換到Class
Intent(String) : 轉換到action
Intent() : 調用setAction()後再進行轉換

class

如上例, 直接new 出Intent, 指定由 this轉換到SecondActivity.class, 再用startActivity(intent)開始進行切換

action

在<activity>標簽中加入如下

<activity
    android:name=".SecondActivity"
    android:screenOrientation="landscape"
    android:label="第二個畫面">
    <intent-filter>
        <action android:name="com.asuscomm.mahaljsp.IntentTest.Second" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

<action android:name>請輸入獨一無二之名稱, 而<category android:name=”android.intent.category.DEFAULT” />則為一般的Action.
若為 category.LAUNCHER, 則表示是第一個主畫面.

而在Java程式中使用如下方式啟動

public void btnFirst_click(View view){
    Intent intent=new Intent("com.asuscomm.mahaljsp.IntentTest.Second");
    startActivity(intent);
}

傳送與接收資料

傳送資料

當由主畫面A切換到B畫面時, 若要連同一些資料也傳送給B, 則可以把資料放入Intent中一起傳送. Intent類別提供 putExtra(字串, 資料)方法. 第二個參數可以是八大原生基本資料, 也可以是String, CharSequence. 另還有一個特殊的Bundle物件

public void btnFirst_click(View view){
    Intent intent=new Intent("com.asuscomm.mahaljsp.IntentTest.Second");
    intent.putExtra("Tel", editTel.getText().toString());
    startActivity(intent);
}

Bundle

Bundle可以把不同的資料形態包在一起, 再使用Intent類別的putExtra(String, Bundle)傳送給啟動元件. 首先創造一個Bundle物件.
Bundle bundle=new Bundle();
再用bundle.putInt(String, int), bundle.putString(String, String)等方法將資料包入Bundle物件. 之後就可以使用Intent的putExtra(String, Bundle), 或putExtras(Bundle)傳送出去

public void btnFirst_click(View view){
    Intent intent=new Intent("com.asuscomm.mahaljsp.IntentTest.Second");
    Bundle bundle=new Bundle();
    bundle.putInt("Age", 23);
    bundle.putString("Tel", editTel.getText().toString());
    intent.putExtra("Info", bundle);
    startActivity(intent);
}

接收資料

被呼叫端啟動後, 可先使用getIntent()取得傳送進來的Intent物件. 再由Intent的intent.getIntExtra(String, default), intent.getStringExtra(String)等方法取得資料.

如果傳送進來的是Bundle物件, 則可使用下列二種方式取得Bundle物件
Bundle bundle=intent.getExtras();
Bundle bundle=intent.getBundleExtra(String);

然後再由bundle.getString(), bundle.getInt()等方式取得資料

回傳

當由主畫面A切換到B畫面, 然後又要由B切回A時, 稱為回傳. 此時由A切到B需使用startActivityForResult(intent, requestCode)進行切換. 待B切回A時, 會執行A的
protected void onActivityResult(int requestCode, int resultCode, Intent data)方法

resultCode是指由B切回的狀況, 有Activity.RESULT_OK及Activity.RESULT_CANCELED二種. 請注意, 當使用者按back鍵切回A, 是屬於Activity.RESULT_CANCELED.

requestCode是由A切換到B, 再切回來A的識別碼, 可用此碼判斷是A的那一個按鈕動作的

接收端B接收Intent後, 若想傳回值給A, 則需使用原來的Intent物件, 置入資料後, 再使用setResult(resultCode, Intent)回傳, 最後再把B自己finish();

完整範例如下

android_intent_1

android_intent_2

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.asuscomm.mahaljsp.ch11_01_newactivity">
    <application
        android:allowBackup="true"
        android:icon="@drawable/lpic"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:screenOrientation="locked"
            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=".SecondActivity"
            android:label="請選擇行星">
            <intent-filter>
                <action android:name="com.asuscomm.mahaljsp.IntentTest.Second" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="planet_array">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
        <item>Jupiter</item>
        <item>Saturn</item>
        <item>Uranus</item>
        <item>Neptune</item>
        <item>Pluto</item>
    </string-array>
</resources>

activity_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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.MainActivity"
    android:orientation="vertical">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:text="1  "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textView"
            android:textSize="20sp" />
        <TextView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:id="@+id/txt1"/>
        <ImageButton
            android:onClick="onClick"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            app:srcCompat="?android:attr/actionModeWebSearchDrawable"
            android:id="@+id/bt1"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:text="2  "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:id="@+id/textView2"/>
        <TextView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:id="@+id/txt2"/>
        <ImageButton
            android:onClick="onClick"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            app:srcCompat="?android:attr/actionModeWebSearchDrawable"
            android:id="@+id/bt2"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:text="3  "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:id="@+id/textView3"/>
        <TextView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:id="@+id/txt3"/>
        <ImageButton
            android:onClick="onClick"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            app:srcCompat="?android:attr/actionModeWebSearchDrawable"
            android:id="@+id/bt3"/>
    </LinearLayout>
</LinearLayout>

activity_second.xml

<?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:id="@+id/activity_second"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.asuscomm.mahaljsp.ch11_01_newactivity.SecondActivity"
    android:orientation="vertical">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </LinearLayout>
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/listView" />
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    TextView txt1, txt2, txt3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        processViews();
    }
    public void processViews(){
        txt1=(TextView)findViewById(R.id.txt1);
        txt2=(TextView)findViewById(R.id.txt2);
        txt3=(TextView)findViewById(R.id.txt3);
    }
    public void onClick(View view){
        Intent intent=new Intent(this, SecondActivity.class);
        int requestCode=0;
        switch(view.getId()){
            case R.id.bt1:
                requestCode=0;
                break;
            case R.id.bt2:
                requestCode=1;
                break;
            case R.id.bt3:
                requestCode=2;
                break;
        }
        startActivityForResult(intent, requestCode);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String planet=data.getStringExtra("Planet");
        if(resultCode== Activity.RESULT_OK){
            switch(requestCode){
                case 0:
                    txt1.setText(planet);
                    break;
                case 1:
                    txt2.setText(planet);
                    break;
                case 2:
                    txt3.setText(planet);
                    break;
            }
        }
    }
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {
    ListView listView;
    Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        processViews();
        processControllers();
    }
    public void processViews(){
        intent=getIntent();
        listView=(ListView)findViewById(R.id.listView);
    }
    public void processControllers(){
        listView.setAdapter(ArrayAdapter.createFromResource(
                this, R.array.planet_array, android.R.layout.simple_list_item_1));
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                String s=adapterView.getItemAtPosition(i).toString();
                intent.putExtra("Planet", s);
                setResult(Activity.RESULT_OK, intent);
                SecondActivity.this.finish();
            }
        });
    }
}

啟動系統內建Acitivty

Android系統內鍵了許多的Activity元件, 比如撥打電話, 傳送簡訊, web 搜尋, 地圖導覽. 所以在我們自己開發的應用程式中, 可以直接呼叫.

系統內建的Activity都有設定<action>標簽. 但action 名稱又過長, 所以Intent類別就定義了幾個長用的變數, 比如android.intent.action.DIAL, 可以直接使用Intent.ACTION_DIAL來呼叫.

當呼叫這些Activity元件時, 若需要傳入資料, 可先使用如 Uri uri=Uri.parse(“tel:0987454123”)的格式, 利用parse()的方法將字串轉成Uri物件, 然後再用Intent的setData(Uri)將資料傳入

打電話

打電話的Action有ACTION_DIAL : 準備打電話, aCTION_CALL : 立即打電話, 程式碼如下

Intent intent=new Intent();
intent.setAction(Intent.ACTION_DIAL);
Uri uri=Uri.parse("tel:0987454123");
intent.setData(uri);
startActivity(intent);

android_dial


簡訊

Intent intent=new Intent(Intent.ACTION_SENDTO);
Uri uri=Uri.parse("smsto:0987454123");
intent.setData(uri);
intent.putExtra("sms_body", "測試簡訊傳遞");
startActivity(intent);

android_sms


電子郵件

Intent intent=new Intent(Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(Intent.EXTRA_EMAIL, "mahaljsp@gmail.com");
intent.putExtra(Intent.EXTRA_SUBJECT,"eMail測試");
intent.putExtra(Intent.EXTRA_TEXT, "這是郵件的內容");
startActivity(Intent.createChooser(intent, "Send EMail")); //會彈出要使用那一支應用程式

網頁搜尋

Intent intent=new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, "mahaljsp");
startActivity(intent);

網頁瀏覽

Intent intent=new Intent(Intent.ACTION_VIEW);
Uri uri=Uri.parse("");
intent.setData(uri);
startActivity(intent);

顯示地圖

Intent intent=new Intent(Intent.ACTION_VIEW);
String point="24.06,120.5232";
String zoom="16";
Uri uri=Uri.parse("geo:"+point+"?z="+zoom);
intent.setData(uri);
startActivity(intent);

地圖導航

Intent intent=new Intent(Intent.ACTION_VIEW);
String from="24.06,120.5232";
String to="24.0816363,120.5362556";
Uri uri=Uri.parse("http://maps.google.com/maps?f=d&saddr="+from+"&daddr="+to);
intent.setData(uri);
startActivity(intent);

街景服務

Intent intent=new Intent(Intent.ACTION_VIEW);
String point="24.0813997,120.5388488";
String direction="0";
String streetZoom="1.0";
String vertical="0";
String zoom="16";
Uri uri=Uri.parse("google.streetview:cbll="+point+"&cbp=1,"+direction+
        ",,"+streetZoom+",0&mz="+zoom);
intent.setData(uri);
startActivity(intent);

android_street

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *