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);
			} 

 

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