Java의 탐색 구성 요소를 사용하여 Android KnowMyBoard 앱에 Huawei Map Kit 및 Location Kit 통합

Java의 탐색 구성 요소를 사용하여 Android KnowMyBoard 앱에 Huawei Map Kit 및 Location Kit 통합

2022-10-19 last update

38 minutes reading navigationcomponent huaweilocationkit huaweimapkit hmscore

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

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

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

지원되는 장치

지원 국가/지역

지원 국가/지역

개발 개요

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

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

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

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

    3단계. Adding HMS Core SDK

    코딩을 시작하자

    메인 액티비티.자바

     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();
        }
    }
    
    


    로그인보기 모델.자바

    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);
        }
    }
    
    


    요청위치데이터.자바

    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>
    
    


    로그인Fragment.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 kit, Location kit를 통합하는 방법을 배웠습니다. 이전 기사 파트 2를 여기에서 볼 수도 있습니다. 지도 키트 기능이 이 샘플과 같이 여러분에게도 도움이 되기를 바라며 요구 사항에 따라 지도 키트를 사용할 수 있습니다.

    읽어주셔서 감사합니다. 이 기사가 Android 애플리케이션 KnowMyBoard에서 Huawei Map kit와 Location kit의 통합을 이해하는 데 도움이 되기를 바랍니다.

    참조

    Map KitTraining video

    Location KitTraining video