linee 6 dní pred
rodič
commit
316d1559bc

+ 1 - 0
build.gradle

@@ -38,6 +38,7 @@ buildscript {
     dependencies {
         classpath 'com.huawei.ohos:hap:3.1.5.0'
         classpath 'com.huawei.ohos:decctest:1.2.7.20'
+        classpath 'com.huawei.agconnect:agcp-harmony:1.3.0.300'
     }
 }
 

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 0
entry/agconnect-services.json


+ 4 - 0
entry/build.gradle

@@ -1,4 +1,5 @@
 apply plugin: 'com.huawei.ohos.hap'
+apply plugin: 'com.huawei.agconnect'
 apply plugin: 'com.huawei.ohos.decctest'
 //For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/ide_debug_device-0000001053822404-V3#section1112183053510
 ohos {
@@ -34,6 +35,9 @@ dependencies {
     implementation 'com.huawei.hms:maps-harmony:6.4.0.300'
     testImplementation 'junit:junit:4.13.1'
     ohosTestImplementation 'com.huawei.ohos.testkit:runner:2.0.0.400'
+
+    implementation 'com.huawei.hms:hwid-ohos:6.5.0.300'
+    implementation 'com.huawei.agconnect:agconnect-core-harmony:1.3.0.300'
 }
 decc {
     supportType = ['html', 'xml']

+ 3 - 1
entry/proguard-rules.pro

@@ -6,4 +6,6 @@
 -keepattributes SourceFile,LineNumberTable
 -keep class com.huawei.hianalytics.**{*;}
 -keep class com.huawei.updatesdk.**{*;}
--keep class com.huawei.hms.**{*;}
+-keep class com.huawei.hms.**{*;}
+-keep class com.huawei.harmony.**{*;}
+-keep class com.huawei.mylibrary.**{*;}

+ 18 - 3
entry/src/main/config.json

@@ -7,10 +7,20 @@
       "name": "1.0.0"
     }
   },
-  "deviceConfig": {},
+  "deviceConfig": {
+    "default": {
+      "network": {
+        "cleartextTraffic": true
+      }
+    }
+  },
   "module": {
     "allowClassMap": true,
     "reqPermissions": [
+      {
+        "name": "ohos.permission.MANAGE_SECURE_SETTINGS",
+        "reason": "获取设置项的车牌信息"
+      },
       {
         "name": "ohos.permission.LOCATION",
         "reason": "需要定位权限以在地图上显示当前位置",
@@ -58,6 +68,10 @@
           "name": "hwc-theme",
           "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar",
           "extra": ""
+        },
+        {
+          "name": "com.huawei.hms.client.appid",
+          "value": "6917590990169282724"
         }
       ]
     },
@@ -92,10 +106,11 @@
             "scheduledUpdateTime": "10:30",
             "defaultDimension": "2*2",
             "name": "widget",
-            "description": "This is a service widget.",
+            "description": "爱泊客停车缴费",
             "colorMode": "auto",
             "type": "JS",
             "supportDimensions": [
+              "2*4",
               "2*2"
             ],
             "updateEnabled": true,
