學習了來自ApiDemos中的App->Activity->Receive Rseult的應用程式,此程式主要目的是在於熟悉Intent中startActivityForResult的用法,在此紀錄一下心得以及在實作中遇到的現象。
Intent的作用: 作為Activity之間互動的工具。當要將目前的Activity跳轉至另一個Activity時,先前已知道可以使用Intent來達成這項目的,甚至可以利用setExtras來放上附加資訊來傳遞至下一個Activity。(reference: http://hbiao68.iteye.com/blog/1319225)
若今天的情況是Activity_A需要轉至Activity_B,並從Activity_B取得一些資訊後再回到Activity_A中的話要怎麼作呢?
1. 或許使用Intent(Activity_A.this, Activity_B.class)與Intent(Activity_B.this, Activity_A.class)可以達到A跳至B再回到A來,然後將資料用Extras方式傳送與取得。
2. 第二個方式就是這次範例所用到的startActivityForResult方式。關於說明可以在網路上找到很多教學與解釋。目前理解上就是Activity之間從A轉到B,然後在B中取得資料後用setResult方式回傳至A( 如果B程式中沒有結束指令的話當前的Activity仍然還會是B,範例中是以finish()來結束B而回到A。),然後A會去呼叫onActivityResult 函數,在這裡面可以取得B所回傳而來的訊息並作適當處理。
範例程式碼:
OnCreate函數主要在做依layout顯示畫面、設定按鈕監聽功能以及設定TextView可編輯項目。設定TextView可編輯項目這邊依目前實作後的理解是能將顯示過的訊息保存下來,而不會被新的訊息清除掉,在後續的程式中會發現並不是用setText()去顯示,而是用append去添加每一筆訊息於前次訊息之後。
當按鈕按下後表示要執行跳轉到B的程序,其中startActivityForResult(intent, GET_CODE)的GET_CODE是可以用來識別由哪個Activity回傳資訊回來的一項重要參數,在此例中因為只有兩個Activity所以無法發揮作用,但可以想像一下如果App中有多個Activity A,B,C,D,…,假設A會跳轉B或C去取得資料,這時候回傳至A的資料如何分辨是來自B還是C呢,GET_CODE這時就可發揮辨識的作用,之後的範例實作會使用到。
這段程式就是在作取得回傳的資料並將其顯示在畫面上的工作。以下是SendResult程式碼:
實作:
1. 實驗A->B,A->C時資料回傳的辨識方式。
2. setTag與getTag的使用。
程式碼:
注意這邊startActivityForResult第二項參數的不同之處,ActB傳來的requestCode=0,ActC傳來的requestCode=1,在A中的OnActivityResult()函數裡可藉此分辨。
這裡是在實作用Intent來執行觀看聯絡人資訊、編輯聯絡人資訊、撥號畫面、執行撥號、開啟指定網頁、開啟地圖的方法。
透過switch對requestCode的差異進行不一樣的處理,可以分辨出來自B或C回傳的資料。
附上其他Activity的程式碼:
實作結果:
在實作的過程中發現,當旋轉實機畫面時,TextView中的文字訊息會被回復原值(即message)文字,查了一下資料發現,旋轉實機時因為會變更畫面,而變更的方式是採用重啟Activity的方式,而先前的Activity會被殺掉,如果想要實機旋轉後不去改變文字訊息的話,可以將TextView的設定改為freezesText="true",就可以達到效果。
(reference: http://blog.csdn.net/mg505/article/details/7754678)
Intent的作用: 作為Activity之間互動的工具。當要將目前的Activity跳轉至另一個Activity時,先前已知道可以使用Intent來達成這項目的,甚至可以利用setExtras來放上附加資訊來傳遞至下一個Activity。(reference: http://hbiao68.iteye.com/blog/1319225)
若今天的情況是Activity_A需要轉至Activity_B,並從Activity_B取得一些資訊後再回到Activity_A中的話要怎麼作呢?
1. 或許使用Intent(Activity_A.this, Activity_B.class)與Intent(Activity_B.this, Activity_A.class)可以達到A跳至B再回到A來,然後將資料用Extras方式傳送與取得。
2. 第二個方式就是這次範例所用到的startActivityForResult方式。關於說明可以在網路上找到很多教學與解釋。目前理解上就是Activity之間從A轉到B,然後在B中取得資料後用setResult方式回傳至A( 如果B程式中沒有結束指令的話當前的Activity仍然還會是B,範例中是以finish()來結束B而回到A。),然後A會去呼叫onActivityResult 函數,在這裡面可以取得B所回傳而來的訊息並作適當處理。
範例程式碼:
public class ActivityForResult extends Activity {
private TextView texta;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_for_result);
Button btnab = (Button) findViewById(R.id.btnAB);
Button btnac = (Button) findViewById(R.id.btnAC);
Button btnactview = (Button) findViewById(R.id.btnActView);
Button btnactedit = (Button) findViewById(R.id.btnActEdit);
Button btnactdial = (Button) findViewById(R.id.btnActDial);
Button btnactweb = (Button) findViewById(R.id.btnActWeb);
Button btnactcall = (Button) findViewById(R.id.btnActCall);
Button btnactmap = (Button) findViewById(R.id.btnActMap);
btnab.setOnClickListener(btnabListener);
btnac.setOnClickListener(btnacListener);
btnactview.setTag(0);
btnactedit.setTag(1);
btnactdial.setTag(2);
btnactcall.setTag(3);
btnactmap.setTag(4);
btnactweb.setTag(5);
btnactview.setOnClickListener(btnactListener);
btnactedit.setOnClickListener(btnactListener);
btnactdial.setOnClickListener(btnactListener);
btnactcall.setOnClickListener(btnactListener);
btnactmap.setOnClickListener(btnactListener);
btnactweb.setOnClickListener(btnactListener);
texta = (TextView) findViewById(R.id.textA);
texta.setText(texta.getText(), TextView.BufferType.EDITABLE);
}
OnCreate函數主要在做依layout顯示畫面、設定按鈕監聽功能以及設定TextView可編輯項目。設定TextView可編輯項目這邊依目前實作後的理解是能將顯示過的訊息保存下來,而不會被新的訊息清除掉,在後續的程式中會發現並不是用setText()去顯示,而是用append去添加每一筆訊息於前次訊息之後。
static final private int GET_CODE = 0;
private OnClickListener mGetListener = new OnClickListener() {
public void onClick(View v) {
// Start the activity whose result we want to retrieve. The
// result will come back with request code GET_CODE.
Intent intent = new Intent(ReceiveResult.this, SendResult.class);
startActivityForResult(intent, GET_CODE);
}
};
當按鈕按下後表示要執行跳轉到B的程序,其中startActivityForResult(intent, GET_CODE)的GET_CODE是可以用來識別由哪個Activity回傳資訊回來的一項重要參數,在此例中因為只有兩個Activity所以無法發揮作用,但可以想像一下如果App中有多個Activity A,B,C,D,…,假設A會跳轉B或C去取得資料,這時候回傳至A的資料如何分辨是來自B還是C呢,GET_CODE這時就可發揮辨識的作用,之後的範例實作會使用到。
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
// You can use the requestCode to select between multiple child
// activities you may have started. Here there is only one thing
// we launch.
if (requestCode == GET_CODE) {
// We will be adding to our text.
Editable text = (Editable)mResults.getText();
// This is a standard resultCode that is sent back if the
// activity doesn't supply an explicit result. It will also
// be returned if the activity failed to launch.
if (resultCode == RESULT_CANCELED) {
text.append("(cancelled)");
// Our protocol with the sending activity is that it will send
// text in 'data' as its result.
} else {
text.append("(okay ");
text.append(Integer.toString(resultCode));
text.append(") ");
if (data != null) {
text.append(data.getAction());
}
}
text.append("\n");
}
}
這段程式就是在作取得回傳的資料並將其顯示在畫面上的工作。以下是SendResult程式碼:
public class SendResult extends Activity
{
/**
* Initialization of the Activity after it is first created. Must at least
* call {@link android.app.Activity#setContentView setContentView()} to
* describe what is to be displayed in the screen.
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
// Be sure to call the super class.
super.onCreate(savedInstanceState);
// See assets/res/any/layout/hello_world.xml for this
// view layout definition, which is being set here as
// the content of our screen.
setContentView(R.layout.send_result);
// Watch for button clicks.
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(mCorkyListener);
button = (Button)findViewById(R.id.violet);
button.setOnClickListener(mVioletListener);
}
private OnClickListener mCorkyListener = new OnClickListener()
{
public void onClick(View v)
{
// To send a result, simply call setResult() before your
// activity is finished.
setResult(RESULT_OK, (new Intent()).setAction("Corky!"));
finish();
}
};
private OnClickListener mVioletListener = new OnClickListener()
{
public void onClick(View v)
{
// To send a result, simply call setResult() before your
// activity is finished.
setResult(RESULT_OK, (new Intent()).setAction("Violet!"));
finish();
}
};
}
實作:
1. 實驗A->B,A->C時資料回傳的辨識方式。
2. setTag與getTag的使用。
程式碼:
package com.example.activityforresulttest;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ActivityForResult extends Activity {
private TextView texta;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity_for_result);
Button btnab = (Button) findViewById(R.id.btnAB);
Button btnac = (Button) findViewById(R.id.btnAC);
Button btnactview = (Button) findViewById(R.id.btnActView);
Button btnactedit = (Button) findViewById(R.id.btnActEdit);
Button btnactdial = (Button) findViewById(R.id.btnActDial);
Button btnactweb = (Button) findViewById(R.id.btnActWeb);
Button btnactcall = (Button) findViewById(R.id.btnActCall);
Button btnactmap = (Button) findViewById(R.id.btnActMap);
btnab.setOnClickListener(btnabListener);
btnac.setOnClickListener(btnacListener);
//因以下按鈕觸發後執行的工作相近,利用Tag可以共用一個觸發函數
btnactview.setTag(0);
btnactedit.setTag(1);
btnactdial.setTag(2);
btnactcall.setTag(3);
btnactmap.setTag(4);
btnactweb.setTag(5);
btnactview.setOnClickListener(btnactListener);
btnactedit.setOnClickListener(btnactListener);
btnactdial.setOnClickListener(btnactListener);
btnactcall.setOnClickListener(btnactListener);
btnactmap.setOnClickListener(btnactListener);
btnactweb.setOnClickListener(btnactListener);
texta = (TextView) findViewById(R.id.textA);
texta.setText(texta.getText(), TextView.BufferType.EDITABLE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_activity_for_result, menu);
return true;
}
private OnClickListener btnabListener = new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(ActivityForResult.this,ActB.class);
startActivityForResult(intent,0);
}
};
private OnClickListener btnacListener = new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(ActivityForResult.this,ActC.class);
startActivityForResult(intent,1);
}
};
注意這邊startActivityForResult第二項參數的不同之處,ActB傳來的requestCode=0,ActC傳來的requestCode=1,在A中的OnActivityResult()函數裡可藉此分辨。
private OnClickListener btnactListener = new OnClickListener(){
public void onClick(View v){
Intent intent = new Intent();
int tag = (Integer) v.getTag();
String data;
Uri uri;
switch(tag){
case 0:
data = "content://contacts/people/1";
uri = Uri.parse(data);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
break;
case 1:
data = "content://contacts/people/1";
uri = Uri.parse(data);
intent.setAction(Intent.ACTION_EDIT);
intent.setData(uri);
break;
case 2:
data = "tel:13811111111";
uri = Uri.parse(data);
intent.setAction(Intent.ACTION_DIAL);
intent.setData(uri);
break;
case 3:
data = "tel:13811111111";
uri = Uri.parse(data);
intent.setAction(Intent.ACTION_CALL);
intent.setData(uri);
break;
case 4:
data = "geo://39.92,116.46";
uri = Uri.parse(data);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
break;
case 5:
data = "http://www.google.com";
uri = Uri.parse(data);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
break;
default:
break;
}
startActivity(intent);
}
};
這裡是在實作用Intent來執行觀看聯絡人資訊、編輯聯絡人資訊、撥號畫面、執行撥號、開啟指定網頁、開啟地圖的方法。
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data){
Editable text = (Editable)texta.getText();
switch(requestCode){
case 0:
if(resultCode == RESULT_CANCELED){
text.append("B:Cancelled!!");
}
else{
text.append("B: ok("+Integer.toString(resultCode)+")- ");
if(data!=null){
text.append(data.getAction());
}
}
text.append("\n");
break;
case 1:
if(resultCode == RESULT_CANCELED){
text.append("C:Cancelled!");
}
else{
text.append("C: Hello");
}
text.append("\n");
break;
default:
break;
}
}
}
透過switch對requestCode的差異進行不一樣的處理,可以分辨出來自B或C回傳的資料。
附上其他Activity的程式碼:
package com.example.activityforresulttest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class ActB extends Activity {
private EditText editb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_act_b);
Button btnb = (Button) findViewById(R.id.btnB);
btnb.setOnClickListener(btnbListener);
editb = (EditText) findViewById(R.id.editTB);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_act_b, menu);
return true;
}
private OnClickListener btnbListener = new OnClickListener(){
public void onClick(View v){
String input = editb.getText().toString();
setResult(RESULT_OK,(new Intent()).setAction(input));
finish();
}
};
}
package com.example.activityforresulttest;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActC extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_act_c);
Button btnc = (Button) findViewById(R.id.btnC);
btnc.setOnClickListener(btncListener);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_act_c, menu);
return true;
}
private OnClickListener btncListener = new OnClickListener(){
public void onClick(View v){
setResult(RESULT_OK);
finish();
}
};
}
實作結果:
在實作的過程中發現,當旋轉實機畫面時,TextView中的文字訊息會被回復原值(即message)文字,查了一下資料發現,旋轉實機時因為會變更畫面,而變更的方式是採用重啟Activity的方式,而先前的Activity會被殺掉,如果想要實機旋轉後不去改變文字訊息的話,可以將TextView的設定改為freezesText="true",就可以達到效果。
(reference: http://blog.csdn.net/mg505/article/details/7754678)
留言
張貼留言