设备中包含许多传感器,如加速度传感器、角速度传感器、磁场传感器、温度传感器、大气压力传感器等等。这些传感器为设备提供了感知外界环境的能力。例如,借助加速度传感器,手机可以获知其姿态信息,运行在手机上的应用程序可以根据这些信息对横放、竖放、平放等不同姿态做出相应的反馈。
在鸿蒙系统中,所有关于传感器的API都被封装在ohos.sensor包的六个类中。这些类的名字均以Category开头,并以Agent结尾,中间单词为Motion、Environment、Orientation、Light、Body和Other,分别表示运动、环境、方向、光线、健康和其它传感器。
划分这些类的依据是面向应用的能力集,而非实现其功能的物理设备。一个传感器类可能会涉及多个不同的传感器设备,一个传感器设备也可能同时支持多个不同的传感器类。
传感器提供的信息随时都可能发生变化。为了满足数据更新的实时性,应用程序通常采用订阅的方式获取传感器的输出,即由传感器在数据发生变化时,主动通知应用程序,应用程序在与这些通知对应的回调方法中,被动地对传感器数据做出响应。
z y
| /
______
/ /
/ /
/ /
/_____/ _x
加速度传感器可以感知重力加速度在三个轴上的分量。
"reqPermissions": [ { "name": "ohos.permission.ACCELEROMETER" } ]
CategoryMotionAgent agent = new CategoryMotionAgent();
CategoryMotion motion = agent.getSingleSensor( CategoryMotion.SENSOR_TYPE_ACCELEROMETER);
ICategoryMotionDataCallback callback = new ICategoryMotionDataCallback() { @Override public void onSensorDataModified( CategoryMotionData categoryMotionData) { // 数据更新回调 ... } @Override public void onAccuracyDataModified( CategoryMotion categoryMotion, int i) { // 精度改变回调 ... } @Override public void onCommandCompleted( CategoryMotion categoryMotion) { // 命令完成回调 ... } };
agent.setSensorDataCallback(callback, motion, SensorAgent.SENSOR_SAMPLING_RATE_UI);
agent.releaseSensorDataCallback(callback, motion);
例程:Gravity
...\Gravity\entry\src\main\config.json
{ ... "module": { ... "reqPermissions": [ { "name": "ohos.permission.ACCELEROMETER" } ] } }
...\Gravity\entry\src\main\resources\base\layout\ability_main.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="center" ohos:orientation="vertical" ohos:background_element="#000000"> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.3" ohos:text="Gx" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="right" /> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.1" ohos:text="=" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtGx" ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.6" ohos:text_size="28fp" ohos:text_color="#ff7f27" ohos:text_alignment="left" /> </DirectionalLayout> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.3" ohos:text="Gy" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="right" /> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.1" ohos:text="=" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtGy" ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.6" ohos:text_size="28fp" ohos:text_color="#ff7f27" ohos:text_alignment="left" /> </DirectionalLayout> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.3" ohos:text="Gz" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="right" /> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.1" ohos:text="=" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtGz" ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.6" ohos:text_size="28fp" ohos:text_color="#ff7f27" ohos:text_alignment="left" /> </DirectionalLayout> </DirectionalLayout>
...\Gravity\entry\src\main\java\com\minwei\gravity\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private Text txtGx, txtGy, txtGz; private CategoryMotionAgent agent; private CategoryMotion motion; private ICategoryMotionDataCallback callback; @Override public void onStart(Intent intent) { ... txtGx = (Text)findComponentById(ResourceTable.Id_txtGx); txtGy = (Text)findComponentById(ResourceTable.Id_txtGy); txtGz = (Text)findComponentById(ResourceTable.Id_txtGz); agent = new CategoryMotionAgent(); motion = agent.getSingleSensor( CategoryMotion.SENSOR_TYPE_ACCELEROMETER); callback = new ICategoryMotionDataCallback() { @Override public void onSensorDataModified( CategoryMotionData categoryMotionData) { getUITaskDispatcher().asyncDispatch(() -> { txtGx.setText(String.valueOf( categoryMotionData.values[0])); txtGy.setText(String.valueOf( categoryMotionData.values[1])); txtGz.setText(String.valueOf( categoryMotionData.values[2])); }); } @Override public void onAccuracyDataModified( CategoryMotion categoryMotion, int i) { } @Override public void onCommandCompleted( CategoryMotion categoryMotion) { } }; agent.setSensorDataCallback(callback, motion, SensorAgent.SENSOR_SAMPLING_RATE_UI); } ... @Override protected void onStop() { super.onStop(); agent.releaseSensorDataCallback(callback, motion); } }
运行效果如下图所示:
分类 | 代理 | 测量值 |
---|---|---|
运动 | CategoryMotionAgent | 加速度、角速度、步数 |
环境 | CategoryEnvironmentAgent | 温度、湿度、磁场、气压 |
方向 | CategoryOrientationAgent | 自由度、屏向、设备方向、旋转矢量 |
光线 | CategoryLightAgent | 接近光、环境光、色温、ToF |
健康 | CategoryBodyAgent | 心率、佩戴 |
其它 | CategoryOtherAgent | 霍尔、手握 |
CategoryMotionAgent agent = new CategoryMotionAgent();
\ /
分类
/ \
CategoryMotion motion = agent.getSingleSensor(
CategoryMotion.SENSOR_TYPE_ACCELEROMETER);
\_______________________/
测量值
CategoryOrientationAgent agent = new CategoryOrientationAgent();
CategoryOrientation orientation = agent.getSingleSensor( CategoryOrientation.SENSOR_TYPE_ORIENTATION);
ICategoryOrientationDataCallback callback = new ICategoryOrientationDataCallback() { @Override public void onSensorDataModified( ... } @Override public void onAccuracyDataModified( CategoryOrientation categoryOrientation, int i) { ... } @Override public void onCommandCompleted( CategoryOrientation categoryOrientation) { ... } };
agent.setSensorDataCallback(callback, orientation, SensorAgent.SENSOR_SAMPLING_RATE_UI);
agent.releaseSensorDataCallback(callback, orientation);
例程:Compass
...\Compass\entry\src\main\config.json
{ ... "module": { ... "abilities": [ { ... "orientation": "portrait", ... } ] } }
...\Compass\entry\src\main\resources\base\media\compass.png
...\Compass\entry\src\main\resources\base\media\arrow.png
...\Compass\entry\src\main\resources\base\layout\ability_main.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="center" ohos:orientation="vertical" ohos:background_element="#1b1c20"> <StackLayout ohos:height="match_content" ohos:width="match_content"> <Image ohos:id="$+id:img" ohos:height="match_content" ohos:width="match_content" ohos:top_margin="60vp" ohos:image_src="$media:compass" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <Text ohos:id="$+id:txt" ohos:height="match_content" ohos:width="match_parent" ohos:text_size="28fp" ohos:text_color="#d04c40" ohos:text_alignment="horizontal_center"/> <Image ohos:height="match_content" ohos:width="match_content" ohos:top_margin="20vp" ohos:image_src="$media:arrow" /> </DirectionalLayout> </StackLayout> </DirectionalLayout>
...\Compass\entry\src\main\java\com\minwei\compass\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private Text txt; private Component img; private CategoryOrientationAgent agent; private CategoryOrientation orientation; private ICategoryOrientationDataCallback callback; @Override public void onStart(Intent intent) { ... txt = (Text)findComponentById(ResourceTable.Id_txt); img = findComponentById(ResourceTable.Id_img); agent = new CategoryOrientationAgent(); orientation = agent.getSingleSensor( CategoryOrientation.SENSOR_TYPE_ORIENTATION); callback = new ICategoryOrientationDataCallback() { @Override public void onSensorDataModified( CategoryOrientationData categoryOrientationData) { getUITaskDispatcher().asyncDispatch(() -> { txt.setText("北偏" + String.valueOf( (int)categoryOrientationData.values[0]) + "°"); img.setRotation(-categoryOrientationData.values[0]); }); } @Override public void onAccuracyDataModified( CategoryOrientation categoryOrientation, int i) { } @Override public void onCommandCompleted( CategoryOrientation categoryOrientation) { } }; agent.setSensorDataCallback(callback, orientation, SensorAgent.SENSOR_SAMPLING_RATE_UI); } ... @Override protected void onStop() { super.onStop(); agent.releaseSensorDataCallback(callback, orientation); } }
运行效果如下图所示:
其中请求参数中包含了与精度和功耗有关的各种优先级和应用场景,如:
获取位置信息需要ohos.permission.LOCATION权限,该权限需要动态申请。
Locator locator = new Locator(this);
RequestParam param = new RequestParam(RequestParam.SCENE_NAVIGATION);
LocatorCallback callback = new LocatorCallback() { @Override public void onLocationReport(Location location) { ... } @Override public void onStatusChanged(int i) { ... } @Override public void onErrorReport(int i) { ... } };
locator.startLocating(param, callback);
locator.stopLocating(callback);
例程:Locator
...\Locator\entry\src\main\config.json
{ ... "module": { ... "reqPermissions": [ { "name": "ohos.permission.LOCATION" } ] } }
...\Locator\entry\src\main\resources\base\layout\ability_main.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="center" ohos:orientation="vertical" ohos:background_element="#000000"> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.3" ohos:text="经度" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="right" /> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.1" ohos:text="=" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtLongitude" ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.6" ohos:text_size="28fp" ohos:text_color="#22b14c" ohos:text_alignment="left" /> </DirectionalLayout> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.3" ohos:text="纬度" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="right" /> <Text ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.1" ohos:text="=" ohos:text_size="28fp" ohos:text_color="#ffffff" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtLatitude" ohos:height="match_content" ohos:width="match_parent" ohos:weight="0.6" ohos:text_size="28fp" ohos:text_color="#22b14c" ohos:text_alignment="left" /> </DirectionalLayout> </DirectionalLayout>
...\Locator\entry\src\main\java\com\minwei\locator\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private Text txtLongitude, txtLatitude; private Locator locator; private LocatorCallback callback; @Override public void onStart(Intent intent) { ... requestPermissions(); txtLongitude = (Text)findComponentById( ResourceTable.Id_txtLongitude); txtLatitude = (Text)findComponentById( ResourceTable.Id_txtLatitude); locator = new Locator(this); RequestParam param = new RequestParam( RequestParam.SCENE_NAVIGATION); callback = new LocatorCallback() { @Override public void onLocationReport(Location location) { getUITaskDispatcher().asyncDispatch(() -> { txtLongitude.setText(String.valueOf( location.getLongitude())); txtLatitude.setText(String.valueOf( location.getLatitude())); }); } @Override public void onStatusChanged(int i) { } @Override public void onErrorReport(int i) { } }; locator.startLocating(param, callback); } ... @Override protected void onStop() { super.onStop(); locator.stopLocating(callback); } private void requestPermissions() { List<String> reqPermissions = new ArrayList<>(); String[] permissions = {"ohos.permission.LOCATION"}; for (String permission : permissions) if (verifySelfPermission(permission) != 0 && canRequestPermission(permission)) reqPermissions.add(permission); requestPermissionsFromUser( reqPermissions.toArray(new String[0]), 0); } }
运行效果如下图所示:
通过地理编码(Geocode)可以实现地名地址和地理坐标(经纬度)之间的相互转换:
使用地理编码需要访问网络,应先申请ohos.permission.INTERNET权限。
GeoConvert geoConvert = new GeoConvert(Locale.getDefault());
List<GeoAddress> geoAddresses = geoConvert .getAddressFromLocationName(name, 1);
List<GeoAddress> geoAddresses = geoConvert .getAddressFromLocation(latitude, longitude, 1);
例程:Geocode
...\Geocode\entry\src\main\config.json
{ ... "module": { ... "reqPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }
...\Geocode\entry\src\main\resources\base\graphic\background_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="100"/> <solid ohos:color="#00a2e8"/> </shape>
...\Geocode\entry\src\main\resources\base\layout\ability_main.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:left_padding="80vp" ohos:right_padding="80vp" ohos:alignment="center" ohos:orientation="vertical"> <Text ohos:height="match_content" ohos:width="match_content" ohos:text="地理编码" ohos:text_size="28fp" ohos:text_color="#00a2e8" /> <Text ohos:height="2vp" ohos:width="match_parent" ohos:top_margin="10vp" ohos:bottom_margin="5vp" ohos:background_element="#00a2e8" /> <Button ohos:id="$+id:btnCode" ohos:height="match_content" ohos:width="match_parent" ohos:padding="8vp" ohos:top_margin="10vp" ohos:background_element="$graphic:background_button" ohos:text="地址转坐标" ohos:text_size="24fp" ohos:text_color="#ffffff" /> <Button ohos:id="$+id:btnDecode" ohos:height="match_content" ohos:width="match_parent" ohos:padding="8vp" ohos:top_margin="10vp" ohos:background_element="$graphic:background_button" ohos:text="坐标转地址" ohos:text_size="24fp" ohos:text_color="#ffffff" /> </DirectionalLayout>
...\Geocode\entry\src\main\java\com\minwei\geocode\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private static final HiLogLabel label = new HiLogLabel( HiLog.LOG_APP, 0x00101, MainAbilitySlice.class.getCanonicalName()); @Override public void onStart(Intent intent) { ... findComponentById(ResourceTable.Id_btnCode) .setClickedListener(component -> onCode()); findComponentById(ResourceTable.Id_btnDecode) .setClickedListener(component -> onDecode()); } ... private void onCode() { getGlobalTaskDispatcher(TaskPriority.DEFAULT) .asyncDispatch(() -> code("北京动物园")); } private void onDecode() { getGlobalTaskDispatcher(TaskPriority.DEFAULT) .asyncDispatch(() -> decode(116.333719, 39.940016)); } private void code(String name) { GeoConvert geoConvert = new GeoConvert(Locale.getDefault()); try { final List<GeoAddress> geoAddresses = geoConvert.getAddressFromLocationName(name, 1); for (GeoAddress geoAddress : geoAddresses) printAddress(geoAddress); } catch (Exception exception) { HiLog.info(label, exception.getLocalizedMessage()); } } private void decode(double longitude, double latitude) { GeoConvert geoConvert = new GeoConvert(Locale.getDefault()); try { final List<GeoAddress> geoAddresses = geoConvert.getAddressFromLocation(latitude, longitude, 1); for (GeoAddress geoAddress : geoAddresses) printAddress(geoAddress); } catch (Exception exception) { HiLog.info(label, exception.getLocalizedMessage()); } } private void printAddress(GeoAddress geoAddress) { String s = geoAddress.getLocale().toString(); if (s != null && !s.isEmpty()) HiLog.info(label, " 语言:%{public}s", s); s = geoAddress.getCountryCode(); if (s != null && !s.isEmpty()) HiLog.info(label, " 国家代码:%{public}s", s); s = geoAddress.getCountryName(); if (s != null && !s.isEmpty()) HiLog.info(label, " 国家名称:%{public}s", s); s = geoAddress.getAdministrativeArea(); if (s != null && !s.isEmpty()) HiLog.info(label, "省级行政区:%{public}s", s); s = geoAddress.getLocality(); if (s != null && !s.isEmpty()) HiLog.info(label, "地级行政区:%{public}s", s); s = geoAddress.getSubAdministrativeArea(); if (s != null && !s.isEmpty()) HiLog.info(label, "乡级行政区:%{public}s", s); s = geoAddress.getSubLocality(); if (s != null && !s.isEmpty()) HiLog.info(label, "县级行政区:%{public}s", s); s = geoAddress.getRoadName(); if (s != null && !s.isEmpty()) HiLog.info(label, " 道路名称:%{public}s", s); s = geoAddress.getSubRoadName(); if (s != null && !s.isEmpty()) HiLog.info(label, "道路子名称:%{public}s", s); s = geoAddress.getPlaceName(); if (s != null && !s.isEmpty()) HiLog.info(label, " 地名:%{public}s", s); s = geoAddress.getPremises(); if (s != null && !s.isEmpty()) HiLog.info(label, "单元房间号:%{public}s", s); s = geoAddress.getPostalCode(); if (s != null && !s.isEmpty()) HiLog.info(label, " 邮政编码:%{public}s", s); s = geoAddress.getPhoneNumber(); if (s != null && !s.isEmpty()) HiLog.info(label, " 电话号码:%{public}s", s); if (geoAddress.hasLongitude()) HiLog.info(label, " 经度:%{public}f", geoAddress.getLongitude()); if (geoAddress.hasLatitude()) HiLog.info(label, " 纬度:%{public}f", geoAddress.getLatitude()); for (int i = 0; i < geoAddress.getDescriptionsSize(); ++i) HiLog.info(label, " 描述信息:%{public}s", geoAddress.getDescriptions(i)); } }
运行效果如下图所示:
TinyMap是HarmonyOS技术的先行者——董昱先生开发的首个可在鸿蒙系统上运行的开源地图组件。其开源地址为:
https://gitee.com/dongyu1009/tiny-map-for-harmony-os
其包结构如下:
com
│
└─dongyu
│
└─tinymap
│
├─Element.java
├─Tile.java
└─TinyMap.java
由于TinyMap使用的是高德在线地图,因此需要申请网络访问权限:
"reqPermissions": [ { "name": "ohos.permission.INTERNET" } ]
在页面布局中添加TinyMap组件:
<com.dongyu.tinymap.TinyMap
ohos:id="$+id:tm"
ohos:height="match_parent"
ohos:width="match_parent"/>
并在Java代码中获取该组件:
TinyMap tm = (TinyMap)findComponentById(ResourceTable.Id_tm);
TinyMap的五个常用方法:
例程:Map
...\Map\entry\src\main\config.json
{ ... "module": { ... "reqPermissions": [ { "name": "ohos.permission.INTERNET" }, { "name": "ohos.permission.LOCATION" } ] } }
...\Map\entry\src\main\resources\base\media\dot.png
...\Map\entry\src\main\resources\base\graphic\background_blue_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="32"/> <solid ohos:color="#c000a2e8"/> </shape>
...\Map\entry\src\main\resources\base\graphic\background_green_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="32"/> <solid ohos:color="#c022b14c"/> </shape>
...\Map\entry\src\main\resources\base\graphic\background_orange_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="32"/> <solid ohos:color="#c0ff7f27"/> </shape>
...\Map\entry\src\main\resources\base\graphic\background_red_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="32"/> <solid ohos:color="#c0ff4040"/> </shape>
...\Map\entry\src\main\resources\base\layout\ability_main.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"> <StackLayout ohos:height="match_parent" ohos:width="match_parent"> <com.dongyu.tinymap.TinyMap ohos:id="$+id:tm" ohos:height="match_parent" ohos:width="match_parent"/> <DirectionalLayout ohos:height="match_parent" ohos:width="match_parent" ohos:margin="10vp"> <Button ohos:id="$+id:btnZoomin" ohos:height="match_content" ohos:width="match_content" ohos:padding="8vp" ohos:layout_alignment="right" ohos:background_element="$graphic:background_blue_button" ohos:text="放大" ohos:text_size="20fp" ohos:text_color="#ffffff" /> <Button ohos:id="$+id:btnZoomout" ohos:height="match_content" ohos:width="match_content" ohos:padding="8vp" ohos:top_margin="5vp" ohos:layout_alignment="right" ohos:background_element="$graphic:background_green_button" ohos:text="缩小" ohos:text_size="20fp" ohos:text_color="#ffffff" /> <Button ohos:id="$+id:btnSwitch" ohos:height="match_content" ohos:width="match_content" ohos:padding="8vp" ohos:top_margin="5vp" ohos:layout_alignment="right" ohos:background_element="$graphic:background_orange_button" ohos:text="切换" ohos:text_size="20fp" ohos:text_color="#ffffff" /> <Button ohos:id="$+id:btnLocator" ohos:height="match_content" ohos:width="match_content" ohos:padding="8vp" ohos:top_margin="5vp" ohos:layout_alignment="right" ohos:background_element="$graphic:background_red_button" ohos:visibility="hide" ohos:text="定位" ohos:text_size="20fp" ohos:text_color="#ffffff" /> </DirectionalLayout> </StackLayout> </DirectionalLayout>
...\Map\entry\src\main\java\com\minwei\map\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private TinyMap tm; private Locator locator; private LocatorCallback callback; private double longitude, latitude; private int source; @Override public void onStart(Intent intent) { ... requestPermissions(); tm = (TinyMap)findComponentById(ResourceTable.Id_tm); switchSource(0); findComponentById(ResourceTable.Id_btnZoomin) .setClickedListener(component -> onZoomin()); findComponentById(ResourceTable.Id_btnZoomout) .setClickedListener(component -> onZoomout()); findComponentById(ResourceTable.Id_btnSwitch) .setClickedListener(component -> onSwitch()); findComponentById(ResourceTable.Id_btnLocator) .setClickedListener(component -> onLocator()); locator = new Locator(this); RequestParam param = new RequestParam( RequestParam.SCENE_NAVIGATION); callback = new LocatorCallback() { @Override public void onLocationReport(Location location) { longitude = location.getLongitude(); latitude = location.getLatitude(); getUITaskDispatcher().asyncDispatch(() -> { findComponentById(ResourceTable.Id_btnLocator) .setVisibility(Component.VISIBLE); }); } @Override public void onStatusChanged(int i) { } @Override public void onErrorReport(int i) { } }; locator.startLocating(param, callback); } ... @Override protected void onStop() { super.onStop(); locator.stopLocating(callback); } private void requestPermissions() { List<String> reqPermissions = new ArrayList<>(); String[] permissions = {"ohos.permission.LOCATION"}; for (String permission : permissions) if (verifySelfPermission(permission) != 0 && canRequestPermission(permission)) reqPermissions.add(permission); requestPermissionsFromUser( reqPermissions.toArray(new String[0]), 0); } private void onZoomin() { tm.zoomIn(); } private void onZoomout() { tm.zoomOut(); } private void onSwitch() { ListDialog dialog = new ListDialog(this, ListDialog.SINGLE); dialog.setAutoClosable(true); dialog.setSingleSelectItems(new String[] { "高德地图 - 矢量", "高德地图 - 道路", "高德地图 - 卫星"}, source); dialog.setOnSingleSelectListener( new IDialog.ClickedListener() { @Override public void onClick(IDialog iDialog, int i) { switchSource(i); } }); dialog.show(); dialog.getListContainer().setPaddingLeft(42); } private void onLocator() { double[] mercator = toMercator(longitude, latitude); tm.addElement((float)mercator[0], (float)mercator[1], ResourceTable.Media_dot); } private void switchSource(int src) { switch (source = src) { case 0: tm.setMapSource(MapSource.GAODE_VECTOR); break; case 1: tm.setMapSource(MapSource.GAODE_ROAD); break; case 2: tm.setMapSource(MapSource.GAODE_SATELLITE); break; } tm.refreshMap(); } private double[] toMercator(double longitude, double latitude) { double x = longitude * 20037508.342789 / 180; double y = Math.log(Math.tan((latitude + 90) * Math.PI / 360)) / (Math.PI / 180) * 20037508.342789 / 180; return new double[] {x, y}; } }
运行效果如下图所示: