首页 > 酒水分类 > 红酒

京东手机app官网下载苹果,京东手机app官网下载

酒易淘 红酒 2022-09-09 14:10:09

品牌名称:酱香白酒加盟 所属行业:酒水 > 白酒

基本投资:10~50万元 投资热度:

加盟意向:1634 门店数量:534家

索要资料 查看详情

  

  随着鸿蒙系统2.0的发布,华为的部分手机用户迎来了繁荣时代。JD.COM作为华为鸿蒙系统OS的合作APP,第一时间投入了鸿蒙系统应用商业版的开发,在V10.0.2已经上架   

  

     

  

  鸿蒙 OS 特性   

  

  2021年6月2日,华为举行了鸿蒙系统OS 2.0发布会。鸿蒙系统操作系统带来了全新的桌面和用户体验。   

  

  比如桌面图标支持向上滑动调出快捷卡,原子化能力可以通过鸿蒙系统设备之间的循环,以及统一控制中心(手势:右上角向下滑动)和服务中心(手势:屏幕左下角或右下角侧向向上滑动)快速分享和展示。   

  

  Android 工程鸿蒙化   

  

  为了利用鸿蒙系统的功能,我们开发者需要尽快将应用鸿蒙系统化。   

  

  但是制作整个App鸿蒙系统的工作量极其巨大,那么有没有办法利用鸿蒙系统的特点,快速适配呢?   

  

  答案是肯定的,就是混合包开发模式。整个App基本上没有大的改动,只需要增加鸿蒙系统相关的模块,实现鸿蒙系统相关的功能。   

  

  JD。COM App-鸿蒙系统版能够快速适应上线,并且具有鸿蒙系统的特色,就是使用了这种开发模式。我们将以JD.COM App-鸿蒙系统版为例详细介绍相关流程。   

  

  Android 工程改造   

  

  需要依赖鸿蒙系统的兼容包(包文件可以通过联系我们获得),并从HarmonyApplication继承我们现有的应用程序。我们只需要编译依赖关系,不需要实际输入到App中。   

  

  compileOnlyfiles(' libs/ability shell _ ide _ Java . jar ')   

  

  在Android manifest . XML中,将添加到根节点。   

  

  uses-feature Android : name=' zidane . software . ability ' Android : required=' false '/   

  

  向应用程序节点添加一个子节点。   

  

  meta-data Android : name=' perm za ' Android : value=' true '/meta-data Android : name=' multi frame work bundle ' Android : value=' true '/   

  

  此后,鸿蒙系统需要的apk包已经搭建好了,你也可以通过配置和编译变体来搭建鸿蒙系统版本的apk包。   

  

  注意:鸿蒙系统包中混合的apk必须是64位。   

  

  配置鸿蒙工程   

  

  在项目入口模块的build.gradle中,增加了apk文件的配置。   

  

  legaapkoptions { legacyapkrootproproject . file(' Android _ entry . apk ')。absolute path//混合apk sign config { storefilerootproject . file(' XXX . keystore ')//混合apk中使用的签名文件的存储路径}}   

  

  总体配置如下:   

  

     

  

  签名转换,我们需要根据Android apk签名。   

做鸿蒙应用签名的申请,需要将 .keystore 或 .jks 格式的签名文件转换成 .p12 文件,签名秘钥和别名保持不变。具体转换步骤,大家可以自行搜索。

  


  

参考:在转换 .p12 文件时,我们遇到了问题,由于我们 Android 的签名格式是 .keystore,转出来的 .p12 文件有问题无法申请鸿蒙应用证书。

  


  

经过和华为方面沟通,我们将鸿蒙应用的签名秘钥和别名保持和Android的一致,解决了打包问题。

  


  

配置文件增加属性,在鸿蒙工程的每个 feature module 的 config.json app 节点下,增加 originalName,表示混入的 apk 包名,同时要将 bundleName 的值也改成一致。

  


  

在 entry 模块下,新建一个空的 Ability 类并配置在 config.json 里作为启动入口,如:

  

  "abilities": <{   "skills": <{     "entities": <"entity.system.home">,     "actions": <"action.system.home">   }>,   "orientation": "portrait",   "visible": true,   "name": "com.xxx.xxx.xx.EntryAbility",   "icon": "$media:icon",   "description": "$string:mainability_description",   "label": "$string:app_name",   "type": "page",   "launchType": "standard" }>,

  

自此已经可以构建出包含原有 Android 功能的鸿蒙包了。

  


  

Android-鸿蒙互调用

  


  

①从 Android 启动鸿蒙组件

  


  

我们需要集成鸿蒙的一个 jar 包(可以联系我们获得此文件),来实现从 Android 启动鸿蒙的组件。如:

  

Intent intent = new Intent();ComponentName componentName = new ComponentName("your harmony app's bundleName name","your ability's full name");intent.setComponent(componentName);intent.putExtras(bundle);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);AbilityUtils.startAbility(context, intent);

  

