赞
踩
【关键字】
HarmonyOS、H5页面、拨打电话、获取系统定位、跳转高德地图导航
【1、写在前面】
上一篇中我们带领大家实现了一个在低码项目中跳转加载H5页面的功能,有兴趣的可以参考以下文章:
华为开发者论坛:【HarmonyOS】一文教你如何在低代码项目中跳转H5页面
今天我们继续在上一篇的基础上继续开发,这次我们要实现的功能是在H5页面中点击按钮实现:①拨打电话、②获取系统定位、③拉起第三方地图应用开启导航功能(本文以高德地图为例),本项目是基于API6的JS工程,项目中使用的是JS FA调用Java PA机制(Java中使用WebView组件加载H5页面),OK,下面一起来实战一下吧。
完整代码见文末。
【2、H5页面】
想要实现上面的效果,我们的核心技术点就是JS跟Java的数据交互,可以参考以下官方文档中的实现:
首先准备一个H5页面,页面内容很简单,就是3个按钮,每个按钮绑定一个点击事件,点击事件中是JS调用Java的代码,然后将该文件放在本地entry/src/main/resources/rawfile目录下,这里仅仅是简单写一个H5页面做为测试使用,实际项目开发中此部分内容可以不用看,以实际H5页面地址为准。内容如下:
关于加载本地H5页面可以参考文档中的写法,文档地址如下:
【3、拨打电话】
前面在H5页面中已经定义了JS调用Java端的方法名及参数,这里参考文档中的写法:
然后在Java侧实现addJsCallback(),在回调方法onCallback中实现具体的拨打电话的业务逻辑:
【4、获取定位】
想要获取系统的位置信息,首先需要获取定位权限,关于权限的获取可以参考这篇文章中的实现:
鸿蒙动态权限申请完整规范流程和操作详解-开源基础软件社区-51CTO.COM
我们这里获取的是LOCATION权限,需要在config.json文件的module中添加权限配置,
然后需要编写动态获取权限的代码:
在获取权限之后,就可以编写获取位置信息的代码了,关于如何获取位置信息可以参考这篇文章:
HarmonyOS使用Java获取位置信息-java获取当前位置
location对象中就可以获取到经纬度等位置信息了。然后同样的需要实现onCallback()方法:
【5、跳转导航】
这里我们是通过(逆)地理编码转化结合Scheme跳转来实现拉起导航功能的,(逆)地理编码转化的参考文档如下:
高德地图导航的Scheme协议要求如下:
导航-Android-开发指南-高德地图手机版 | 高德地图API
跳转的代码就很简单啦:
同样的需要实现onCallback()方法:
【6、实现效果】
最后来看一下实现的效果吧:
【7、完整代码】
test.html文件:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>测试页面</title>
- <script>
- function callToApp() {
- if (window.JsCallbackToCall && window.JsCallbackToCall.call) {
- var result = JsCallbackToCall.call("10086");
- }
- }
- function locationToApp() {
- if (window.JsCallbackToLocation && window.JsCallbackToLocation.call) {
- var result = JsCallbackToLocation.call("");
- }
- }
- function naviToApp() {
- if (window.JsCallbackToNavi && window.JsCallbackToNavi.call) {
- var result = JsCallbackToNavi.call("南京市玄武湖");
- }
- }
- </script>
- </head>
-
- <body>
- <div align="center">
- <button type="button" id="btn_call" "callToApp()">电话</button>
- <button type="button" id="btn_location" "locationToApp()">定位</button>
- <button type="button" id="btn_navi" "naviToApp()">导航</button>
- </div>
- </body>
-
- </html>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
相关文本字段strings.json中:
- {
- "name": "permission_location",
- "value": "定位原因"
- }
index.js中跳转H5Ability.java页面代码:
- gotoH5Ability() {
- featureAbility.startAbility({
- want:
- {
- bundleName: "com.jarchie.h5",
- abilityName: "com.jarchie.h5.H5Ability"
- },
- });
- }
config.json中的权限配置:
- "reqPermissions": [
- {
- "name": "ohos.permission.INTERNET"
- },
- {
- "name": "ohos.permission.LOCATION",
- "reason": "$string:permission_location",
- "usedScene": {
- "ability": [
- "com.jarchie.h5.H5Ability"
- ],
- "when": "always"
- }
- }
- ]
H5Ability.java:
- import com.jarchie.h5.slice.H5AbilitySlice;
- import ohos.aafwk.ability.Ability;
- import ohos.aafwk.content.Intent;
- import ohos.agp.window.dialog.ToastDialog;
- import ohos.bundle.IBundleManager;
-
- import static com.jarchie.h5.slice.LocationAbilitySlice.MY_PERMISSIONS_REQUEST_LOCATION;
-
- public class H5Ability extends Ability {
- private H5AbilitySlice h5AbilitySlice;
-
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setMainRoute(H5AbilitySlice.class.getName());
- }
-
- @Override
- public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
- super.onRequestPermissionsFromUserResult(requestCode, permissions, grantResults);
- switch (requestCode) {
- case MY_PERMISSIONS_REQUEST_LOCATION: {
- // 匹配requestPermissions的requestCode
- if (grantResults.length > 0
- && grantResults[0] == IBundleManager.PERMISSION_GRANTED) {
- // 权限被授予之后做相应业务逻辑的处理
- h5AbilitySlice.requestLocation();
- } else {
- // 权限被拒绝
- new ToastDialog(getContext()).setText("权限被拒绝").show();
- }
- return;
- }
- }
- }
-
- public H5AbilitySlice getH5AbilitySlice() {
- return h5AbilitySlice;
- }
-
- public void setH5AbilitySlice(H5AbilitySlice h5AbilitySlice) {
- this.h5AbilitySlice = h5AbilitySlice;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
ability_h5.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <DirectionalLayout
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
- ohos:height="match_parent"
- ohos:width="match_parent"
- ohos:alignment="horizontal_center"
- ohos:orientation="vertical">
-
- <Text
- ohos:id="$+id:back"
- ohos:height="50vp"
- ohos:width="match_parent"
- ohos:start_margin="10vp"
- ohos:end_margin="10vp"
- ohos:text="返回"
- ohos:text_size="18vp"/>
-
- <ohos.agp.components.webengine.WebView
- ohos:id="$+id:webview"
- ohos:height="match_parent"
- ohos:width="match_parent"/>
- </DirectionalLayout>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
H5AbilitySlice.java:
- import com.jarchie.h5.H5Ability;
- import com.jarchie.h5.ResourceTable;
- import ohos.aafwk.ability.AbilitySlice;
- import ohos.aafwk.content.Intent;
- import ohos.aafwk.content.Operation;
- import ohos.agp.components.Text;
- import ohos.agp.components.webengine.*;
- import ohos.agp.utils.TextTool;
- import ohos.agp.window.dialog.ToastDialog;
- import ohos.bundle.IBundleManager;
- import ohos.global.resource.Resource;
- import ohos.hiviewdfx.HiLog;
- import ohos.hiviewdfx.HiLogLabel;
- import ohos.location.*;
- import ohos.utils.net.Uri;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URLConnection;
- import java.util.List;
-
- public class H5AbilitySlice extends AbilitySlice {
- private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, H5AbilitySlice.class.getName());
- private Text backText;
- private WebView webView;
- // 定位
- public static final int MY_PERMISSIONS_REQUEST_LOCATION = 0;
- private Locator locator;
- private RequestParam requestParam;
- private MyLocatorCallback locatorCallback;
-
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_h5);
- H5Ability h5Ability = (H5Ability) getAbility();
- h5Ability.setH5AbilitySlice(this);
- initBackText();
- initWebView();
- callPhone();
- location();
- navi();
- }
-
- private void navi(){
- final String jsName = "JsCallbackToNavi";
- webView.addJsCallback(jsName, new JsCallback() {
- @Override
- public String onCallback(String msg) {
- gotoGaode(msg);
- return "jsResult";
- }
- });
- }
-
- // 获取定位
- private void location(){
- final String jsName = "JsCallbackToLocation";
- webView.addJsCallback(jsName, new JsCallback() {
- @Override
- public String onCallback(String msg) {
- requestPermission();
- return "jsResult";
- }
- });
- }
-
- // 拨打电话
- private void callPhone(){
- final String jsName = "JsCallbackToCall";
- webView.addJsCallback(jsName, new JsCallback() {
- @Override
- public String onCallback(String msg) {
- // 增加自定义处理
- Intent intent = new Intent();
- intent.setAction("ohos.intent.action.dial");
- intent.setUri(Uri.parse("tel:"+msg));
- startAbility(intent,0);
- return "jsResult";
- }
- });
- }
-
- private void gotoGaode(String destination){
- try {
- // (逆)地理编码转换
- GeoConvert geoConvert = new GeoConvert();
- List<GeoAddress> geoList = geoConvert.getAddressFromLocationName(destination, 1);
- GeoAddress geoAddress = geoList.get(0);
- if (geoAddress == null)
- return;
- Intent intent1 = new Intent();
- Operation operation = new Intent.OperationBuilder()
- .withAction("android.intent.action.VIEW")
- .withUri(Uri.parse("androidamap://navi?sourceApplication=amap&lat="+geoAddress.getLatitude()+"&lon="+geoAddress.getLongitude()+"&dev=1&style=2"))
- .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)
- .build();
- intent1.setOperation(operation);
- startAbility(intent1);
- }catch (Exception e){
- e.printStackTrace();
- }
- }
-
- private void requestPermission() {
- if (verifySelfPermission("ohos.permission.LOCATION") != IBundleManager.PERMISSION_GRANTED) {
- // 应用未被授予权限
- if (canRequestPermission("ohos.permission.LOCATION")) {
- // 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
- requestPermissionsFromUser(new String[]{"ohos.permission.LOCATION"}, MY_PERMISSIONS_REQUEST_LOCATION);
- } else {
- // 显示应用需要权限的理由,提示用户进入设置授权
- new ToastDialog(getContext()).setText("请进入系统设置进行授权").show();
- }
- } else {
- // 权限已被授予
- requestLocation();
- }
- }
-
- public void requestLocation() {
- locator = new Locator(this);
- requestParam = new RequestParam(RequestParam.SCENE_NAVIGATION);
- locatorCallback = new MyLocatorCallback();
- locator.requestOnce(requestParam, locatorCallback); // 请求一次
- // locator.startLocating(requestParam, locatorCallback); // 多次请求 直接启动服务
- }
-
- public class MyLocatorCallback implements LocatorCallback {
- @Override
- public void onLocationReport(Location location) {
- if (location != null) {
- getUITaskDispatcher().asyncDispatch(() -> {
- // (逆)地理编码转换
- GeoConvert geoConvert = new GeoConvert();
- try {
- List<GeoAddress> list = geoConvert.getAddressFromLocation(location.getLatitude(), location.getLongitude(), 1);
- GeoAddress geoAddress = list.get(0);
- if (geoAddress == null)
- return;
- new ToastDialog(getContext())
- .setText("当前位置:经度:" + location.getLongitude() + "\n纬度:" + location.getLatitude()
- + "\n国家:" + geoAddress.getCountryName())
- .show();
- // "位置:" + geoAddress.getPlaceName()
- } catch (IOException e) {
- e.printStackTrace();
- }
- });
- }
- }
-
- @Override
- public void onStatusChanged(int type) {
- }
-
- @Override
- public void onErrorReport(int type) {
- }
- }
-
- // 初始化WebView
- private void initWebView() {
- webView = (WebView) findComponentById(ResourceTable.Id_webview);
- webView.getWebConfig().setJavaScriptPermit(true); // 如果网页需要使用JavaScript,增加此行
- webView.getWebConfig().setWebStoragePermit(true);
- webView.setWebAgent(new WebAgent() {
- @Override
- public ResourceResponse processResourceRequest(WebView webview, ResourceRequest request) {
- final String authority = "com.jarchie.h5";
- final String rawFile = "/rawfile/";
- final String local = "/local/";
- Uri requestUri = request.getRequestUrl();
- if (authority.equals(requestUri.getDecodedAuthority())) {
- String path = requestUri.getDecodedPath();
- if (TextTool.isNullOrEmpty(path)) {
- return super.processResourceRequest(webview, request);
- }
- if (path.startsWith(rawFile)) {
- // 根据自定义规则访问资源文件
- String rawFilePath = "entry/resources/rawfile/" + path.replace(rawFile, "");
- String mimeType = URLConnection.guessContentTypeFromName(rawFilePath);
- try {
- Resource resource = getResourceManager().getRawFileEntry(rawFilePath).openRawFile();
- ResourceResponse response = new ResourceResponse(mimeType, resource, null);
- return response;
- } catch (IOException e) {
- HiLog.info(TAG, "open raw file failed");
- }
- }
- if (path.startsWith(local)) {
- // 根据自定义规则访问本地文件
- String localFile = getContext().getFilesDir() + path.replace(local, "/");
- HiLog.info(TAG, "open local file " + localFile);
- File file = new File(localFile);
- if (!file.exists()) {
- HiLog.info(TAG, "file not exists");
- return super.processResourceRequest(webview, request);
- }
- String mimeType = URLConnection.guessContentTypeFromName(localFile);
- try {
- InputStream inputStream = new FileInputStream(file);
- ResourceResponse response = new ResourceResponse(mimeType, inputStream, null);
- return response;
- } catch (IOException e) {
- HiLog.info(TAG, "open local file failed");
- }
- }
- }
- return super.processResourceRequest(webview, request);
- }
- });
- webView.load("https://com.jarchie.h5/rawfile/test.html");
- }
-
- // 初始化返回文本
- private void initBackText() {
- backText = (Text) findComponentById(ResourceTable.Id_back);
- backText.setClickedListener(component -> onBackPressed());
- }
-
- @Override
- public void onActive() {
- HiLog.info(TAG, "onActive:");
- super.onActive();
- }
-
- @Override
- public void onForeground(Intent intent) {
- HiLog.info(TAG, "onForeground:");
- super.onForeground(intent);
- }
-
- @Override
- protected void onStop() {
- HiLog.info(TAG, "onStop:");
- super.onStop();
- locator.stopLocating(locatorCallback);
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。