Android intent URI跳轉以及參數拼接

Android啓動一個界面,可以通過顯示和隱式兩種方式。

(一)activity的跳轉方式小結

地址:https://github.com/buder-cp/base_component_learn/tree/master/URIJump

方式一:顯示啓動,通過類名

一般應用內部跳轉會經常使用該方法。

/**
 * 方式一:類名跳轉
 */
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
startActivity(intent);

方式二:通過ComponentName跳轉

通過組件名稱跳轉需要知道包名和Activity名稱,該方法一般用於外部應用跳轉。

 Intent it = new Intent();
 ComponentName componentName = new ComponentName("com.test.helleworld", "com.test.helloworld.ActivityA");
 it.setComponent(componentName);
 startActivity(it);

方式三:通過包名、類名跳轉

與上述方法類似,都需要知道包名和Activit名稱,其實setClassNmae裏面也是通過設置ComponentName的,該方法一般用於外部應用跳轉。

Intent it = new Intent();
it.setClassName("com.test.helleworld", "com.test.helloworld.ActivityA");
startActivity(it);

方式四:根據包名跳轉

根據應用包名跳轉,這裏打開的是跳轉應用的默認啓動Activity。

PackageManager pm = getPackageManager();
 Intent it = pm.getLaunchIntentForPackage("com.test.helloworld");
 //it.setAction("android.intent.action.MAIN");
 startActivity(it);

方式五:隱式啓動利用action,通過在AndroidManifest中定義intentfilter進行action的匹配

不需要指定跳轉的Activity名字,只需雙方協定好指定的action即可,該方法一般常用於外部應用跳轉。

  • 步驟一:在啓動界面new Intent中定義好我們要跳轉到界面的action,這個action名字可以隨意起,例如這裏是self_define_action
/**
 * 方式二:action跳轉
 */

Intent intent1 = new Intent("self_define_action");
startActivity(intent1);
  • 步驟二:在被啓動界面的manifest文件中定義好和上面對應的action
        <activity android:name=".Main2Activity" android:exported="true">
            <intent-filter>
                <!--配置action路徑-->
                <action android:name="self_define_action" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

        </activity>

方式三:隱式啓動,利用URI,和上面的action類似,只是這裏由action轉成了uri 

  • 步驟一:首先需要定義符合URI通信的協議,這裏很簡單:hello://test.uri.activity?action=123&secret=buder

(1)scheme協議:hello

(2)host路由地址:test.uri.activity

(3)?query參數:query參數可以有多個,是鍵值對的表示方式,鍵值對之間用&連接。本例中key=action,value=123

  •  步驟二:協議定義好後,需要在intent中添加上action字段,這裏我們還是自定義self_define_uri作爲action字段
/**
 * 方式三:URI跳轉
 */
String uriString = "hello://test.uri.activity?action=123&secret=buder";
Uri uri = Uri.parse(uriString);
Intent intent = new Intent("self_define_uri");
//Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
  • 步驟三:在被跳轉的activity的manifest文件中聲明好和上面兩步對應的協議字段

本例中,action爲self_define_uri;scheme爲hello;host爲test.uri.activity

        <activity android:name=".Main2Activity" android:exported="true">
            <intent-filter>
<!--                <action android:name="android.intent.action.VIEW" />-->
                <action android:name="self_define_uri" />
                <category android:name="android.intent.category.DEFAULT" />
                <data
                    android:scheme="hello"
                    android:host="test.uri.activity" />
            </intent-filter>

        </activity>
  • 步驟四:當我們業務中需要傳過來的參數時,在接收方這麼獲取穿過來的參數:
        Intent intent = getIntent();
        if (null != intent) {
            Uri uri = intent.getData();
            if (uri == null) {
                return;
            }
            String actionData = uri.getQueryParameter("action");
            String secretData = uri.getQueryParameter("secret");

            TextView tv = findViewById(R.id.txt);
            tv.append("\n傳過來的action值爲:" + actionData);
            tv.append("\n傳過來的secret值爲:" + secretData);
        }

