HarmonyOS Sample 之 Intent 信息传递 原创 精华

Buty9147
发布于 2021-7-28 20:52
浏览
2收藏

@toc

Intent 信息传递

介绍

Intent 是对象之间传递信息的载体。例如,当一个 Ability 需要启动另一个 Ability 时,或者一个 AbilitySlice 需要导航到另一个 AbilitySlice 时,可以通过 Intent 指定启动的目标同时携带相关数据。
启动应用有两种方式:根据 Ability 的全称启动应用,根据 Operation 的其他属性启动应用。
本示例结合第三方登录的场景演示了如何根据Ability的全称启动应用和根据Operation的其他属性启动应用。
模拟的第三方登录的场景只是为了实践Intent 信息传递的功能,真实原理不一定是这样。

搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

项目结构

该实例一共有3个应用,intent、secondapp、thirdapp
演示的效果是模拟第三方授权登录场景,使用Action和Ability的全称两种不同方式启动应用,实现不同应用之间的数据传递。
HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区

实现步骤

1.编写界面

intent的main_ability_slice.xml界面
HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区
secondapp的main_ability_slice.xml界面
HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区
thirdapp的main_ability_slice.xml界面
HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区

2.编写启动应用代码

intent应用的MainAbility.java

public class MainAbility extends Ability {

    private static final HiLogLabel LABEL= new HiLogLabel(HiLog.LOG_APP,0x0001,"=>"+MainAbilitySlice.class.getName());

    //商定的参数名称
    private static final String ACCOUNT_KEY = "ohos.samples.intent.LIVE_ACCOUNT";
    private static final String PASSWORD_KEY = "ohos.samples.intent.LIVE_PASSWORD";

    private static final int REQ_CODE_START = 0;

    private String ACTION_WECHAT = "action.custom.wechat";
    private String ACTION_WEIBO = "action.custom.weibo";

    private TextField accountTextField;
    private TextField  passwordTextField;
    private Button loginButton;
    private Text closeText;
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(MainAbilitySlice.class.getName());
        //使用页面组件,必须设置
        super.setUIContent(ResourceTable.Layout_main_ability_slice);