②鸿蒙模块调用 Android

  


  

鸿蒙启动 Android 组件:鸿蒙里本身是支持启动 Android 组件的,只需要在 Intent 里增加一个 flag。

  

Intent.FLAG_NOT_OHOS_COMPONENT

  

如:

  

  Intent intent = new Intent();        Operation operation = new Intent.OperationBuilder()                .withDeviceId("")                .withBundleName("your android app’s packagename")                .withAbilityName("your android app’s activity fullname")                .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)                .build();        intent.setOperation(operation);        startAbility(intent);

  

鸿蒙模块调用 Android 现有能力:在 Android 包里,已经有了很多现有功能,如埋点收集、用户登录态获取、定位、地址等等。

  


  

在鸿蒙模块里需要用到这些功能时,我们为了节省时间暂时没有再去开发一遍鸿蒙版,我们利用了 Java 的反射技术来搞定。

  


  

经过验证,在 Android 中反射鸿蒙以及鸿蒙中反射 Android 都是可以的。

  


  

③获取当前是否为鸿蒙系统

  


  

在有些场景下,我们需要知道当前系统的运行环境是不是鸿蒙系统,可以使用以下代码段来实现。

  

private static final String HARMONY_OS = "harmony";/*** check the system is harmony os** @return true if it is harmony os*/public static boolean isHarmonyOS() {    try {        Class clz = Class.forName("com.huawei.system.BuildEx");        Method method = clz.getMethod("getOsBrand");        return HARMONY_OS.equals(method.invoke(clz));    } catch (ClassNotFoundException e) {        Log.e(TAG, "occured ClassNotFoundException");    } catch (NoSuchMethodException e) {        Log.e(TAG, "occured NoSuchMethodException");    } catch (Exception e) {        Log.e(TAG, "occur other problem");    }    return false;}

  

鸿蒙 OS 特性+购物应用场景开发

  


  

鸿蒙 OS 打破了设备间的壁垒,对用户及应用开发者来说,形成了超级终端。超级终端包含手机、大屏、平板,未来或许会有更多的设备加入,设备间协同合作让购物体验变得优质。

  


  

每个设备不再是孤立的个体,而是基于鸿蒙操作系统的智慧终端,即便用户拿着不同的设备,也可以有很好的体验。

  


  

通过一键流转实现跨设备间的数据传输,从而实现无缝的购物体验。

  


  

流转:直播间 FA

  


  

介绍:流转泛指多设备间的分布式操作,打破设备界限,多设备联动,使用户应用程序可分可合、可流转。流转按照体验可分为跨端迁移和多端协同。流转支持免安装运行 FA。

  


  

京东 App-鸿蒙版本中的直播 FA 就利用了流转能力,将当前手机的直播流转至 TV 端,做到无缝衔接,并支持通过手机端控制 TV 端直播显示的功能。

  


  

效果如下:

  

  

开发:我们以京东 App-鸿蒙版中直播 FA 的流转开发经验进行介绍,如何具备流转能力。

  


  

权限要求:由于使用到了分布式能力,我们需要先把权限配置好,在对应的 module 的 config.json 下,增加以下权限:

  

ohos.permission.GET_DISTRIBUTED_DEVICE_INFOohos.permission.DISTRIBUTED_DATASYNCohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE

  

同时在 Ability 里,需要增加动态权限申请。

  

requestPermissionsFromUser(       new String<>{SystemPermission.DISTRIBUTED_DATASYNC},         Constants.PermissionCode.PERMISSION_DISTRIBUTED_DATASYNC);关键接口如下图:

  

  

功能实现如下:

  


  

a.通过流转服务注册管理器,将当前 FA 注册,注册时可以指定流转的过滤条件,如设备类型、目标设备等等:

  

  

b.当需要流转时,我们通过流转服务注册管理器获取当前满足条件的设备列表:

  

  

系统会自动查找设备,将满足条件的设备自动展示出来供用户选择,当用户点击某个设备后,就会回调 IContinuationDeviceCallback 的 onDeviceConnectDone 方法,获取到目标设备的 Id 后,就可以启动目标设备的 FA。

  


  