@@ -115,10 +130,10 @@
     "name": ".MyApplication",
     "js": [
       {
+        "name": "widget",
         "pages": [
           "pages/index/index"
         ],
-        "name": "widget",
         "window": {
           "designWidth": 720,
           "autoDesignWidth": true

+ 29 - 0
entry/src/main/java/com/fujica/abk/MyApplication.java

@@ -1,10 +1,39 @@
 package com.fujica.abk;
 
+import com.huawei.hms.accountsdk.exception.ApiException;
+import com.huawei.hms.accountsdk.support.account.AccountAuthManager;
+import com.huawei.hms.accountsdk.support.account.tasks.Task;
 import ohos.aafwk.ability.AbilityPackage;
 
 public class MyApplication extends AbilityPackage {
     @Override
     public void onInitialize() {
         super.onInitialize();
+        // 调用示例initHuaweiAccountSDK方法,在HarmonyOS应用初始化方法onInitialize中进行华为帐号SDK初始化
+        initHuaweiAccountSDK();
+    }
+
+    // 示例:此方法中调用华为帐号SDK的初始化方法AccountAuthManager.init()进行初始化
+    private void initHuaweiAccountSDK() {
+        Task<Void> task;
+        try {
+            // 调用AccountAuthManager.init方法初始化
+            task = AccountAuthManager.init(this);
+        } catch (ApiException apiException) {
+            apiException.getStatusCode();
+            return;
+        }
+        task.addOnSuccessListener(v -> {
+            //初始化成功
+        });
+
+        task.addOnFailureListener(e -> {
+            // SDK初始化失败
+            if (e instanceof ApiException) {
+                ApiException apiException = (ApiException) e;
+                // SDK初始化失败,status code标识了失败的原因,请参见API参考中的错误码了解详细错误原因
+                apiException.getStatusCode();
+            }
+        });
     }
 }

+ 67 - 0
entry/src/main/java/com/fujica/abk/api/cache.java

@@ -0,0 +1,67 @@
+package com.fujica.abk.api;
+
+import ohos.app.Context;
+import ohos.data.DatabaseHelper;
+import ohos.data.preferences.Preferences;
+
+/**
+ * 缓存工具类
+ */
+public class cache {
+    private static final String PREF_NAME = "app_cache";
+    private static final String KEY_TOKEN = "token";
+
+    /**
+     * 获取Preferences实例
+     */
+    private static Preferences getPreferences(Context context) {
+        DatabaseHelper databaseHelper = new DatabaseHelper(context.getApplicationContext());
+        return databaseHelper.getPreferences(PREF_NAME);
+    }
+
+    /**
+     * 获取Token
+     */
+    public static String getToken(Context context) {
+        try {
+            Preferences preferences = getPreferences(context);
+            if (preferences != null) {
+                return preferences.getString(KEY_TOKEN, "");
+            }
+            return "";
+        } catch (Exception e) {
+            return "";
+        }
+    }
+
+    /**
+     * 保存Token
+     */
+    public static void setToken(Context context, String token) {
+        try {
+            Preferences preferences = getPreferences(context);
+            if (preferences != null) {
+                preferences.putString(KEY_TOKEN, token);
+                preferences.flushSync();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 登出,清除Token
+     */
+    public static void logout(Context context) {
+        try {
+            Preferences preferences = getPreferences(context);
+            if (preferences != null) {
+                preferences.delete(KEY_TOKEN);
+                preferences.flushSync();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
+

+ 70 - 0
entry/src/main/java/com/fujica/abk/common/EventBus.java

@@ -0,0 +1,70 @@
+package com.fujica.abk.common;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 事件总线
+ */
+public class EventBus {
+    private static EventBus instance;
+    private Map<String, List<EventListener>> listeners = new HashMap<>();
+
+    private EventBus() {
+    }
+
+    public static EventBus getInstance() {
+        if (instance == null) {
+            synchronized (EventBus.class) {
+                if (instance == null) {
+                    instance = new EventBus();
+                }
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * 发送事件
+     */
+    public void emit(String event) {
+        List<EventListener> eventListeners = listeners.get(event);
+        if (eventListeners != null) {
+            for (EventListener listener : eventListeners) {
+                listener.onEvent(event);
+            }
+        }
+    }
+
+    /**
+     * 订阅事件
+     */
+    public void on(String event, EventListener listener) {
+        List<EventListener> eventListeners = listeners.get(event);
+        if (eventListeners == null) {
+            eventListeners = new ArrayList<>();
+            listeners.put(event, eventListeners);
+        }
+        eventListeners.add(listener);
+    }
+
+    /**
+     * 取消订阅
+     */
+    public void off(String event, EventListener listener) {
+        List<EventListener> eventListeners = listeners.get(event);
+        if (eventListeners != null) {
+            eventListeners.remove(listener);
+        }
+    }
+
+    /**
+     * 事件监听器接口
+     */
+    public interface EventListener {
+        void onEvent(String event);
+    }
+}
+

+ 168 - 37
entry/src/main/java/com/fujica/abk/slice/MainAbilitySlice.java

@@ -1,44 +1,53 @@
 package com.fujica.abk.slice;
 
 import com.fujica.abk.ResourceTable;
-import ohos.aafwk.ability.AbilitySlice;
-import ohos.aafwk.content.Intent;
-import com.huawei.hms.maps.harmony.HuaweiMap;
-import com.huawei.hms.maps.harmony.MapView;
-import com.huawei.hms.maps.harmony.HuaweiMapOptions;
-import com.huawei.hms.maps.harmony.OnMapClickListener;
-import com.huawei.hms.maps.harmony.OnInfoWindowClickListener;
-import com.huawei.hms.maps.harmony.OnMarkerClickListener;
-import com.huawei.hms.maps.harmony.CameraUpdate;
-import com.huawei.hms.maps.harmony.CameraUpdateFactory;
-import com.huawei.hms.maps.harmony.CommonContext;
+import com.fujica.abk.api.cache;
+import com.fujica.abk.utils.Log;
+import com.fujica.abk.utils.Toast;
+import com.fujica.abk.utils.api;
+import com.huawei.hms.accountsdk.constant.CommonConstant;
+import com.huawei.hms.accountsdk.exception.ApiException;
+import com.huawei.hms.accountsdk.support.account.AccountAuthManager;
+import com.huawei.hms.accountsdk.support.account.request.AccountAuthParams;
+import com.huawei.hms.accountsdk.support.account.request.AccountAuthParamsHelper;
+import com.huawei.hms.accountsdk.support.account.result.AuthAccount;
+import com.huawei.hms.accountsdk.support.account.service.AccountAuthService;
+import com.huawei.hms.accountsdk.support.account.tasks.OnFailureListener;
+import com.huawei.hms.accountsdk.support.account.tasks.OnSuccessListener;
+import com.huawei.hms.accountsdk.support.account.tasks.Task;
+import com.huawei.hms.maps.harmony.*;
 import com.huawei.hms.maps.harmony.model.CameraPosition;
 import com.huawei.hms.maps.harmony.model.LatLng;
 import com.huawei.hms.maps.harmony.model.Marker;
 import com.huawei.hms.maps.harmony.model.MarkerOptions;
-import ohos.agp.components.*;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.ability.DataAbilityHelper;
+import ohos.aafwk.ability.IDataAbilityObserver;
+import ohos.aafwk.content.Intent;
+import ohos.account.AccountAbility;
 import ohos.agp.colors.RgbColor;
+import ohos.agp.colors.StateColor;
+import ohos.agp.components.*;
 import ohos.agp.components.element.ShapeElement;
 import ohos.agp.utils.Color;
 import ohos.agp.window.dialog.ToastDialog;
 import ohos.agp.window.service.Window;
 import ohos.agp.window.service.WindowManager;
-import ohos.hiviewdfx.HiLog;
-import ohos.hiviewdfx.HiLogLabel;
+import ohos.global.resource.NotExistException;
+import ohos.global.resource.Resource;
 import ohos.location.Location;
 import ohos.location.Locator;
 import ohos.location.LocatorCallback;
 import ohos.location.RequestParam;
-import ohos.global.resource.NotExistException;
-import ohos.global.resource.Resource;
+import ohos.sysappcomponents.settings.AppSettings;
+import ohos.sysappcomponents.settings.SystemSettings;
 
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
 public class MainAbilitySlice extends AbilitySlice {
-    private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, MainAbilitySlice.class.getName());
-
     // PageSlider相关
     private PageSlider pageSlider;
     private PageSliderProvider pageSliderProvider;
@@ -82,11 +91,21 @@ public class MainAbilitySlice extends AbilitySlice {
      * 当前位置标记
      */
     private Marker currentLocationMarker;
+    DataAbilityHelper dataAbilityHelper;
+    IDataAbilityObserver dataAbilityObserver;
 
     @Override
     public void onStart(Intent intent) {
         super.onStart(intent);
 
+        cache.setToken(getContext(), "sdfdsfdsf11111111111");
+        String token = cache.getToken(getContext());
+
+//        api.http(getContext(), "http://www.baidu.com", "GET", null, null, null);
+
+        api.http(getContext(), "/park/near/page?longitude=0&latitude=0", "GET", null, null, null);
+
+
         // 设置全屏显示
         setFullScreen();
 
@@ -107,8 +126,112 @@ public class MainAbilitySlice extends AbilitySlice {
 
         // 初始化定位
         initLocation();
+
+        Button mBtnHuaweiIdSignIn = findComponentById(ResourceTable.Id_btn_hwid_sign_in);
+        mBtnHuaweiIdSignIn.setClickedListener((Component c) -> {
+            huaweiIdSignIn();
+        });
+
+        final String key = "car_license_plate_number";
+//        final String key = SystemSettings.Date.TIME_FORMAT;
+
+        dataAbilityHelper = DataAbilityHelper.creator(this);
+        dataAbilityObserver = () -> {
+            String timeFormat = SystemSettings.getValue(dataAbilityHelper, key);
+            setTimeFormat(timeFormat);
+        };
+        dataAbilityHelper.registerObserver(SystemSettings.getUri(key), dataAbilityObserver);
+        String timeFormat1 = SystemSettings.getValue(dataAbilityHelper, "car_license_plate_number");
+        String timeFormat = SystemSettings.getValue(dataAbilityHelper, key);
     }
 
+    void setTimeFormat(String timeFormat) {
+        String timeStr = "12";
+        if (timeStr.equals(timeFormat)) {
+            // Display in 12-hour format
+        } else {
+            // Display in 24-hour format
+        }
+    }
+
+    void huaweiIdSignIn() {
+        AccountAuthService accountAuthService;
+        // 1、配置登录请求参数AccountAuthParams,包括请求用户id(openid、unionid)、email、profile(昵称、头像)等。
+        // 2、DEFAULT_AUTH_REQUEST_PARAM默认包含了id和profile(昵称、头像)的请求。
+        // 3、如需要再获取用户邮箱,需要setEmail();
+        // 4、如需要获取其他受限信息,如国家和地区,则需要先申请scope,再设置请求参数。
+        AccountAuthParams accountAuthParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
+                .setEmail()
+                .createParams();
+        try {
+            accountAuthService = AccountAuthManager.getService(accountAuthParams);
+        } catch (ApiException e) {
+            // 处理初始化登录授权服务失败,status code标识了失败的原因,请参考API中的错误码参考了解详细错误原因
+            e.getStatusCode();
+            Toast.error(getContext(),"Init Huawei accountAuthService FAILED.");
+            return;
+        }
+        Toast.info(getContext(),"Init Huawei accountAuthService SUCCESS");
+
+        if (accountAuthService == null) {
+            Toast.error(getContext(),"获取不到账号信息");
+            return;
+        }
+        // 调用静默登录接口。
+        // 如果华为系统帐号已经登录,并且已经授权,会登录成功;
+        // 否则静默登录失败,需要在失败监听中,显式地调用前台登录授权接口,完成登录授权。
+        Task<AuthAccount> taskSilentSignIn = accountAuthService.silentSignIn();
+//        Task<AuthAccount> taskSilentSignIn = accountAuthService.silentSignIn();
+        Toast.info(getContext(),"SilentSign START.");
+        // 添加静默登录成功处理监听
+        taskSilentSignIn.addOnSuccessListener(authAccount -> updateUI(authAccount));
+        // 添加静默登录失败监听
+        taskSilentSignIn.addOnFailureListener(e -> {
+            if (e instanceof ApiException) {
+                ApiException apiException = (ApiException) e;
+                Toast.error(getContext(),"SilentSignIn FAILED, status code: " + apiException.getStatusCode() + ". Need to foreground sign in" + "\r\n" + apiException.getStatusMessage()
+                        + "\r\n" + apiException.getMessage() + "\r\n" + apiException.getCause());
+
+                // 静默登录失败,显式地调用前台登录授权接口,完成登录授权。
+                Task<AuthAccount> taskSignIn = accountAuthService.signIn();
+                Toast.info(getContext(),"SignIn foreground START.");
+                if (taskSignIn == null) {
+                    Toast.info(getContext(),"SignIn foreground task is null.");
+                    return;
+                }
+                taskSignIn.addOnSuccessListener(new OnSuccessListener<AuthAccount>() {
+                    @Override
+                    public void onSuccess(AuthAccount result) {
+                        Toast.info(getContext(),"SignIn foreground SUCCESS.");
+                        updateUI(result);
+                    }
+                });
+                taskSignIn.addOnFailureListener(new OnFailureListener() {
+                    @Override
+                    public void onFailure(Exception e) {
+                        Toast.info(getContext(),"SignIn foreground FAILED.");
+                        if (e instanceof ApiException) {
+                            ApiException apiException = (ApiException) e;
+                            // 登录失败,status code标识了失败的原因,请参考API中的错误码参考了解详细错误原因
+                            apiException.getStatusCode();
+                            Toast.info(getContext(),"SignIn foreground FAILED. status code: "
+                                    + apiException.getStatusCode()
+                                    + ".");
+                            if (CommonConstant.RETCODE.SIGN_IN_CANCELLED == apiException.getStatusCode()) {
+                                Toast.info(getContext(),"Error message: User click CANCEL or Return, user cancel login in.");
+                            }
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    private void updateUI(AuthAccount authAccount) {
+        Toast.info(getContext(),authAccount.getOpenId() + " : " + authAccount.getUnionId());
+    }
+
+
     /**
      * 设置全屏显示
      */
@@ -124,7 +247,7 @@ public class MainAbilitySlice extends AbilitySlice {
                 window.setLayoutConfig(layoutConfig);
             }
         } catch (Exception e) {
-            HiLog.error(TAG, "设置全屏失败: " + e.getMessage());
+            Log.error("设置全屏失败: " + e.getMessage());
         }
     }
 
@@ -167,7 +290,7 @@ public class MainAbilitySlice extends AbilitySlice {
                             pages.add(page);
                         }
                     } catch (Exception e) {
-                        HiLog.error(TAG, "创建页面失败: " + e.getMessage());
+                        Log.error("创建页面失败: " + e.getMessage());
                         e.printStackTrace();
                     }
                     return page;
@@ -198,7 +321,7 @@ public class MainAbilitySlice extends AbilitySlice {
                     // 页面切换完成
                     currentTab = index;
                     updateBottomNavState(index);
-                    HiLog.info(TAG, "切换到页面: " + index);
+                    Log.info("切换到页面: " + index);
                 }
 
                 @Override
@@ -248,7 +371,7 @@ public class MainAbilitySlice extends AbilitySlice {
         }
         if (navCurrentLocation != null) {
             navCurrentLocation.setClickedListener(component -> {
-                HiLog.info(TAG, "点击了当前位置按钮");
+                Log.info("点击了当前位置按钮");
                 locateCurrentPosition();
             });
         }
@@ -359,21 +482,24 @@ public class MainAbilitySlice extends AbilitySlice {
                     // Set Preference Maximum Zoom Level
                     .maxZoomPreference(13);
 
+            if (true) return;
+
             // Initialize MapView Object. - 完全按照 MarkerDemo
             mMapView = new MapView(this, huaweiMapOptions);
             mMapView.onCreate();
 
+
             // Obtains the HuaweiMap object. - 完全按照 MarkerDemo
             mMapView.getMapAsync(huaweiMap -> {
                 mHuaweiMap = huaweiMap;
 
                 // If mHuaweiMap is null, the program stops running. - 完全按照 MarkerDemo
                 if (null == mHuaweiMap) {
-                    HiLog.error(TAG, "mHuaweiMap 为 null");
+                    Log.error("mHuaweiMap 为 null");
                     return;
                 }
 
-                HiLog.info(TAG, "地图已就绪,开始获取定位");
+                Log.info("地图已就绪,开始获取定位");
 
                 mHuaweiMap.setOnMapClickListener(new OnMapClickListener() {
                     @Override
@@ -447,7 +573,7 @@ public class MainAbilitySlice extends AbilitySlice {
             // 加载MapView
             myLayout.addComponent(mMapView);
         } catch (Exception e) {
-            HiLog.error(TAG, "初始化地图失败: " + e.getMessage());
+            Log.error("初始化地图失败: " + e.getMessage());
             e.printStackTrace();
         }
     }
@@ -493,7 +619,7 @@ public class MainAbilitySlice extends AbilitySlice {
                     double latitude = location.getLatitude();
                     double longitude = location.getLongitude();
 
-                    HiLog.info(TAG, "定位成功: " + latitude + ", " + longitude);
+                    Log.info("定位成功: " + latitude + ", " + longitude);
 
                     // 将坐标传递给地图
                     updateMapWithLocation(location);
@@ -501,19 +627,19 @@ public class MainAbilitySlice extends AbilitySlice {
 
                 @Override
                 public void onStatusChanged(int type) {
-                    HiLog.info(TAG, "定位状态变化: " + type);
+                    Log.info("定位状态变化: " + type);
                 }
 
                 @Override
                 public void onErrorReport(int errorCode) {
-                    HiLog.error(TAG, "定位错误: " + errorCode);
+                    Log.error("定位错误: " + errorCode);
                     new ToastDialog(CommonContext.getContext())
                             .setText("定位失败,错误码: " + errorCode)
                             .show();
                 }
             };
         } catch (Exception e) {
-            HiLog.error(TAG, "初始化定位服务失败: " + e.getMessage());
+            Log.error("初始化定位服务失败: " + e.getMessage());
         }
     }
 
@@ -522,7 +648,7 @@ public class MainAbilitySlice extends AbilitySlice {
      */
     private void locateCurrentPosition() {
         if (locator == null || locatorCallback == null) {
-            HiLog.error(TAG, "定位服务未初始化");
+            Log.error("定位服务未初始化");
             return;
         }
 
@@ -530,9 +656,9 @@ public class MainAbilitySlice extends AbilitySlice {
             // 请求定位
             RequestParam requestParam = new RequestParam(RequestParam.PRIORITY_ACCURACY, 0, 0);
             locator.startLocating(requestParam, locatorCallback);
-            HiLog.info(TAG, "开始定位...");
+            Log.info("开始定位...");
         } catch (Exception e) {
-            HiLog.error(TAG, "定位失败: " + e.getMessage());
+            Log.error("定位失败: " + e.getMessage());
         }
     }
 
@@ -541,7 +667,7 @@ public class MainAbilitySlice extends AbilitySlice {
      */
     private void updateMapWithLocation(Location location) {
         if (mHuaweiMap == null) {
-            HiLog.warn(TAG, "地图未初始化完成,等待地图就绪");
+            Log.warn("地图未初始化完成,等待地图就绪");
             return;
         }
 
@@ -549,7 +675,7 @@ public class MainAbilitySlice extends AbilitySlice {
             double latitude = location.getLatitude();
             double longitude = location.getLongitude();
 
-            HiLog.info(TAG, "更新地图位置: " + latitude + ", " + longitude);
+            Log.info("更新地图位置: " + latitude + ", " + longitude);
 
             // 创建坐标点
             LatLng latLng = new LatLng(latitude, longitude);
@@ -574,7 +700,7 @@ public class MainAbilitySlice extends AbilitySlice {
             // move camera - 完全按照示例代码
             mHuaweiMap.moveCamera(cameraUpdate);
 
-            HiLog.info(TAG, "地图已更新到当前位置");
+            Log.info("地图已更新到当前位置");
 
             // 显示提示
             new ToastDialog(CommonContext.getContext())
@@ -582,7 +708,7 @@ public class MainAbilitySlice extends AbilitySlice {
                     .show();
 
         } catch (Exception e) {
-            HiLog.error(TAG, "更新地图位置失败: " + e.getMessage());
+            Log.error("更新地图位置失败: " + e.getMessage());
             e.printStackTrace();
         }
     }
@@ -635,12 +761,17 @@ public class MainAbilitySlice extends AbilitySlice {
             try {
                 locator.stopLocating(locatorCallback);
             } catch (Exception e) {
-                HiLog.error(TAG, "停止定位失败: " + e.getMessage());
+                Log.error("停止定位失败: " + e.getMessage());
             }
         }
         // 销毁地图 - 完全按照示例代码
         if (mMapView != null) {
             mMapView.onDestroy();
         }
+
+        if (dataAbilityHelper != null) {
+
+        }
+        dataAbilityHelper.unregisterObserver(SystemSettings.getUri(SystemSettings.Date.TIME_FORMAT), dataAbilityObserver);
     }
 }

+ 1 - 6
entry/src/main/java/com/fujica/abk/slice/MapViewDemoSlice.java

@@ -40,12 +40,7 @@ public class MapViewDemoSlice extends AbilitySlice {
             @Override
             public void onMapReady(HuaweiMap huaweiMap) {
                 HuaweiMap mHuaweiMap = huaweiMap;
-                mHuaweiMap.setOnMapClickListener(new  OnMapClickListener() {
-                    @Override
-                    public void onMapClick(LatLng latLng) {
-                        new ToastDialog(CommonContext.getContext()).setText("onMapClick ").show();
-                    }
-                });
+                mHuaweiMap.setOnMapClickListener(latLng -> new ToastDialog(CommonContext.getContext()).setText("onMapClick ").show());
             }
         });
 

+ 56 - 0
entry/src/main/java/com/fujica/abk/utils/ApiOption.java

@@ -0,0 +1,56 @@
+package com.fujica.abk.utils;
+
+/**
+ * API请求选项
+ */
+public class ApiOption {
+    private String url;
+    private Object data;
+    private Boolean toast; // 错误提示,默认不传值提示
+    private Boolean hideLoading;
+
+    public ApiOption() {
+    }
+
+    public ApiOption(String url) {
+        this.url = url;
+    }
+
+    public ApiOption(String url, Object data) {
+        this.url = url;
+        this.data = data;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public Boolean getToast() {
+        return toast;
+    }
+
+    public void setToast(Boolean toast) {
+        this.toast = toast;
+    }
+
+    public Boolean getHideLoading() {
+        return hideLoading;
+    }
+
+    public void setHideLoading(Boolean hideLoading) {
+        this.hideLoading = hideLoading;
+    }
+}
+

+ 35 - 0
entry/src/main/java/com/fujica/abk/utils/Log.java

@@ -0,0 +1,35 @@
+package com.fujica.abk.utils;
+
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+
+
+public class Log {
+    private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, "fspark log");
+
+    public static void error(String message) {
+        HiLog.error(TAG, message);
+    }
+    public static void info(String message) {
+        HiLog.info(TAG, message);
+    }
+
+    public static void warn(String message) {
+        HiLog.warn(TAG, message);
+    }
+//    public static error(message: string | ESObject): void {
+//    const msg: string = (message && typeof (message) == 'object') ? JSON.stringify(message) : (message || '').toString()
+//        console.error(`fspark log:${msg}`);
+//    }
+//
+//    public static info(message: string | ESObject): void {
+//    const msg: string = (message && typeof (message) == 'object') ? JSON.stringify(message) : (message || '').toString()
+//        console.info(`fspark log:${msg}`);
+//    }
+//
+//    public static debug(message: string | ESObject): void {
+//    const msg: string = (message && typeof (message) == 'object') ? JSON.stringify(message) : (message || '').toString()
+//        console.debug(`fspark log:${msg}`);
+//    }
+}
+

+ 62 - 0
entry/src/main/java/com/fujica/abk/utils/R.java

@@ -0,0 +1,62 @@
+package com.fujica.abk.utils;
+
+/**
+ * HTTP响应封装类
+ * @param <T> 响应数据类型
+ */
+public class R<T> {
+    private boolean success;
+    private String msg;
+    private int code;
+    private T data;
+
+    public R() {
+    }
+
+    public R(String msg) {
+        this.success = false;
+        this.msg = msg;
+        this.code = -1;
+    }
+
+    public R(boolean success, String msg, int code, T data) {
+        this.success = success;
+        this.msg = msg;
+        this.code = code;
+        this.data = data;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+}
+

+ 0 - 4
entry/src/main/java/com/fujica/abk/utils/ScreenUtil.java

@@ -1,7 +1,3 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2008-2021. All rights reserved.
- */
-
 package com.fujica.abk.utils;
 
 import ohos.agp.window.service.DisplayManager;

+ 39 - 0
entry/src/main/java/com/fujica/abk/utils/Toast.java

@@ -0,0 +1,39 @@
+package com.fujica.abk.utils;
+
+import ohos.agp.window.dialog.ToastDialog;
+import ohos.app.Context;
+import ohos.eventhandler.EventHandler;
+import ohos.eventhandler.EventRunner;
+
+public class Toast {
+    /**
+     * 在主线程显示 Toast
+     */
+    private static void showOnMainThread(Context context, String message) {
+        if (context == null) {
+            return;
+        }
+        // 获取主线程的 EventRunner
+        EventRunner mainRunner = EventRunner.getMainEventRunner();
+        if (mainRunner == null) {
+            // 如果获取不到主线程,直接在当前线程显示(可能已经是主线程)
+            new ToastDialog(context).setText(message).show();
+            return;
+        }
+        
+        // 创建主线程的 EventHandler
+        EventHandler mainHandler = new EventHandler(mainRunner);
+        mainHandler.postTask(() -> {
+            new ToastDialog(context).setText(message).show();
+        });
+    }
+    
+    public static void info(Context context, String message) {
+        showOnMainThread(context, message);
+    }
+    
+    public static void error(Context context, String message) {
+        showOnMainThread(context, message);
+    }
+}
+

+ 368 - 0
entry/src/main/java/com/fujica/abk/utils/api.java

@@ -0,0 +1,368 @@
+package com.fujica.abk.utils;
+
+import com.fujica.abk.api.cache;
+import com.fujica.abk.common.EventBus;
+import ohos.app.Context;
+import ohos.utils.zson.ZSONObject;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * HTTP请求工具类
+ * HarmonyOS Java API7 版本
+ */
+public class api {
+    // 后端gateway连接
+    // private static String host = "http://192.168.12.139:10004/mobile";   //中台服务
+    // private static String host = "http://192.168.12.139:10001/transfer/mobile";  //本机网关
+//    private static String host = "http://192.168.12.139:10004/mobile";  // 本机中转
+
+     private static String host = "https://gatewayservicev2dev.fujica.com.cn/transfer/mobile"; //UAT环境
+    // private static String host = "https://gatewayservicev2test.fujica.com.cn/transfer/mobile"; //PRE环境
+
+    // 前端nginx连接
+//     private static String host = "https://fsabk.fujica.com.cn/api"; //正式环境
+    // private static String host = "https://pre-fsh5.fujica.com.cn"; //测试环境
+
+    /**
+     * 合并URL
+     */
+    private static String mergeUrl(String url, String method, Object data) {
+        if ("GET".equals(method) && data != null && data instanceof Map) {
+            @SuppressWarnings("unchecked")
+            Map<String, Object> params = (Map<String, Object>) data;
+            StringBuilder paramStr = new StringBuilder();
+            for (Map.Entry<String, Object> entry : params.entrySet()) {
+                if (paramStr.length() > 0) {
+                    paramStr.append("&");
+                }
+                try {
+                    paramStr.append(entry.getKey())
+                            .append("=")
+                            .append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
+                } catch (Exception e) {
+                    paramStr.append(entry.getKey())
+                            .append("=")
+                            .append(entry.getValue());
+                }
+            }
+            if (paramStr.length() > 0) {
+                url = url.indexOf("?") > 0 ? url + "&" + paramStr : url + "?" + paramStr;
+            }
+        }
+        return url.startsWith("http") ? url : host + url;
+    }
+
+    /**
+     * 延迟方法
+     */
+    public static CompletableFuture<Void> sleep() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                Thread.sleep(1500);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        });
+    }
+
+    /**
+     * 将对象转换为JSON字符串
+     */
+    private static String objectToJson(Object data) {
+        if (data instanceof String) {
+            return (String) data;
+        } else if (data instanceof Map) {
+            ZSONObject jsonObj = new ZSONObject((Map<String, Object>) data);
+            return ZSONObject.toZSONString(jsonObj);
+        } else {
+            // 对于其他对象,尝试使用反射或直接toString
+            // 这里简化处理,实际项目中可能需要更复杂的序列化
+            return data != null ? data.toString() : "{}";
+        }
+    }
+
+    /**
+     * 从JSON字符串解析为R对象
+     */
+    @SuppressWarnings("unchecked")
+    private static <T> R<T> parseResponse(String jsonStr) {
+        try {
+            ZSONObject jsonObj = ZSONObject.stringToZSON(jsonStr);
+            R<T> result = new R<>();
+            if (jsonObj.containsKey("success")) {
+                result.setSuccess(jsonObj.getBooleanValue("success"));
+            }
+            if (jsonObj.containsKey("msg")) {
+                result.setMsg(jsonObj.getString("msg"));
+            }
+            if (jsonObj.containsKey("code")) {
+                result.setCode(jsonObj.getIntValue("code"));
+            }
+            if (jsonObj.containsKey("data")) {
+                // data字段可能是任意类型,这里直接设置为Object
+                // 如果需要特定类型,调用方需要自己转换
+                result.setData((T) jsonObj.get("data"));
+            }
+            
+            return result;
+        } catch (Exception e) {
+            Log.error("JSON解析失败: " + e.getMessage());
+            return new R<>("JSON解析失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * HTTP请求核心方法
+     */
+    public static <T> CompletableFuture<R<T>> http(Context context, String url, String method,
+                                                   Object data, Boolean failToast, Boolean hideLoading) {
+        Log.error("请求:" + url);
+        if (failToast == null) {
+            failToast = true;
+        }
+        
+        url = mergeUrl(url, method, data);
+        Log.info("请求" + url);
+        String token = cache.getToken(context);
+        final String _url = url;
+        final Boolean _failToast = failToast;
+        return CompletableFuture.supplyAsync(() -> {
+            HttpURLConnection connection = null;
+            try {
+                URL requestUrl = new URL(_url);
+                connection = (HttpURLConnection) requestUrl.openConnection();
+                
+                // 设置请求方法
+                connection.setRequestMethod(method);
+                
+                // 设置请求头
+                connection.setRequestProperty("Accept", "application/json");
+                connection.setRequestProperty("Content-Type", "application/json");
+                connection.setRequestProperty("token", token);
+                
+                // 设置超时
+                connection.setConnectTimeout(10000);
+                connection.setReadTimeout(60000);
+                
+                // 设置请求体(非GET请求)
+                if (!"GET".equals(method) && data != null) {
+                    connection.setDoOutput(true);
+                    String jsonData = objectToJson(data);
+                    OutputStream os = connection.getOutputStream();
+                    os.write(jsonData.getBytes("UTF-8"));
+                    os.flush();
+                    os.close();
+                }
+                
+                // 执行请求
+                int responseCode = connection.getResponseCode();
+                
+                try {
+                    if (responseCode == 401) {
+                        Toast.error(context,"登录过期,请重试");
+                        cache.logout(context);
+                        EventBus.getInstance().emit("onAuthChanged");
+                        return new R<>("登录过期,请重试");
+                    } else if (responseCode != 200) {
+                        String msg = "操作失败:" + responseCode;
+                        Toast.error(context, msg);
+                        Log.info("响应:" + responseCode);
+                        return new R<>(msg);
+                    } else {
+                        // 读取响应
+                        InputStream inputStream = connection.getInputStream();
+                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+                        StringBuilder response = new StringBuilder();
+                        String line;
+                        while ((line = reader.readLine()) != null) {
+                            response.append(line);
+                        }
+                        reader.close();
+                        inputStream.close();
+                        
+                        String resultStr = response.toString();
+                        Log.error("响应:" + resultStr);
+                        R<T> result = parseResponse(resultStr);
+                        
+                        if (result != null && !result.isSuccess() && _failToast) {
+                            String errorMsg = result.getMsg() != null ? result.getMsg() : "操作失败" + result.getCode();
+                            Toast.error(context,errorMsg);
+                        }
+                        Log.info("响应:" + resultStr);
+                        return result != null ? result : new R<>("解析响应失败");
+                    }
+                } catch (Exception e) {
+                    String msg = "操作失败" + e.getMessage();
+                    Toast.error(context,msg);
+                    Log.error("响应解析错误: " + e.getMessage());
+                    return new R<>(msg);
+                }
+            } catch (IOException e) {
+                String msg = (e.getMessage() != null && (e.getMessage().contains("2300006") || e.getMessage().contains("2300007"))) 
+                        ? "网络连接失败" : e.getMessage() + ":" + e.getClass().getSimpleName();
+                Toast.error(context,msg);
+                Log.error("请求错误: " + e.getMessage());
+                return new R<>(msg);
+            } catch (Exception e) {
+                String msg = "操作失败" + e.getMessage();
+                Toast.error(context,msg);
+                Log.error("请求异常: " + e.getMessage());
+                return new R<>(msg);
+            } finally {
+                if (connection != null) {
+                    connection.disconnect();
+                }
+            }
+        });
+    }
+
+    /**
+     * DELETE请求
+     */
+    public static <T> CompletableFuture<R<T>> del(Context context, String url, Object data) {
+        return http(context, url, "DELETE", data, null, null);
+    }
+
+    /**
+     * POST请求
+     */
+    public static <T> CompletableFuture<R<T>> post(Context context, String url, Object data) {
+        return http(context, url, "POST", data, null, null);
+    }
+
+    /**
+     * POST请求(带选项)
+     */
+    public static <T> CompletableFuture<R<T>> post1(Context context, ApiOption option) {
+        return http(context, option.getUrl(), "POST", option.getData(), option.getToast(), option.getHideLoading());
+    }
+
+    /**
+     * GET请求(带选项)
+     */
+    public static <T> CompletableFuture<R<T>> get1(Context context, ApiOption option) {
+        return http(context,option.getUrl(), "GET", option.getData(), option.getToast(), option.getHideLoading());
+    }
+
+
+    /**
+     * PUT请求(带选项)
+     */
+    public static <T> CompletableFuture<R<T>> put1(Context context, ApiOption option) {
+        return http(context, option.getUrl(), "PUT", option.getData(), option.getToast(), option.getHideLoading());
+    }
+
+    /**
+     * 文件上传
+     */
+    public static <T> CompletableFuture<R<T>> upload(Context context, String url, String imageUri) {
+        url = url.startsWith("http") ? url : host + url;
+        Log.info("请求" + url);
+        String token = cache.getToken(context);
+
+        String finalUrl = url;
+        return CompletableFuture.supplyAsync(() -> {
+            HttpURLConnection connection = null;
+            try {
+                URL requestUrl = new URL(finalUrl);
+                connection = (HttpURLConnection) requestUrl.openConnection();
+                
+                // 设置请求方法
+                connection.setRequestMethod("POST");
+                
+                // 设置请求头
+                String boundary = "----WebKitFormBoundary" + System.currentTimeMillis();
+                connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
+                connection.setRequestProperty("Connection", "keep-alive");
+                connection.setRequestProperty("token", token);
+                connection.setDoOutput(true);
+                
+                // 构建multipart/form-data请求体
+                OutputStream os = connection.getOutputStream();
+                java.io.File file = new java.io.File(imageUri);
+                if (file.exists()) {
+                    // 写入文件部分
+                    os.write(("--" + boundary + "\r\n").getBytes("UTF-8"));
+                    os.write(("Content-Disposition: form-data; name=\"file\"; filename=\"file.jpg\"\r\n").getBytes("UTF-8"));
+                    os.write(("Content-Type: image/jpg\r\n\r\n").getBytes("UTF-8"));
+                    
+                    // 读取并写入文件内容
+                    java.io.FileInputStream fis = new java.io.FileInputStream(file);
+                    byte[] buffer = new byte[8192];
+                    int bytesRead;
+                    while ((bytesRead = fis.read(buffer)) != -1) {
+                        os.write(buffer, 0, bytesRead);
+                    }
+                    fis.close();
+                    
+                    // 结束multipart
+                    os.write(("\r\n--" + boundary + "--\r\n").getBytes("UTF-8"));
+                }
+                os.flush();
+                os.close();
+                
+                // 执行请求
+                int responseCode = connection.getResponseCode();
+                
+                try {
+                    if (responseCode != 200) {
+                        String msg = "操作失败:" + responseCode;
+                        Toast.error(context,msg);
+                        Log.info("响应:" + responseCode);
+                        return new R<>(msg);
+                    } else {
+                        // 读取响应
+                        InputStream inputStream = connection.getInputStream();
+                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+                        StringBuilder response = new StringBuilder();
+                        String line;
+                        while ((line = reader.readLine()) != null) {
+                            response.append(line);
+                        }
+                        reader.close();
+                        inputStream.close();
+                        
+                        String resultStr = response.toString();
+                        R<T> result = parseResponse(resultStr);
+                        
+                        if (result != null && !result.isSuccess()) {
+                            String errorMsg = result.getMsg() != null ? result.getMsg() : "操作失败" + result.getCode();
+                            Toast.error(context,errorMsg);
+                        }
+                        Log.info("响应:" + resultStr);
+                        return result != null ? result : new R<>("解析响应失败");
+                    }
+                } catch (Exception e) {
+                    String msg = "操作失败" + e.getMessage();
+                    Toast.error(context,msg);
+                    Log.error("响应解析错误: " + e.getMessage());
+                    return new R<>(msg);
+                }
+            } catch (IOException e) {
+                String msg = e.getMessage() + ":" + e.getClass().getSimpleName();
+                Toast.error(context,msg);
+                Log.error("上传错误: " + e.getMessage());
+                return new R<>(msg);
+            } catch (Exception e) {
+                String msg = "操作失败" + e.getMessage();
+                Toast.error(context,msg);
+                Log.error("上传异常: " + e.getMessage());
+                return new R<>(msg);
+            } finally {
+                if (connection != null) {
+                    connection.disconnect();
+                }
+            }
+        });
+    }
+}

+ 2 - 2
entry/src/main/js/widget/i18n/zh-CN.json

@@ -1,6 +1,6 @@
 {
   "strings": {
-    "title": "今日美食推荐",
-    "detail": "一碗香喷喷的炸酱面,回到儿时的青涩回忆"
+    "title": "爱泊客",
+    "detail": "富士只能大厦停车场"
   }
 }

+ 1 - 1
entry/src/main/js/widget/pages/index/index.hml

@@ -5,7 +5,7 @@
         </div>
         <div class="container-inner">
             <text class="title">{{ $t('strings.title') }}</text>
-            <text class="detail_text">{{ $t('strings.detail') }}</text>
+            <text class="detail_text"> {{ $t('strings.detail') }}</text>
         </div>
     </stack>
 </div>

+ 11 - 0
entry/src/main/js/widget/pages/index/index1.hml

@@ -0,0 +1,11 @@
+<div class="container">
+    <stack>
+        <div class="container-img">
+            <image src="/common/ic_default_image@3x.png" class="bg-img" onclick="routerEvent"></image>
+        </div>
+        <div class="container-inner">
+            <text class="title">{{ $t('strings.title') }}</text>
+            <text class="detail_text"> {{ $t('strings.detail') }}</text>
+        </div>
+    </stack>
+</div>

+ 1 - 1
entry/src/main/resources/base/element/string.json

@@ -2,7 +2,7 @@
   "string": [
     {
       "name": "entry_MainAbility",
-      "value": "entry_MainAbility"
+      "value": "爱泊客"
     },
     {
       "name": "mainability_description",

+ 2 - 0
entry/src/main/resources/base/layout/ability_main.xml

@@ -220,6 +220,8 @@
                 </DirectionalLayout>
             </DirectionalLayout>
         </DirectionalLayout>
+
+        <Button ohos:width="match_parent" ohos:height="60vp" ohos:id="$+id:btn_hwid_sign_in" ohos:text="华为账号登录" ohos:layout_alignment="right|horizontal_center"  ></Button>
     </DirectionalLayout>
 
 </StackLayout>

+ 1 - 1
entry/src/main/resources/en_US/element/string.json

@@ -2,7 +2,7 @@
   "string": [
     {
       "name": "entry_MainAbility",
-      "value": "entry_MainAbility"
+      "value": "爱泊客"
     },
     {
       "name": "mainability_description",

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
entry/src/main/resources/rawfile/agconnect-services.json


+ 1 - 1
entry/src/main/resources/zh_CN/element/string.json

@@ -2,7 +2,7 @@
   "string": [
     {
       "name": "entry_MainAbility",
-      "value": "entry_MainAbility"
+      "value": "爱泊客"
     },
     {
       "name": "mainability_description",