標籤:android 基礎 activity intent 意圖過濾器
- Activity簡介
- Activity的簡單使用
- Activity之間的跳轉
- 意圖傳遞資料
- 建立Activity擷取返回資料
- 如何調用系統傳送簡訊的頁面
- 如何傳送簡訊
Activity簡介
Activity是Android的四大組件之一,它用於展示介面。它提供一個螢幕,使用者可以用來互動,可以通過setContentView(View)來顯示指定的控制項。
在一個android應用中,一個Activity通常就是一個單獨的螢幕,它上面可以顯示一些控制項也可以監聽並處理使用者的事件做出響應。Activity之間通過Intent進行通訊。
Activity的簡單使用
① 定義類繼承Activity
-
② 在AndroidManifest.xml的
<application>節點中聲明
<activity>
-
☆
<application>:中lable是指程式的名字,在卸載頁面顯示的名字就是這個lable指定的。
-
☆<activity>中的lable是指activity的名字,如果此activity還指定了以下intent-filter,那麼這個介面就會在案頭建立捷徑,捷徑名字就是這個activity的lable。
<category>:指定意圖的類別,LAUNCHER是在案頭建立捷徑。
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /></intent-filter>
-
Activity在資訊清單檔中的配置
-
①Lable屬性:Activity頁面的標題,介面的名字,如果此介面被建立捷徑,則捷徑的名字就是lable值。
-
②Name屬性:指定的值為:包名.Activity類名。包名如果與mainfest的package一致,可以用“.”代替;或者不寫。
-
③Intent-filter子節點:添加意圖過濾,可以通過隱式意圖啟動。可以在案頭產生捷徑,增加應用程式的入口。
-
④Icon屬性:指定應用程式的表徵圖
-
⑤android:theme屬性:指定主題android:theme=”@android:style/Theme.Dialog”
-
如何讓程式有多個啟動入口
-
建立一個SecondActivity並在資訊清單檔中聲明,且修改兩個<activity>的android:label值。
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.bzh.launch.MainActivity" android:label="我是入口1" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.bzh.launch.SecondActivity" android:label="我是入口2" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity></application>
測試結果圖如下:
我們可以看到,在應用程式資訊清單中多了兩個應用表徵圖我是入口1 和我是入口2,分別開啟後所對應的就是資訊清單檔中聲明的Activity。
Activity之間的跳轉
-
什麼是意圖?
-
即Intent,用於啟用組件,Android的組件都可以通過intent去啟用。
-
Activity之間的跳轉分為兩種
-
①顯式意圖跳轉:知道跳轉目標的類名,並且可以拿到其位元組碼對象。一般用於自己程式的內部。一般用於自己程式的內部。顯式跳轉不可以跳轉到其他程式的頁面中。
//建立一個Intent對象,並傳遞當前對象(Context對象)和要跳轉的Activity類位元組碼Intent intent = new Intent(this, SecondActivity.class);//啟動第二個ActivitystartActivity(intent);
-
②隱式意圖跳轉::可以在當前程式跳轉到另一個程式的頁面。隱式跳轉不需要引用到那個類,但是必須得知道那個介面的動作(action)和資訊(category);因此,能夠被隱式跳轉的Activity,在資訊清單檔中聲明時必須指定動作和資訊這兩個屬性。
-
顯式意圖是指在建立意圖時指定了組件,而隱式意圖則不指定組件,通過動作、類型、資料匹配對應的組件。
-
當我們為一個Activity增加如下的過濾器時,
<intent-filter > <!-- 在意圖過濾器中設定action和category,當有匹配的action和category的時候啟動該Activity。這裡使用Android提供的預設category即可 --> <action android:name="com.itheima.activitySkip.SecondActivity"/> <category android:name="android.intent.category.DEFAULT"/></intent-filter>
-
那麼想要啟用這個Activity的話,需要在intent中指定動作和類型
//建立一個Intent對象Intent intent = new Intent();//設定Actionintent.setAction("com.bzh.SecondActivity");//對於android.intent.category.DEFAULT類型的資訊為Android系統預設的資訊,省略也可以intent.addCategory("android.intent.category.DEFAULT");//啟動ActivitystartActivity(intent);
意圖傳遞資料
Intent除了可以啟用組件(啟動Activity等),還可以通過封裝的Bundle對象來攜帶資料。所以在啟動一個Activity的時候,同時還可以傳遞資料,然後在新的Activity中可以獲得意圖對象以擷取其中Bundle儲存的資料。
Intent可傳遞的資料類型有: 八大基礎資料型別 (Elementary Data Type),String,數組,ArrayList<String>, Bundle資料捆, 實現序列化介面的javabean。
實現Serizlizable可以再網路中傳輸
實現Parcelable可以序列化到記憶體中
注意: Intent傳遞的資料過多可能會造成跳轉速度極慢甚至黑屏一會,不要用Intent傳遞過多的資料,會影響到應用程式的使用。
-
使用意圖過濾器資料協議傳遞資料
-
設定資料協議和配置資料的mimeType,從而達到傳遞資料的目的
-
① 在資訊清單檔中配置意圖過濾器
<activity android:name="com.bzh.SecondActivity"><!-- 配置意圖過濾器 --><intent-filter > <!-- 在意圖過濾器中設定action和category,當有匹配的action和category的時候啟動該Activity --> <action android:name="com.bzh.SecondActivity"/> <!-- 設定資料協議 --> <data android:scheme="money"/> <!-- 配置資料的mimeType:必須為xxx/xxx的格式,否則會報異常 --> <data android:mimeType="data/mymime"/> </intent-filter></activity>
-
② 在FristActivity中啟用意圖,並使用資料協議,設定資料。
// 建立一個Intent對象Intent intent = new Intent();// 設定Actionintent.setAction("com.bzh.SecondActivity");// 對於android.intent.category.DEFAULT類型的資訊為Android系統預設的資訊,省略也可以intent.addCategory("android.intent.category.DEFAULT");intent.setDataAndType(Uri.parse("money:轉賬100元。"), "data/mymime");
-
③ 在SecondActivity中使用getIntent()擷取到意圖,並拿到資料
//擷取從當前Context對象中擷取IntentIntent intent = getIntent();//注意這個是getIntent()//擷取資料String data = intent.getData().toString();System.out.println(data);
-
使用意圖的Bundle傳遞資料
-
Google在Intent中提供了大量的重載的putExtra(XX,XX)方法,協助我們傳遞資料,但是我們看一下源碼會發現底層用的都是Bundle對象來實現的。
public Intent putExtra(String name, char[] value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putCharArray(name, value); return this;}
我們再看一下Bundle的建構函式,發現Bundle內部其實是個Map
public Bundle() { mMap = new HashMap<String, Object>(); mClassLoader = getClass().getClassLoader();}
-
接下來看看在
Intent中如何藉助
Bundle傳遞資料
-
在發送端
//給Intent設定資料intent.putExtra("name", "張三");//給你Intent設定字串類型的集合intent.putStringArrayListExtra("list", list);//聲明一個Bundle對象,bundle內部是封裝過的map集合Bundle bundle = new Bundle();//在Bundle對象中綁定資料bundle.putString("pwd", "123456");//給Intent設定Bundle對象intent.putExtras(bundle);//通過putExtras()傳遞bundle
-
接收端
Bundle extras = intent.getExtras();//通過getExtras擷取bundle//從Bundle中擷取可以為name的資料String name = (String) extras.get("name");//再通過get()擷取具體值System.out.println("name="+name);//從Bundle對象中擷取key為pwd的資料String pwd = (String) extras.get("pwd");System.out.println(pwd);//從Bundle中擷取ley為list的資料List<String> list = (List<String>) extras.get("list");
建立Activity擷取返回資料
-
操作步驟:
-
①使用
startActivityForResult(Intent intent, int requestCode) 方法開啟Activity
-
②重寫
onActivityResult(int requestCode, int resultCode, Intent data)方法
-
③在被開啟的Activity中調用
setResult(int resultCode, Intent data)設定返回資料之後,使用
finish()關閉Activity,第一個Activity就會調用
onActivityResult方法
-
requestCode,請求碼:用於區別是哪個操作啟動的意圖
-
resultCode,結果碼,用於區別是哪個Activity返回的資料
如何調用系統傳送簡訊的頁面
如何能夠把我們的資料傳遞給系統的簡訊頁面,例如下面這個樣子
代碼其實是很簡單的
Intent intent = new Intent();// 設定傳送簡訊的動作intent.setAction("android.intent.action.SEND");intent.addCategory("android.intent.category.DEFAULT");// 設定資料類型intent.setType("text/plain");// 使用Bundle傳遞資料intent.putExtra("sms_body", content);startActivity(intent);
但是裡面有些關鍵資訊(意圖過濾器,索引值),例如action、type、putExtra的key值怎麼找到?其實才是個痛點。
-
接下來就講一下如何找到這些關鍵資訊的思路。當前,前提是你要有Android的源碼。
-
①我們知道,Andriod有4層架構,最上層是應用程式層,在原生的系統中就帶有很多的應用,而短息也是應用之一。在我們的源碼中,可以知道
android4.4src/packages/apps就是我們系統內建的一些應用。
-
②既然知道了這些,那麼就找到我們的簡訊所在的目錄把
android4.4src/pagkages/apps/mms/
-
③ 我們知道,資訊清單檔中的activity下才是定義意圖過濾器的地方,所以我們看一下資訊清單檔,而且,既然是傳送簡訊,我們再搜尋一下SEND關鍵字,可以得到如下的結果:
<activity android:name=".ui.ComposeMessageActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:windowSoftInputMode="stateHidden|adjustResize" android:theme="@style/MmsHoloTheme" android:parentActivityName=".ui.ConversationList" android:launchMode="singleTop" > ... <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> ...</activity>
這樣,意圖過濾器的關鍵資訊就知道了;接下來就是要在Bundle中儲存資料了,那麼intent.putExtras(K,V)中的K值怎找到?
既然這個是系統的應用,那麼系統的代碼中就應該會有類似於intent.putExtras(K,V)這樣的代碼,而上面的<activity name=‘...‘>中的name屬性值為.ui.ComposeMessageActivity,我們又知道了具體的類是什麼,那麼我們搜尋一下就OK了。結果如下:
如何傳送簡訊
傳送簡訊的步驟相當簡單,請參看下面的代碼:
// 擷取簡訊管理器SmsManager smsManager = SmsManager.getDefault();// 防止簡訊內容過長,將其內容分割開ArrayList<String> messageList = smsManager.divideMessage(content);for (String sms : messageList) { // 目標人 String destinationAddress = contact; // 簡訊服務中心地址 String scAddress = null; // 簡訊內容 String text = sms; // 延期廣播一般為NULL PendingIntent sentIntent = null; PendingIntent deliveryIntent = null; // 使用簡訊管理器傳送簡訊 smsManager.sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);}
當然,這隻是很簡單的樣本,更為詳細的請參看Android API
Android基礎筆記(七)-頁面跳轉和資料傳遞