Intent 与 Intent Filters 实现外部调用

Intent 与 Intent Filters

如需了解更多官方文档: 《App Components》

您还可以参考这些优秀博文:

  • Android Intent最全面的解析
  • 史上最全的隐式Intent解析
  • Android deep links技术实现

Intent 应用

  • deep links
  • LAPP (Light App) 即轻应用
  • APP 之间跳转等等

下面是一个小米轻应用示例

我们知道轻应用无非就是每个Activity 暴露接口给其它APP调用,若刚好你的APP Activity 很多,那就必须在Activity节点下增加

  <intent-filter>...intent-filter>

还有要在Activity 解析Intent ,还破坏了原有代码结构。仔细思考了一番,既然 节点下可以添加多个action、category、data.那可以新建一个代理Activity来控制跳转的逻辑等业务。


<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xiaomi.relax">

    <application android:label="@string/app_name" android:largeHeap="true"
        android:screenOrientation="landscape"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
        <activity android:name=".activity.SplashActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:label="@string/app_name" android:screenOrientation="landscape"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.APPSTORE_LAUNCHER" />
            intent-filter>
        activity>
        <activity android:name=".activity.RelaxProxyActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/splash"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/home"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/album"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/theme"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/radio"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/song"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/vip"
                    android:scheme="hifi" />
                <data android:host="com.hifimusic.xiaomi.qing" android:path="/goods"
                    android:scheme="hifi" />
                <data android:host="com.hifimusic.xiaomi.qing" android:path="/url"
                    android:scheme="hifi" />

                <data android:host="com.hifimusic.xiaomi.qing" android:path="/meal"
                    android:scheme="hifi" />

            intent-filter>
        activity>
    application>

manifest>

RelaxProxyActivity

public class RelaxProxyActivity extends Activity {
    private static final String TAG = "RelaxProxyActivity";
    UriParse uriParse = null;
    final String splashPath = "/splash";
    final String homePath = "/home";
    final String ablumPath = "/album";
    final String themePath = "/theme";
    final String userPath = "/vip";
    final String radioPath = "/radio";
    final String playingPath = "/song";
    final String goodsPath = "/goods";
    final String urlPath = "/url";
    final String mealPath = "/meal";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        uriParse = new UriParse(this);
        //
        String path = uriParse.getPath();
        Log.i(TAG, "path: " + path);
        Intent intent = new Intent();
        //检查是否激活
        int activate = Integer.parseInt(DataManager.getInstance().getString("activate", "0"));
        if (activate == 0) {
            intent.setClass(this, SplashActivity.class);
            intent.setData(getIntent().getData());
            startActivity(intent);
        } else {
            switch (path) {
                case splashPath:
                    intent.setClass(this, SplashActivity.class);
                    startActivity(intent);
                    break;
                case homePath:
                    int pos = 0;
                    try {
                        Integer id = Integer.valueOf(uriParse.getQueryParameter("id"));
                        pos = id > 0 ? id : 0;
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    intent.setClass(this, HomeActivity.class);
                    intent.putExtra("pos", pos);
                    startActivity(intent);
                    break;
                case ablumPath:
                    try {
                        long albumid = Long.valueOf(uriParse.getQueryParameter("id"));
                        intent.setClass(this, AlbumDetailActivity.class);
                        intent.putExtra("id", albumid);
                        startActivity(intent);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                case themePath:
                    try {
                        long albumid = Long.valueOf(uriParse.getQueryParameter("id"));
                        intent.setClass(this, ThemeDetailActivity.class);
                        intent.putExtra("id", albumid);
                        startActivity(intent);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                case userPath:
                    intent.setClass(this, UserInfoActivity.class);
                    startActivity(intent);
                    break;
                case radioPath:
                    try {
                        long radioId = Long.valueOf(uriParse.getQueryParameter("id"));
                        intent.setClass(this, PlayingActivity.class);
                        intent.putExtra("contentId", radioId);
                        intent.putExtra(PlayingActivity.Extra_RadioAction, true);
                        startActivity(intent);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                case playingPath:
                    intent.setClass(this, PlayingActivity.class);
                    startActivity(intent);
                    break;
                case goodsPath:
                    try {
                        long goodsId = Long.valueOf(uriParse.getQueryParameter("id"));
                        intent.setClass(this, CommodityActivity.class);
                        startActivity(intent);
                        EventBus.getDefault().postSticky(goodsId);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                case urlPath:
                    try {
                        String url = uriParse.getQueryParameter("url");
                        intent.setClass(this, CordovaActivity.class);
                        intent.putExtra("url", url);
                        startActivity(intent);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                case mealPath:
                    try {
                        String type = uriParse.getQueryParameter("type");
                        if ("0".equals(type)) {
                            UIHelper.startVipWebActivity(getActivity());
                        } else if ("1".equals(type)) {
                            UIHelper.startDownloadWebActivity(getActivity());
                        }
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    Log.e(TAG, "can't find path" + path);
                    break;
            }
        }
        finish();
    }

    public class UriParse implements IUriParse {
        Activity activity;

        public UriParse(Activity activity) {
            this.activity = activity;
        }

        @Override
        public Uri parseUri() {
            return activity.getIntent().getData();
        }

        @Override
        public Uri parseUri(Intent p1) {
            return p1.getData();
        }

        @Override
        public String getPath() {
            return activity.getIntent().getData().getPath();
        }

        @Override
        public String getQueryParameter(Uri uri, String key) {
            return uri.getQueryParameter(key);
        }

        @Override
        public String getPath(Activity activity) {
            return activity.getIntent().getData().getPath();
        }

        @Override
        public String getQueryParameter(String key) {
            return activity.getIntent().getData().getQueryParameter(key);
        }


        @Override
        public String getQueryParameter(Activity activity, String key) {
            return getQueryParameter(parseUri(activity.getIntent()), key);
        }
    }

    public Activity getActivity() {
        return this;
    }
}

对于熟悉隐式Intent的部分,这部分代码应该不难理解。增加了一个Activity 保持原有代码不变是一个很好的做法。

Uri 实现外部调用

Uri是什么?

通用资源标志符(Universal Resource Identifier, 简称”URI”)。
Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。

final String hostUrl = "hifi://com.hifimusic.xiaomi.qing/";
@Override
public void onClick(View v) {
    Uri uri;
    try {
        Intent intent = new Intent();
        switch (v.getId()) {
            case R.id.startBtn:
                uri = Uri.parse(hostUrl + "splash");//启动APP
                intent.setData(uri);
                startActivity(intent);
                break;
            case R.id.indexBtn:
                    uri = Uri.parse(hostUrl + "home?id=1");
                    intent.setData(uri);
                    startActivity(intent);
                    break;

浏览器如何调用?

<a href="hifi://com.hifimusic.xiaomi.qing/album?id=1372004452289">打开专辑a>

Intent 与 Intent Filters 实现外部调用_第1张图片

Demo 代码
关于Intent 与 Intent Filters 的使用还是很简单的

你可能感兴趣的:(Android)