c.启动远程 FA。需要注意的是,在启动对端设备上 FA 时,我们要确保对端设备的分布式能力已经被初始化。

  

  

FA 近场分享:商详 FA

  


  

介绍:FA 近场分享能力依赖于华为分享服务,可以快速实现 FA 分享的功能。

  


  

较单纯的使用分布式 FA 流转功能,为开发者免除了设备发现功能,并且没有了同账号同网络等限制条件。

  


  

在京东 App-鸿蒙版中,商详 FA 就使用了此功能实现了 FA 的近场分享,并且能够做到免安装打开商详页面。

  


  

下图分别是 A 向 B 发送商详 FA 和 B 接收商详 FA。

  

  

开发:我们将以在京东 App-鸿蒙版中的相关开发经验介绍下如何进行 FA 近场分享的开发。

  


  

工作原理图示:

  

  

由于功能依赖华为分享服务,我们首先要引入 IDL 文件。

  


  

①导入 IDL 文件

  


  

在商详 FA module 中 java 同级目录,创建 idl 目录,并创建包名 com.huawei.hwshare.third,在此包名下创建 IHwShareCallback.idl 和 IHwShareService.idl 文件。

  


  

文件具体内容如下:

  

IHwShareCallback.idl:interface com.huawei.hwshare.third.IHwShareCallback {     void notifyState( int state);}IHwShareService.idl:sequenceable ohos.interwork.utils.PacMapEx;interface com.huawei.hwshare.third.IHwShareCallback;interface com.huawei.hwshare.third.IHwShareService {    int startAuth( String appId,  IHwShareCallback callback);     int shareFaInfo( PacMapEx pacMapEx);}

  

  

②对分享能力进行封装

  


  

以下是我们在商详 FA 中封装好的代码,大家可以直接使用:

  

package com.xxx.xxx.xxx;import com.huawei.hwshare.third.HwShareCallbackStub;import com.huawei.hwshare.third.HwShareServiceProxy;import ohos.aafwk.ability.IAbilityConnection;import ohos.aafwk.content.Intent;import ohos.app.Context;import ohos.bundle.ElementName;import ohos.eventhandler.EventHandler;import ohos.eventhandler.EventRunner;import ohos.interwork.utils.PacMapEx;import ohos.rpc.IRemoteObject;import ohos.rpc.RemoteException;import ohos.hiviewdfx.HiLog;import ohos.hiviewdfx.HiLogLabel;public class ShareFaManager {   private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, "ShareFa");     private static final String LOG_FORMAT = "%{public}s: %{public}s";    // FA的图标 byte<> len < 32768 非必须,不传默认取应用图标    public static final String HM_FA_ICON = "ohos_fa_icon";    // FA的名字 String len < 1024 非必须,不传默认取应用名    public static final String HM_FA_NAME = "ohos_fa_name";    // ability类名 String len < 1024 必须    public static final String HM_ABILITY_NAME = "ohos_ability_name";    // 包名 String len < 1024 必须    public static final String HM_BUNDLE_NAME = "ohos_bundle_name";    // FA类型 int 暂时只有0 非必须,默认为0    public static final String SHARING_FA_TYPE = "sharing_fa_type";    // FA卡片展示图 byte<> len < 153600 必须    public static final String SHARING_THUMB_DATA = "sharing_fa_thumb_data";    // FA卡片展示信息 String len < 1024 必须    public static final String SHARING_CONTENT_INFO = "sharing_fa_content_info";    // 携带的额外信息,可带到被拉起的FA String len < 10240 非必须    public static final String SHARING_EXTRA_INFO = "sharing_fa_extra_info";    private static final String TAG = "ShareHmFaManager";    private static final String SHARE_PKG_NAME = "com.huawei.android.instantshare";    private static final String SHARE_ACTION = "com.huawei.instantshare.action.THIRD_SHARE";    private static final long UNBIND_TIME = 20*1000L;    private Context mContext;    private String mAppId;    private PacMapEx mSharePacMap;    private static ShareFaManager sSingleInstance;    private HwShareServiceProxy mShareService;    private boolean mHasPermission = false;    private EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner());    //服务绑定回调    private final IAbilityConnection mConnection = new IAbilityConnection() {        @Override        public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {            HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "onAbilityConnectDone success.");            mHandler.postTask(()->{                mShareService = new HwShareServiceProxy(iRemoteObject);                try {                    //华为分享认证授权                    mShareService.startAuth(mAppId, mFaCallback);                } catch (RemoteException e) {                    HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "startAuth error.");                }            });        }        @Override       public void onAbilityDisconnectDone(ElementName elementName, int i) {           HiLog.info(LABEL_LOG, LOG_FORMAT, TAG, "onAbilityDisconnectDone.");           mHandler.postTask(()->{               mShareService = null;               mHasPermission = false;            });        }    };    private Runnable mTask = () -> {        if (mContext != null && mShareService != null) {            mContext.disconnectAbility(mConnection);            mHasPermission = false;            mShareService = null;        }    };    //华为分享认证授权回调    private final HwShareCallbackStub mFaCallback = new HwShareCallbackStub("HwShareCallbackStub") {        @Override        public void notifyState(int state) throws RemoteException {            mHandler.postTask(()->{                HiLog.info(LABEL_LOG, LOG_FORMAT, TAG, "notifyState: " + state);                if (state == 0) {                    mHasPermission = true;                    if (mSharePacMap != null) {                       shareFaInfo();                    }                }            });        }    };    /**     \* 单例模式获取ShareFaManager的实例对象     *     \* @param context 程序Context     \* @return ShareFaManager实例对象     */    public static synchronized ShareFaManager getInstance(Context context) {        if (sSingleInstance == null && context != null) {            sSingleInstance = new ShareFaManager(context.getApplicationContext());        }        return sSingleInstance;    }    private ShareFaManager(Context context) {        mContext = context;    }    private void shareFaInfo() {        if (mShareService == null) {            return;        }        if (mHasPermission) {            HiLog.info(LABEL_LOG, LOG_FORMAT, TAG, "start shareFaInfo.");            try {                mShareService.shareFaInfo(mSharePacMap);                mSharePacMap = null;            } catch (RemoteException e) {                HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "shareFaInfo error.");            }        }        // 不使用时断开        mHandler.postTask(mTask, UNBIND_TIME);    }    /**     \* 开始分享     *     \* @param appId 开发者联盟网站创建鸿蒙服务/鸿蒙应用时生成的appid     \* @param pacMap 服务信息载体     */    public void shareFaInfo(String appId, PacMapEx pacMap) {        if (mContext == null) {            return;        }        mAppId = appId;        mSharePacMap = pacMap;        mHandler.removeTask(mTask);        shareFaInfo();        bindShareService();    }    /**     \* 绑定华为分享服务     */    private void bindShareService() {            if (mShareService != null) {            return;        }        HiLog.error(LABEL_LOG, LOG_FORMAT, TAG, "start bindShareService.");        Intent intent = new Intent();        intent.setBundle(SHARE_PKG_NAME);        intent.setAction(SHARE_ACTION);        intent.setFlags(Intent.FLAG_NOT_OHOS_COMPONENT);        mContext.connectAbility(intent, mConnection);    }    }

  