        initComponents();
    }

    private void initComponents() {
        //account
        accountTextField = (TextField) findComponentById(ResourceTable.Id_text_account);
        //password
        passwordTextField = (TextField) findComponentById(ResourceTable.Id_text_password);
        //
        loginButton= (Button) findComponentById(ResourceTable.Id_btn_login);

        //wechat
        Component component1 = findComponentById(ResourceTable.Id_start_by_wechat);
        component1.setClickedListener(component -> applyWeChat());

        //qq
        Component component2 = findComponentById(ResourceTable.Id_start_by_qq);
        component2.setClickedListener(component -> startByName());

        //weibo
        Component component3 = findComponentById(ResourceTable.Id_start_by_weibo);
        component3.setClickedListener(component -> applyWeiBo());


        //关闭
        closeText = (Text) findComponentById(ResourceTable.Id_close_text);
        closeText.setClickedListener(component -> terminateAbility());
    }

    /**
     * 通过AbilityName启动应用
     * startAbility 不返回数据
     */
    private void startByName() {
        Intent intent = new Intent();
        //传递参数:申请授权方
        intent.setParam("applyParty","LiveApp");

        //方式一,AbilityName+bundleName
        Operation operation = new Intent.OperationBuilder().withDeviceId("")
                .withBundleName("ohos.samples.secondapp")
                .withAbilityName("ohos.samples.secondapp.MainAbility")
                .build();
        intent.setOperation(operation);
        //不返回参数
        //startAbility(intent);
        //返回参数,和 onAbilityResult是配套使用的
        startAbilityForResult(intent, REQ_CODE_START);
    }

    /**
     * 通过ACTION启动应用
     * startAbilityForResult 支持返回数据
     */
    private void applyWeChat() {
        Intent intent = new Intent();

        //传递参数:申请授权方
        intent.setParam("applyParty","LiveApp");


        //方式一,AbilityName+bundleName
       /* Operation operation = new Intent.OperationBuilder().withDeviceId("")
                .withBundleName("ohos.samples.secondapp")
                .withAbilityName("ohos.samples.secondapp.MainAbility")
                .build();*/

        //方式二,Action,不用加bundleName
        Operation operation = new Intent.OperationBuilder().withDeviceId("")
                .withAction(ACTION_WECHAT)
                .build();

        intent.setOperation(operation);
        //和 onAbilityResult是配套使用的
        startAbilityForResult(intent, REQ_CODE_START);
    }

    /**
     * 通过ACTION启动应用
     * startAbilityForResult 支持返回数据
     */
    private void applyWeiBo() {

        Intent intent = new Intent();
        //传递参数:申请授权方
        intent.setParam("applyParty","LiveApp");

        //方式一,AbilityName+bundleName
        /*Operation operation = new Intent.OperationBuilder().withDeviceId("")
                .withBundleName("ohos.samples.thirdapp")
                .withAbilityName("ohos.samples.thirdapp.ThirdApplyAbility")
                .build();*/

        //方式二,Action,不用加bundleName
        Operation operation = new Intent.OperationBuilder().withDeviceId("")
                .withAction(ACTION_WEIBO)
                .build();

        intent.setOperation(operation);
        //和onAbilityResult是配套使用的
        startAbilityForResult(intent, REQ_CODE_START);
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        super.onAbilityResult(requestCode, resultCode, resultData);
        HiLog.debug(LABEL,"onResult...requestCode:"+requestCode+",resultData:"+resultData);
        //获取返回的数据
        if (requestCode == REQ_CODE_START && resultData != null) {
            accountTextField.setText(resultData.getStringParam(ACCOUNT_KEY));
            passwordTextField.setText(resultData.getStringParam(PASSWORD_KEY));
        }

        //设置登录按钮可用
        Element element= ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_button_background_actived);
        loginButton.setBackground(element);
    }
}

secondapp应用的MainAbility.java

public class MainAbility extends Ability {

private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0xD0001, "=>" + MainAbility.class.getName());

//商定的参数名称
private static final String ACCOUNT_KEY = "ohos.samples.intent.LIVE_ACCOUNT";
private static final String PASSWORD_KEY = "ohos.samples.intent.LIVE_PASSWORD";

private Button applyButton;
private Button rejectButton;
private Text applyParty;
private Text cancel;

private String ACTION_START = "action.custom.wechat";

@Override
public void onStart(Intent intent) {

    HiLog.debug(LABEL,"ability onStart...");

    super.onStart(intent);
    super.setMainRoute(MainAbilitySlice.class.getName());
    //使用页面组件,必须设置
    super.setUIContent(ResourceTable.Layout_main_ability_slice);

    //如果是Ability的默认slice,可以不设置
    //addActionRoute(ACTION_START, MainAbilitySlice.class.getName());

    //接受授权
    applyButton = (Button) findComponentById(ResourceTable.Id_btn_apply);
    applyButton.setClickedListener(component -> apply());

    //取消授权
    rejectButton = (Button) findComponentById(ResourceTable.Id_btn_reject);
    rejectButton.setClickedListener(component -> terminateAbility());

    //取消授权
    cancel = (Text) findComponentById(ResourceTable.Id_close_text);
    cancel.setClickedListener(component -> terminateAbility());

    //申请授权方
    applyParty = (Text) findComponentById(ResourceTable.Id_apply_party);
    String applyPartyParam = intent.getStringParam("applyParty");
    if (intent.hasParameter("applyParty")) {
        applyParty.setText(applyPartyParam + " 申请使用");
    }
}

/**
 * 接受授权
 */
private void apply() {
    Intent resultIntent = new Intent();
    //设置返回的参数
    resultIntent.setParam(ACCOUNT_KEY, "Zhangsaner");
    resultIntent.setParam(PASSWORD_KEY, "zhangsaner@123");
    setResult(0, resultIntent);
    //关闭当前应用
    terminateAbility();
}

}

