Java의 내비게이션 구성 요소를 사용하여 Android KnowMyBoard 앱에 Huawei Map Kit 및 Location Kit 통합


소개
이 기사에서는 Huawei ML 키트, 지도 키트 및 위치 키트를 Android 애플리케이션 KnowMyBoard에 통합하는 방법을 알아봅니다. Account Kit는 대규모 사용자 기반의 앱에 원활한 로그인 기능을 제공합니다.

Android용 위치 키트 SDK는 Android 앱용 위치 관련 API를 제공합니다. 이러한 API는 주로 융합 위치, 활동 식별, 지오펜스, 고정밀 위치, 실내 위치 및 지오코딩과 같은 6가지 기능과 관련됩니다. 이 모드는 휴대폰 및 Huawei 태블릿에 적용됩니다. 우리는 사용자의 위치를 ​​얻기 위해 위치 키트를 사용하고 있습니다.

Android용 Huawei Map SDK는 지도를 개발하기 위해 호출할 수 있는 일련의 API입니다. 이 SDK를 사용하여 지도 표시, 지도 상호 작용, 지도 그리기 및 지도 스타일 사용자 지정을 포함하여 지도 관련 기능을 Android 앱에 쉽게 추가할 수 있습니다.

지원되는 장치

지원되는 국가/지역

지원되는 국가/지역

개발 개요

Android Studio IDE를 설치해야 하며 Android 애플리케이션 개발에 대한 사전 지식이 있다고 가정합니다.

하드웨어 요구 사항
  • Windows 10을 실행하는 컴퓨터(데스크탑 또는 랩탑).
  • 디버깅에 사용되는 Android 휴대폰(USB 케이블 포함).

  • 소프트웨어 요구 사항
  • 자바 JDK 1.8 이상.
  • Android Studio 소프트웨어 또는 Visual Studio 또는 Code가 설치되었습니다.
  • HMS 코어(APK) 4.X 이상

  • 통합 단계
    1단계. Huawei 개발자 계정 및 Huawei 개발자 웹사이트에서 신원 확인 완료, 등록Huawei ID. 참조
    2단계. Create project in AppGallery Connect

    3단계. Adding HMS Core SDK

    코딩을 시작하자

    MainActivity.java

     public class MainActivity extends AppCompatActivity {
    
        LoginViewModel loginViewModel;
        private MLTextAnalyzer mTextAnalyzer;
        public Uri imagePath;
        Bitmap bitmap;
        static String TAG = "TAG";
        ArrayList<String> result = new ArrayList<>();
        MLLocalLangDetector myLocalLangDetector;
        MLLocalTranslator myLocalTranslator;
        String textRecognized;
        ProgressDialog progressDialog;
        NavController navController;
        ActivityMainBinding activityMainBinding;
        BottomNavigationView bottomNavigationView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            activityMainBinding = DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
            loginViewModel = new ViewModelProvider(MainActivity.this).get(LoginViewModel.class);
    
            navController = Navigation.findNavController(MainActivity.this, R.id.nav_host_fragment);
            MyApplication.setActivity(this);
            progressDialog = new ProgressDialog(this);
            progressDialog.setCancelable(false);
            bottomNavigationView = activityMainBinding.bottomNavigation;
            NavigationUI.setupWithNavController(bottomNavigationView, navController);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            // Process the authorization result to obtain the authorization code from AuthAccount.
            super.onActivityResult(requestCode, resultCode, data);
    
            if (requestCode == 8888) {
    
                Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
                if (authAccountTask.isSuccessful()) {
                    // The sign-in is successful, and the user's ID information and authorization code are obtained.
                    AuthAccount authAccount = authAccountTask.getResult();
                    UserData userData = new UserData();
                    userData.setAccessToken(authAccount.getAccessToken());
                    userData.setCountryCode(authAccount.getCountryCode());
                    userData.setDisplayName(authAccount.getDisplayName());
                    userData.setEmail(authAccount.getEmail());
                    userData.setFamilyName(authAccount.getFamilyName());
                    userData.setGivenName(authAccount.getGivenName());
                    userData.setIdToken(authAccount.getIdToken());
                    userData.setOpenId(authAccount.getOpenId());
                    userData.setUid(authAccount.getUid());
                    userData.setPhotoUriString(authAccount.getAvatarUri().toString());
                    userData.setUnionId(authAccount.getUnionId());
                    Gson gson = new Gson();
                    Log.e("TAG", "sign in success : " + gson.toJson(authAccount));
                    loginViewModel = new ViewModelProvider(MainActivity.this).get(LoginViewModel.class);
                    loginViewModel.sendData(authAccount.getDisplayName());
    
                } else {
                    // The sign-in failed.
                    Log.e("TAG", "sign in failed:" + ((ApiException) authAccountTask.getException()).getStatusCode());
    
                }
            }
            if (requestCode == 2323 && resultCode == RESULT_OK && data != null) {
                progressDialog.setMessage("Initializing text detection..");
                progressDialog.show();
                imagePath = data.getData();
                try {
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imagePath);
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e("TAG", " BITMAP ERROR");
                }
                Log.d("TAG", "Path " + imagePath.getPath());
                try {
                    Bitmap selectedBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imagePath);
                    asyncAnalyzeText(selectedBitmap);
                } catch (IOException e) {
                    e.printStackTrace();
                    progressDialog.dismiss();
                }
            }
        }
    
        private void asyncAnalyzeText(Bitmap bitmap) {
    
            if (mTextAnalyzer == null) {
                createMLTextAnalyzer();
            }
    
            MLFrame frame = MLFrame.fromBitmap(bitmap);
    
            Task<MLText> task = mTextAnalyzer.asyncAnalyseFrame(frame);
            task.addOnSuccessListener(new OnSuccessListener<MLText>() {
                @Override
                public void onSuccess(MLText text) {
                    progressDialog.setMessage("Initializing language detection..");
                    Log.d("TAG", "#==>" + text.getStringValue());
                    textRecognized = text.getStringValue().trim();
                    if(!textRecognized.isEmpty()){
                        // Create a local language detector.
                        MLLangDetectorFactory factory = MLLangDetectorFactory.getInstance();
                        MLLocalLangDetectorSetting setting = new MLLocalLangDetectorSetting.Factory()
                                // Set the minimum confidence threshold for language detection.
                                .setTrustedThreshold(0.01f)
                                .create();
                        myLocalLangDetector = factory.getLocalLangDetector(setting);
                        Task<String> firstBestDetectTask = myLocalLangDetector.firstBestDetect(textRecognized);
                        firstBestDetectTask.addOnSuccessListener(new OnSuccessListener<String>() {
                            @Override
                            public void onSuccess(String languageDetected) {
                                progressDialog.setMessage("Initializing text translation..");
                                // Processing logic for detection success.
                                Log.d("TAG", "Lang detect :" + languageDetected);
                                textTranslate(languageDetected, textRecognized, bitmap);
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(Exception e) {
                                // Processing logic for detection failure.
                                Log.e("TAG", "Lang detect error:" + e.getMessage());
                            }
                        });
                    }else{
                        progressDialog.dismiss();
                        showErrorDialog("Failed to recognize text.");
    
                    }
    
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(Exception e) {
                    Log.e("TAG", "#==>" + e.getMessage());
                }
            });
        }
    
        private void showErrorDialog(String msg) {
            AlertDialog alertDialog = new AlertDialog.Builder(this).create();
            alertDialog.setTitle("Error");
            alertDialog.setMessage(msg);
    
            alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
    
            alertDialog.show();
        }
    
        private void textTranslate(String languageDetected, String textRecognized, Bitmap uri) {
            MLApplication.initialize(getApplication());
            MLApplication.getInstance().setApiKey("$54fDAEDAF4 C9qhwQ==");
    
            // Create an offline translator.
            MLLocalTranslateSetting setting = new MLLocalTranslateSetting.Factory()
                    // Set the source language code. The ISO 639-1 standard is used. This parameter is mandatory. If this parameter is not set, an error may occur.
                    .setSourceLangCode(languageDetected)
                    // Set the target language code. The ISO 639-1 standard is used. This parameter is mandatory. If this parameter is not set, an error may occur.
                    .setTargetLangCode("en")
                    .create();
    
             myLocalTranslator = MLTranslatorFactory.getInstance().getLocalTranslator(setting);
            // Set the model download policy.
            MLModelDownloadStrategy downloadStrategy = new MLModelDownloadStrategy.Factory()
                    .needWifi()// It is recommended that you download the package in a Wi-Fi environment.
                    .create();
            // Create a download progress listener.
            MLModelDownloadListener modelDownloadListener = new MLModelDownloadListener() {
                @Override
                public void onProcess(long alreadyDownLength, long totalLength) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // Display the download progress or perform other operations.
                        }
                    });
                }
            };
    
            myLocalTranslator.preparedModel(downloadStrategy, modelDownloadListener).
                    addOnSuccessListener(new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void aVoid) {
                            // Called when the model package is successfully downloaded.
                            // input is a string of less than 5000 characters.
                            final Task<String> task = myLocalTranslator.asyncTranslate(textRecognized);
                            // Before translation, ensure that the models have been successfully downloaded.
                            task.addOnSuccessListener(new OnSuccessListener<String>() {
                                @Override
                                public void onSuccess(String translated) {
                                    // Processing logic for detection success.
                                    result.clear();
                                    result.add(languageDetected.trim());
                                    result.add(textRecognized.trim());
                                    result.add(translated.trim());
                                    loginViewModel.setImage(uri);
                                    loginViewModel.setTextRecongnized(result);
                                    progressDialog.dismiss();
                                }
                            }).addOnFailureListener(new OnFailureListener() {
                                @Override
                                public void onFailure(Exception e) {
                                    // Processing logic for detection failure.
                                    progressDialog.dismiss();
                                }
                            });
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(Exception e) {
                            // Called when the model package fails to be downloaded.
                            progressDialog.dismiss();
                        }
                    });
    
        }
    
        private void createMLTextAnalyzer() {
            MLLocalTextSetting setting = new MLLocalTextSetting.Factory()
                    .setOCRMode(MLLocalTextSetting.OCR_DETECT_MODE)
                    .create();
            mTextAnalyzer = MLAnalyzerFactory.getInstance().getLocalTextAnalyzer(setting);
    
        }
    
        @Override
        protected void onStop() {
            if (myLocalLangDetector != null) {
                myLocalLangDetector.stop();
            }
            if (myLocalTranslator!= null) {
                myLocalTranslator.stop();
            }
            if(progressDialog!= null){
                progressDialog.dismiss();
            }
            super.onStop();
        }
    }
    
    


    LoginViewModel.java

    public class LoginFragment extends Fragment implements OnMapReadyCallback{
    
        FragmentLoginBinding loginBinding;
        LoginViewModel loginViewModel;
        Menu menu;
        SharedPreferences prefs;
        SharedPreferences.Editor editor;
        NavController navController;
        private String MY_PREF_NAME = "my_pref_name";
        private String TAG = "TAG";
        private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
    
        RequestLocationData locationData;
        HuaweiMap hMap;
        public LoginFragment() {
            // Required empty public constructor
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            loginBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false);
            loginViewModel = new ViewModelProvider(getActivity()).get(LoginViewModel.class);
            loginBinding.setLoginViewModel(loginViewModel);
    
            locationData = new RequestLocationData(getContext(),getActivity(),loginViewModel);
            locationData.setLoginViewModel(loginViewModel);
            locationData.initFusionLocationProviderClint();
            locationData.checkPermission();
            locationData.checkDeviceLocationSettings();
    
           initMap(savedInstanceState);
            loginViewModel.getLocationResult().observeForever(new Observer<LocationResult>() {
                @Override
                public void onChanged(LocationResult locationResult) {
                   refreshLocation(locationResult);
                }
            });
    
            return loginBinding.getRoot();
        }
    
        private void initMap(Bundle savedInstanceState) {
    
            Bundle mapViewBundle = null;
            if (savedInstanceState != null) {
                mapViewBundle = savedInstanceState.getBundle("MapViewBundleKey");
            }
            loginBinding.mapview.onCreate(mapViewBundle);
            loginBinding.mapview.getMapAsync(this) ;
    
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setHasOptionsMenu(true);
            // Initialize the SDK.
            MapsInitializer.initialize(getContext());
    
        }
    
        @Override
        public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
            menu.clear();
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate(R.menu.main, menu);
            this.menu = menu;
            disableMenu(menu);
    
        }
    
        private void disableMenu(Menu menu) {
            try {
                if (menu != null) {
                    if (getPreferenceValue().equals("user_name")) {
                        menu.findItem(R.id.menu_login_logout).setVisible(false);
                        menu.findItem(R.id.menu_cancel_auth).setVisible(false);
                        menu.findItem(R.id.menu_login).setVisible(true);
                        getActivity().setTitle(getResources().getString(R.string.app_name));
                    } else {
                        menu.findItem(R.id.menu_login_logout).setVisible(true);
                        menu.findItem(R.id.menu_cancel_auth).setVisible(true);
                        menu.findItem(R.id.menu_login).setVisible(false);
                    }
    
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        private void enableMenu(Menu menu) {
            try {
                menu.findItem(R.id.menu_login_logout).setVisible(true);
                menu.findItem(R.id.menu_cancel_auth).setVisible(true);
                menu.findItem(R.id.menu_login).setVisible(false);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        @SuppressLint("NonConstantResourceId")
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.menu_cancel_auth:
                    setPreferenceValue("user_name");
                    loginViewModel.cancelAuthorization();
                    disableMenu(menu);
                    return true;
                case R.id.menu_login_logout:
    
                    setPreferenceValue("user_name");
                    loginViewModel.logoutHuaweiID();
                    disableMenu(menu);
                    return true;
                case R.id.menu_login:
                    loginViewModel.loginClicked();
                    return true;
                    case R.id.option_refresh_location:
                    locationData.refreshLocation();
    
                    return true;
    
                default:
                    break;
            }
            return super.onOptionsItemSelected(item);
        }
    
        public void updateMessage(String msg) {
            getActivity().setTitle(msg);
    
        }
    
        void setPreferenceValue(String userName) {
            editor = getActivity().getSharedPreferences(MY_PREF_NAME, MODE_PRIVATE).edit();
            editor.putString("user_name", userName);
            editor.apply();
        }
    
        String getPreferenceValue() {
            prefs = getActivity().getSharedPreferences(MY_PREF_NAME, MODE_PRIVATE);
            return prefs.getString("user_name", "user_name");
    
        }
    
        @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
        @Override
        public void onMapReady(HuaweiMap huaweiMap) {
            try{
                Log.d(TAG, "Map ready");
                hMap = huaweiMap;
                onHuaweiMapReady();
            }catch (Exception e){
                e.printStackTrace();
            }
    
        }
    
        private void onHuaweiMapReady() {
            if(hMap!=null){
                hMap.setMapType(MAP_TYPE_NORMAL);
                hMap.setBuildingsEnabled(true);
                // Enable the my-location layer.
                hMap.setMyLocationEnabled(true);
                // Enable the my-location icon.
                hMap.getUiSettings().setMyLocationButtonEnabled(true);
                hMap.getUiSettings().setGestureScaleByMapCenter(true);
            }
            if(locationData!=null){
               locationData.refreshLocation();
            }
    
        }
    
        private void refreshLocation(LocationResult locationResult) {
            try{
                Log.d(TAG, "Map updated with ");
                Log.d(TAG, "Latitude :"+locationResult.getLastLocation().getLongitude()+" Longitude :"+locationResult.getLastLocation().getLongitude());
                LatLng latLng1 = new LatLng(locationResult.getLastHWLocation().getLatitude(), locationResult.getLastHWLocation().getLongitude());
                float zoom = 10.0f;
                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng1,zoom);
                hMap.animateCamera(cameraUpdate);
    
            }catch (Exception e){
                e.printStackTrace();
                // onHuaweiMapReady();
            }
        }
        @Override
        public void onLowMemory() {
            super.onLowMemory();
            loginBinding.mapview.onLowMemory();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            loginBinding.mapview.onDestroy();
        }
    
        @Override
        public void onStop() {
            super.onStop();
            loginBinding.mapview.onStop();
            locationData.disableLocationData();
    
        }
    
        @Override
        public void onPause() {
            super.onPause();
            loginBinding.mapview.onPause();
        }
    
        @Override
        public void onStart() {
            super.onStart();
            loginBinding.mapview.onStart();
    
        }
    
        @Override
        public void onSaveInstanceState(@NonNull Bundle outState) {
            super.onSaveInstanceState(outState);
            Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
            if (mapViewBundle == null) {
                mapViewBundle = new Bundle();
                outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
            }
            loginBinding.mapview.onSaveInstanceState(mapViewBundle);
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            navController = Navigation.findNavController(view);
        }
    }
    
    


    RequestLocationData.java

    public class RequestLocationData {
        static String TAG = "TAG";
        SettingsClient settingsClient;
        private int isLocationSettingSuccess = 0;
        private LocationRequest myLocationRequest;
        // Define a fusedLocationProviderClient object.
        private FusedLocationProviderClient fusedLocationProviderClient;
        LocationCallback myLocationCallback;
        Context context;
        Activity activity;
        LocationResult locationResult;
        LoginViewModel loginViewModel;
        public RequestLocationData(Context context, FragmentActivity activity, LoginViewModel loginViewModel) {
            setContext(context);
            setActivity(activity);
            setLoginViewModel(loginViewModel);
        }
    
        public LoginViewModel getLoginViewModel() {
            return loginViewModel;
        }
    
        public void setLoginViewModel(LoginViewModel loginViewModel) {
            this.loginViewModel = loginViewModel;
        }
    
        public Context getContext() {
            return context;
        }
    
        public void setContext(Context context) {
            this.context = context;
        }
    
        public Activity getActivity() {
            return activity;
        }
    
        public void setActivity(Activity activity) {
            this.activity = activity;
        }
    
        public void initFusionLocationProviderClint(){
           // Instantiate the fusedLocationProviderClient object.
           fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());
           settingsClient = LocationServices.getSettingsClient(getActivity());
        }
        public void checkDeviceLocationSettings() {
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            myLocationRequest = new LocationRequest();
            builder.addLocationRequest(myLocationRequest);
            LocationSettingsRequest locationSettingsRequest = builder.build();
            // Check the device location settings.
            settingsClient.checkLocationSettings(locationSettingsRequest)
                    // Define the listener for success in calling the API for checking device location settings.
                    .addOnSuccessListener(locationSettingsResponse -> {
                        LocationSettingsStates locationSettingsStates =
                                locationSettingsResponse.getLocationSettingsStates();
                        StringBuilder stringBuilder = new StringBuilder();
                        // Check whether the location function is enabled.
                        stringBuilder.append(",\nisLocationUsable=")
                                .append(locationSettingsStates.isLocationUsable());
                        // Check whether HMS Core (APK) is available.
                        stringBuilder.append(",\nisHMSLocationUsable=")
                                .append(locationSettingsStates.isHMSLocationUsable());
                        Log.i(TAG, "checkLocationSetting onComplete:" + stringBuilder.toString());
                        // Set the location type.
                        myLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                        // Set the number of location updates to 1.
                        myLocationRequest.setNumUpdates(1);
                        isLocationSettingSuccess = 1;
    
    
                    })
                    // Define callback for failure in checking the device location settings.
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(Exception e) {
                            Log.i(TAG, "checkLocationSetting onFailure:" + e.getMessage());
                        }
                    });
    
        }
    
        public void checkPermission() {
            // Dynamically apply for required permissions if the API level is 28 or lower.
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                Log.i(TAG, "android sdk <= 28 Q");
                if (ActivityCompat.checkSelfPermission(getContext(),
                        Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                        && ActivityCompat.checkSelfPermission(getContext(),
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    String[] strings =
                            {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.MANAGE_MEDIA,Manifest.permission.MEDIA_CONTENT_CONTROL,Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
                    ActivityCompat.requestPermissions(getActivity(), strings, 1);
                }
            } else {
                // Dynamically apply for the android.permission.ACCESS_BACKGROUND_LOCATION permission in addition to the preceding permissions if the API level is higher than 28.
                if (ActivityCompat.checkSelfPermission(getActivity(),
                        Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                        && ActivityCompat.checkSelfPermission(getContext(),
                        Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                        && ActivityCompat.checkSelfPermission(getContext(),
                        "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
                    String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
                            android.Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.MEDIA_CONTENT_CONTROL,Manifest.permission.MANAGE_MEDIA,
                            "android.permission.ACCESS_BACKGROUND_LOCATION"};
                    ActivityCompat.requestPermissions(getActivity(), strings, 2);
                }
            }
        }
        public LocationResult refreshLocation() {
    
            if (isLocationSettingSuccess == 1) {
                myLocationCallback = new LocationCallback() {
                    @Override
                    public void onLocationResult(LocationResult locationResult) {
                        if (locationResult != null) {                 
                            getLoginViewModel().setLocationResult(locationResult);
                        }
                    }
                };
                fusedLocationProviderClient.requestLocationUpdates(myLocationRequest, myLocationCallback, Looper.getMainLooper());
    
            } else {
                Log.d(TAG, "Failed to get location settings");
            }
            return locationResult;
        }
    
        public void disableLocationData(){
            fusedLocationProviderClient.disableBackgroundLocation();
            fusedLocationProviderClient.removeLocationUpdates(myLocationCallback);
        }
    
    }
    
    


    navigation_graph.xml

     <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/navigation_graph"
        app:startDestination="@id/loginFragment">
        <fragment
            android:id="@+id/loginFragment"
            android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.LoginFragment"
            android:label="LoginFragment"/>
        <fragment
            android:id="@+id/mainFragment"
            android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.MainFragment"
            android:label="MainFragment"/>
        <fragment
            android:id="@+id/cameraFragment"
            android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.CameraFragment"
            android:label="fragment_camera"
            tools:layout="@layout/fragment_camera" />
    </navigation>
    
    


    *bottom_navigation_menu.xml *

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:id="@+id/loginFragment"
            android:icon="@android:drawable/ic_menu_agenda"
            android:title="Home" />
        <item
            android:id="@+id/mainFragment"
            app:showAsAction="always"
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="Gallery" />
        <item
            android:id="@+id/cameraFragment"
            android:icon="@android:drawable/ic_menu_camera"
            app:showAsAction="always"
            android:title="Camera" />
    </menu>
    
    


    LoginFragment.java

    public class LoginFragment extends Fragment implements OnMapReadyCallback{
    
    FragmentLoginBinding loginBinding;
    
    LoginViewModel loginViewModel;
    
    Menu menu;
    
    SharedPreferences prefs;
    
    SharedPreferences.Editor editor;
    
    NavController navController;
    
    private String MY_PREF_NAME = "my_pref_name";
    
    private String TAG = "TAG";
    
    private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
    
    RequestLocationData locationData;
    
    HuaweiMap hMap;
    
    public LoginFragment() {
    
    // Required empty public constructor
    
    }
    
    @Override
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    
    Bundle savedInstanceState) {
    
    loginBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container, false);
    
    loginViewModel = new ViewModelProvider(getActivity()).get(LoginViewModel.class);
    
    loginBinding.setLoginViewModel(loginViewModel);
    
    locationData = new RequestLocationData(getContext(),getActivity(),loginViewModel);
    
    locationData.setLoginViewModel(loginViewModel);
    
    locationData.initFusionLocationProviderClint();
    
    locationData.checkPermission();
    
    locationData.checkDeviceLocationSettings();
    
    initMap(savedInstanceState);
    
    loginViewModel.getMessage().observeForever(new Observer<String>() {
    
    @Override
    
    public void onChanged(String message) {
    
    updateMessage(message);
    
    if (!message.equals(getResources().getString(R.string.app_name))) {
    
    setPreferenceValue(message);
    
    enableMenu(menu);
    
    } else {
    
    disableMenu(menu);
    
    setPreferenceValue("user_name");
    
    }
    
    }
    
    });
    
    loginViewModel.getLocationResult().observeForever(new Observer<LocationResult>() {
    
    @Override
    
    public void onChanged(LocationResult locationResult) {
    
    refreshLocation(locationResult);
    
    }
    
    });
    
    return loginBinding.getRoot();
    
    }
    
    private void initMap(Bundle savedInstanceState) {
    
    Bundle mapViewBundle = null;
    
    if (savedInstanceState != null) {
    
    mapViewBundle = savedInstanceState.getBundle("MapViewBundleKey");
    
    }
    
    loginBinding.mapview.onCreate(mapViewBundle);
    
    loginBinding.mapview.getMapAsync(this) ;
    
    }
    
    @Override
    
    public void onCreate(@Nullable Bundle savedInstanceState) {
    
    super.onCreate(savedInstanceState);
    
    setHasOptionsMenu(true);
    
    // Initialize the SDK.
    
    MapsInitializer.initialize(getContext());
    
    }
    
    @Override
    
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    
    menu.clear();
    
    super.onCreateOptionsMenu(menu, inflater);
    
    inflater.inflate(R.menu.main, menu);
    
    this.menu = menu;
    
    disableMenu(menu);
    
    }
    
    private void disableMenu(Menu menu) {
    
    try {
    
    if (menu != null) {
    
    if (getPreferenceValue().equals("user_name")) {
    
    menu.findItem(R.id.menu_login_logout).setVisible(false);
    
    menu.findItem(R.id.menu_cancel_auth).setVisible(false);
    
    menu.findItem(R.id.menu_login).setVisible(true);
    
    getActivity().setTitle(getResources().getString(R.string.app_name));
    
    } else {
    
    menu.findItem(R.id.menu_login_logout).setVisible(true);
    
    menu.findItem(R.id.menu_cancel_auth).setVisible(true);
    
    menu.findItem(R.id.menu_login).setVisible(false);
    
    }
    
    }
    
    } catch (Exception e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    private void enableMenu(Menu menu) {
    
    try {
    
    menu.findItem(R.id.menu_login_logout).setVisible(true);
    
    menu.findItem(R.id.menu_cancel_auth).setVisible(true);
    
    menu.findItem(R.id.menu_login).setVisible(false);
    
    } catch (Exception e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    @SuppressLint("NonConstantResourceId")
    
    @Override
    
    public boolean onOptionsItemSelected(MenuItem item) {
    
    switch (item.getItemId()) {
    
    case R.id.menu_cancel_auth:
    
    setPreferenceValue("user_name");
    
    loginViewModel.cancelAuthorization();
    
    disableMenu(menu);
    
    return true;
    
    case R.id.menu_login_logout:
    
    setPreferenceValue("user_name");
    
    loginViewModel.logoutHuaweiID();
    
    disableMenu(menu);
    
    return true;
    
    case R.id.menu_login:
    
    loginViewModel.loginClicked();
    
    return true;
    
    case R.id.option_refresh_location:
    
    locationData.refreshLocation();
    
    return true;
    
    default:
    
    break;
    
    }
    
    return super.onOptionsItemSelected(item);
    
    }
    
    public void updateMessage(String msg) {
    
    getActivity().setTitle(msg);
    
    }
    
    void setPreferenceValue(String userName) {
    
    editor = getActivity().getSharedPreferences(MY_PREF_NAME, MODE_PRIVATE).edit();
    
    editor.putString("user_name", userName);
    
    editor.apply();
    
    }
    
    String getPreferenceValue() {
    
    prefs = getActivity().getSharedPreferences(MY_PREF_NAME, MODE_PRIVATE);
    
    return prefs.getString("user_name", "user_name");
    
    }
    
    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE})
    
    @Override
    
    public void onMapReady(HuaweiMap huaweiMap) {
    
    try{
    
    Log.d(TAG, "Map ready");
    
    hMap = huaweiMap;
    
    onHuaweiMapReady();
    
    }catch (Exception e){
    
    e.printStackTrace();
    
    }
    
    }
    
    private void onHuaweiMapReady() {
    
    if(hMap!=null){
    
    hMap.setMapType(MAP_TYPE_NORMAL);
    
    hMap.setBuildingsEnabled(true);
    
    // Enable the my-location layer.
    
    hMap.setMyLocationEnabled(true);
    
    // Enable the my-location icon.
    
    hMap.getUiSettings().setMyLocationButtonEnabled(true);
    
    hMap.getUiSettings().setGestureScaleByMapCenter(true);
    
    }
    
    if(locationData!=null){
    
    locationData.refreshLocation();
    
    }
    
    }
    
    private void refreshLocation(LocationResult locationResult) {
    
    try{
    
    Log.d(TAG, "Map updated with ");
    
    Log.d(TAG, "Latitude :"+locationResult.getLastLocation().getLongitude()+" Longitude :"+locationResult.getLastLocation().getLongitude());
    
    LatLng latLng1 = new LatLng(locationResult.getLastHWLocation().getLatitude(), locationResult.getLastHWLocation().getLongitude());
    
    float zoom = 10.0f;
    
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng1,zoom);
    
    hMap.animateCamera(cameraUpdate);
    
    
    
    }catch (Exception e){
    
    e.printStackTrace();
    
    
    
    }
    
    }
    
    @Override
    
    public void onLowMemory() {
    
    super.onLowMemory();
    
    loginBinding.mapview.onLowMemory();
    
    }
    
    @Override
    
    public void onDestroy() {
    
    super.onDestroy();
    
    loginBinding.mapview.onDestroy();
    
    }
    
    @Override
    
    public void onStop() {
    
    super.onStop();
    
    loginBinding.mapview.onStop();
    
    locationData.disableLocationData();
    
    }
    
    @Override
    
    public void onPause() {
    
    super.onPause();
    
    loginBinding.mapview.onPause();
    
    }
    
    @Override
    
    public void onStart() {
    
    super.onStart();
    
    loginBinding.mapview.onStart();
    
    }
    
    @Override
    
    public void onSaveInstanceState(@NonNull Bundle outState) {
    
    super.onSaveInstanceState(outState);
    
    Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
    
    if (mapViewBundle == null) {
    
    mapViewBundle = new Bundle();
    
    outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
    
    }
    
    loginBinding.mapview.onSaveInstanceState(mapViewBundle);
    
    }
    
    @Override
    
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    
    super.onViewCreated(view, savedInstanceState);
    
    navController = Navigation.findNavController(view);
    
    }
    
    }
    


    결과



    트릭과 팁

    agconnect-services.json 파일이 추가되었는지 확인합니다.
    필수 종속 항목이 추가되었는지 확인
    AGC에서 서비스가 활성화되어 있는지 확인하십시오.
    gradle.build 파일에서 데이터 바인딩 활성화
    하단 탐색 ID가 탐색 그래프의 프래그먼트 ID와 동일해야 합니다.

    결론

    이 기사에서는 Android 애플리케이션 KnowMyBoard에서 Huawei Map 키트, Location 키트를 통합하는 방법을 배웠습니다. 여기에서 이전 기사 part-2를 살펴볼 수도 있습니다. 이 샘플과 같이 지도 키트 기능이 도움이 되기를 바라며 요구 사항에 따라 지도 키트를 사용할 수 있습니다.

    읽어주셔서 정말 감사합니다. 이 기사가 Android 애플리케이션 KnowMyBoard에서 Huawei 지도 키트와 위치 키트의 통합을 이해하는 데 도움이 되기를 바랍니다.

    참조

    Map KitTraining video

    Location KitTraining video

    좋은 웹페이지 즐겨찾기