③开始分享

  


  

我们将参数进行组装,调用 ShareFaManager 的 shareFaInfo 方法即可自动的完成 FA 分享功能。

  


  

如我们将商详 FA 进行分享:

  

  

注意:

  

使用时要主要传递的数据不要超过限定的大小,否则会分享失败并导致程序崩溃。在对端接收到分享后,我们需要将自定义的参数取出来,从 Intent 中取 sharing_fa_extra_info 即可。

  

Ps:针对远距离的场景,华为也给出了解决方案,通过畅连即可分享购物链接。值得注意的是,此时好友还可以通过屏幕共享在商品页面进行涂鸦互动。

  


  

服务卡片:搜索卡片

  


  

用户上滑 App 图标即可生成万能卡片 ,在桌面呈现更丰富的信息,卡片信息支持实时更新,减少了 App 加载的时间,如目前京东 app,用户上滑 App 图标可打开快捷搜索入口。

  


  

介绍:FA 卡片是 FeatureAbility 的 Page 模板的一种界面展示形式。FA 卡片常用于嵌入到其他应用中作为其界面的一部分显示,并支持基础的交互功能。

  


  

卡片使用方作为卡片展示的宿主负责显示卡片,卡片使用方的典型应用就是桌面应用。卡片使用方仅限系统应用。

  


  

当 FA 规格小于 10M 时,可以支持免安装运行。系统最大支持 500 个卡片,相同名称的卡片实例最大是 32 个。

  


  

通过服务卡片的一些特点,如定时更新、免安装运行等,可以很好的进行快捷入口的引导。

  


  

如我们可以在卡片上展示活动商品,并定期更新,用户可以免安装的打开活动详情,当用户产生进一步购买欲望时,用户可下载整个 App 进行下单。

  

  

开发:卡片的开发支持 JS 和 Java 两种方式。在京东 App-鸿蒙版中的搜索 FA 里,我们加入了 FA 卡片,可以直达搜索。下面我们将以此为例进行开发步骤的讲解。

  


  