(二)activity傳參小結

intent傳遞參數的方式有兩種,一種是大家熟悉的extra,鍵值對的形式,直接傳遞參數;另一種就是uri的方式。

方式一:intent傳參,將參數放到bundle中

如下例子中,有一個playInfo的key裏面有一個JSONObject的字符串:

Intent intent = new Intent(ACTION_DETAIL);
        Bundle bundle = new Bundle();

        JSONObject playInfoJsonObject = new JSONObject();
        try {
            playInfoJsonObject.put("playType", "");
            playInfoJsonObject.put("videoId", content.related_aids);
            playInfoJsonObject.put("episodeId", content.related_vids);
            playInfoJsonObject.put("history", "-1");
            playInfoJsonObject.put("chnId", "");
            playInfoJsonObject.put("customer", PACKAGE_NAME);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String playInfo = playInfoJsonObject.toString();

        bundle.putString("playInfo", playInfo);
        intent.putExtras(bundle);

        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            context.startActivity(intent);
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        }

方式二:使用URI,需要先拼接URI地址

先來認識下URI,如下這個字符串就是一個URI地址例子:

String str = "content://com.android.test?username=merlin&password=123456";

它的文件結構如下:

[scheme:][//authority][path][?query][#fragment] 

其中有下面幾個規則:

  • path可以有多個,每個用/連接,比如

scheme://authority/path1/path2/path3?query#fragment

  • query參數可以帶有對應的值,也可以不帶,如果帶對應的值用=表示,如:

scheme://authority/path1/path2/path3?id = 1#fragment,這裏有一個參數id,它的值是1

  • query參數可以有多個,每個用&連接

scheme://authority/path1/path2/path3?id = 1&name = mingming&old#fragment

這裏有三個參數:

參數1:id,其值是:1

參數2:name,其值是:mingming

參數3:old,沒有對它賦值,所以它的值是null

  • 在android中,除了scheme、authority是必須要有的,其它的幾個path、query、fragment,它們每一個可以選擇性的要或不要,但順序不能變,比如:

其中"path"可不要:scheme://authority?query#fragment
其中"path"和"query"可都不要:scheme://authority#fragment
其中"query"和"fragment"可都不要:scheme://authority/path
"path","query","fragment"都不要:scheme://authority
等等……

對於URI,我們平時的用法如下:

Uri uri = Uri.parse("qijian://test.uri.activity?action=1");  
Intent intent = new Intent("android.qijian.schemeurl.activity");  
intent.setData(uri);  
startActivity(intent);  

有時候需要我們去拼裝這些URI,常用代碼如下:

public static Uri getRouteUri(Action action){
        try {
            Uri.Builder builder=new Uri.Builder();
            builder.scheme(action.scheme);
            builder.authority(action.host);
            builder.path(action.path);
            Map<String, String> query=action.query;
            if(query!=null&&!query.isEmpty()){
                for (Map.Entry<String, String> entry:query.entrySet()){
                    builder.appendQueryParameter(entry.getKey(), entry.getValue());
                }
            }
            return builder.build();
        } catch (Exception e) {
            Log.e(TAG, "getRouteUri: build route uri error, action="+action, e);
            return null;
        }
    }

(三)啓動三方APP的方式小結

兩種啓動三方APP包的方式:

if (!TextUtils.isEmpty(packageName)) {
				Intent intent;
				if (!TextUtils.isEmpty(className)) {
					ComponentName componentName = new ComponentName(packageName, className);
					intent = new Intent();
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
					intent.setComponent(componentName);
					intent.setAction(Intent.ACTION_VIEW);
					intent.putExtra(CUSTOM_PARAMS, params);
				} else {
					intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
					intent.putExtra(CUSTOM_PARAMS, params);
				}
				context.startActivity(intent);
			} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章