secondapp应用的config.json,声明"action.custom.wechat" Action

"abilities": [
      {
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home",
              "action.custom.wechat"
            ]
          }
        ],

thirdapp应用的ThirdApplyAbility.java

public class ThirdApplyAbility extends Ability {

private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0xD0011, "=>" + ThirdApplyAbility.class.getName());

//商定的参数名称
private static final String ACCOUNT_KEY = "ohos.samples.intent.LIVE_ACCOUNT";
private static final String PASSWORD_KEY = "ohos.samples.intent.LIVE_PASSWORD";

private Button applyButton;
private Text cancel;

private String ACTION_START = "action.custom.weibo";
@Override
public void onStart(Intent intent) {
    HiLog.debug(LABEL, "ability onStart...");
    super.onStart(intent);
    super.setMainRoute(ThirdApplyAbilitySlice.class.getName());

    //如果是Ability的默认slice,可以不设置
    //addActionRoute(ACTION_START, ThirdApplyAbilitySlice.class.getName());

    //使用页面组件,必须设置
    super.setUIContent(ResourceTable.Layout_ability_third_apply);

    //接受授权
    applyButton = (Button) findComponentById(ResourceTable.Id_btn_apply);
    applyButton.setClickedListener(component -> apply());

    //取消授权
    cancel = (Text) findComponentById(ResourceTable.Id_close_text);
    //关闭slice
    cancel.setClickedListener(component -> terminateAbility());
}

/**
 * 接受授权
 */
private void apply() {
    Intent resultIntent = new Intent();
    //设置返回的参数
    resultIntent.setParam(ACCOUNT_KEY, "xiaowei");
    resultIntent.setParam(PASSWORD_KEY, "xiaowei@123");
    setResult(0, resultIntent);
    //关闭当前Ability
    terminateAbility();
}
}

thirdapp应用的config.json,在ThirdApplyAbility的skills中声明"action.custom.weibo" Action

{
        "orientation": "unspecified",
        "visible": true,
        "name": "ohos.samples.thirdapp.ThirdApplyAbility",
        "icon": "$media:icon",
        "description": "$string:thirdapplyability_description",
        "label": "$string:thirdapp_ThirdApplyAbility",
        "type": "page",
        "launchType": "standard",
        "metaData": {
          "customizeData": [
            {
              "name": "hwc-theme",
              "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar"
            }
          ]
        },
        "skills": [
          {
            "actions": [
              "action.custom.weibo"
            ]
          }
        ]
      }

问题总结

1.如果在Ability中要使用Slice的组件,需要设置UIContent,否则会找不到组件

@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setMainRoute(MainAbilitySlice.class.getName());
    
    //如果在Ability中使用页面组件,需要设置UIContent
    super.setUIContent(ResourceTable.Layout_main_ability_slice);
    initComponents();
}

2.使用Actin方式,需要在config.json 对应的Ability中声明路由
HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区
是否需要在对应Ability的onStart方法中addActionRoute添加设置,要看路由指向的是不是Ability默认的Slice
HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区

3.使用Action方式,需要在Operation中指定Action,使用Ability的全称方式需要在Operation中指定AbilityName+bundleName

//方式一,AbilityName+bundleName
/*Operation operation = new Intent.OperationBuilder().withDeviceId("")
        //必须设置
        .withBundleName("ohos.samples.thirdapp")
         //可以带bundleName,也可以不带
        .withAbilityName("ThirdApplyAbility")
        .build();*/

//方式二,Action,不用加bundleName
Operation operation = new Intent.OperationBuilder().withDeviceId("")
        .withAction(ACTION_WEIBO)
        .build();

效果展示

HarmonyOS Sample 之 Intent 信息传递-鸿蒙开发者社区

完整代码

附件直接下载

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
Intent.zip 1.93M 41次下载
已于2021-7-29 11:40:39修改
2
收藏 2
回复
举报
回复
    相关推荐