①卡片配置

  


  

首先要在搜索 FA 的 config.json 中配置 forms 节点,比如:

  

  

我们给 SearchAbility 节点下添加 forms 节点,就表示这个卡片的创建及管理由 SearchAbility 来负责。

  


  

注意:必须要设置 label 属性,必须是资源形式的且不能是包名。

  


  

属性解释:

  

  

②实现卡片相关回调

  


  

在 SearchAbility 中,复写以下几个方法:

  

  

创建:在创建卡片时,我们可以从 Intent 中获取当前要创建卡片的 Id,如:

  

  

这是一个很简单的卡片,我们没有对卡片中的视图设置任何数据和事件,那么点击卡片后,打开的就是负责管理卡片的 Ability。

  


  

如果需要设置数据和事件,可以使用以下方式:

  

创建 ComponentProvider。通过 ComponentProvider 设置对应 View 的数据,以及点击事件,目前能够支持的事件有 START_ABILITY 和 START_SERVICE 两类。将 ComponentProvider 对象合并入 ProviderFormInfo 中。

  

更新:当触发了更新卡片方法时,我们可以进行数据更新,并将最新的数据更新到卡片 View 上。

  

  

删除:当卡片使用方将卡片删除,我们可能需要将对应卡片在 App 内的相关持久化数据进行删除。

  

  

③配置 EntryCard 目录

  


  

配置 EntryCard 目录,以便让系统能够识别出服务卡片,并展示在服务中心的推荐里。

  


  

新建应用时可以勾选自动生成,如果是之前 IDE 创建的工程,则需要手动补充上:

  

在工程根目录下创建 EntryCard 目录。EntryCard 目录下,创建一个文件夹,取名为拥有卡片的 FA 工程名,如我们的搜索 FA 拥有服务卡片,搜索 FA 的工程名叫 searchfeature,那我们就创建一个文件夹,名字就叫做 searchfeature。在 searchfeature 目录下创建 base/snapshot 两级目录,在其中放置我们的卡片图片,其命名方式为 formname-dimensions。如搜索卡片的卡片名称配置的是 search_card,尺寸是 2*2 的,那么这个图片就命名为 search_card-2x2.png。

  

鸿蒙 App 打包及上架

  


  

打包构建

  


  

通过以上配置,我们已经可以进行鸿蒙 App 的构建了。

  


  

目前鸿蒙 App 分为两种构建形式,debug 和 release,可以通过 DevEco 工具自带的编译任务或者使用 gradle 的 assembleDebug signReleaseApp 任务进行构建。

  

  

其中 debug 模式构建方式出来的产物是多个目标设备的多个 .hap 文件,每个 FA 都会构建出各自的 .hap 文件;release 会构建出一个 .app 文件,我们需要将此文件进行上架发布。

  

  

安装及运行:

  


  

开发者无法安装 .app 安装包,此文件只能用于上架应用市场。

  


  

通过 adb shell bm get -udid 获取设备 UDID 后,录入到开发者中心,并生成证书文件,我们就可以安装 .hap 包。

  


  

安装时可以将文件 push 到手机某个目录下(如 sdcard/hmphone),然后使用 adb shell bm install -p /sdcard/hmphone/ 进行安装,每次安装可以先删除之前文件。

  


  

注意:由于我们无法安装验证 .app 包,我们要保证在 debug 和 release 两种构建模式下,我们的代码不会发生改变。

  


  

应用上架及发布

  


  

如果还没有在开发者中心创建鸿蒙应用的话,需要先新增一个鸿蒙应用,包名和之前 Android 的包名保持一致,并关联到同一个项目中。

  

  

选择我们创建的鸿蒙应用,在【应用信息】页面中,将应用安装与升级修改为如下图所示。

  

  

在【版本信息】页面中,点击【版本/升级】创建新版本,在新版本页面中的【软件版本】模块下,上传我们构建的 .app 软件包后并勾选,在当前页面填入相关信息后即可提交审核,待审核通过后,在应用市场上就会出现了。

  

  

后续规划

  


  

鸿蒙 OS 为消费者建立便捷的购物超级终端模式提供了可能,随着鸿蒙生态的丰富,人们的购物形式也会随之出现新的改变。

  


  

京东将从用户角度出发,结合鸿蒙 OS,让更多的用户在更多的设备和场景享受京东的优质服务,敬请期待……

  


  

来源:京东零售技术(ID:jd-sys)

  



免费咨询
免费获取加盟资料