Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Integrating Real-Time User Location and Custom Markers with Baidu Maps on Android

Tech 1

Android Manifest Configuration

To enible mapping and location serviecs, you must declare the necessary permissions in your AndroidManifest.xml. These allow the application to access network states, GPS data, and storage.

<!-- Essential Permissions for Baidu Maps -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!-- Screen Compatibility -->
<supports-screens 
    android:largeScreens="true"
    android:normalScreens="true" 
    android:smallScreens="true"
    android:resizeable="true" 
    android:anyDensity="true"/>

Layout Implementation

Add the MapView component to your XML layout file. This component acts as the container for the map interface.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.baidu.mapapi.MapView
        android:id="@+id/main_bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />

</LinearLayout>

MapActivity and Location Logic

The following implementation extends MapActivity to handle the map engine initialization, user location tracking, and the rendering of custom map markers.

package com.tech.map.demo;

import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapController;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.MyLocationOverlay;
import com.baidu.mapapi.OverlayItem;

import java.util.ArrayList;
import java.util.List;

public class LocationTrackingActivity extends MapActivity {

    private MapView mBaiduMapView;
    private BMapManager mBMapManager;
    private MapController mController;
    private LocationListener mLocListener;
    private MyLocationOverlay mUserLocationOverlay;

    private final String API_KEY = "YOUR_BAIDU_MAP_API_KEY";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_main);

        mBaiduMapView = findViewById(R.id.main_bmapView);
        mBMapManager = new BMapManager(this);

        mBMapManager.init(API_KEY, new MKGeneralListener() {
            @Override
            public void onGetPermissionState(int status) {
                if (status == 300) {
                    Toast.makeText(LocationTrackingActivity.this, "Invalid API Key!", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onGetNetworkState(int error) {
                Log.e("MapError", "Network error state: " + error);
            }
        });

        initMapActivity(mBMapManager);

        mBaiduMapView.setBuiltInZoomControls(true);
        mController = mBaiduMapView.getController();
        mController.setZoom(14);

        // Initialize user location tracking layer
        mUserLocationOverlay = new MyLocationOverlay(this, mBaiduMapView);
        mBaiduMapView.getOverlays().add(mUserLocationOverlay);

        mLocListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                if (location != null) {
                    GeoPoint point = new GeoPoint((int) (location.getLatitude() * 1e6),
                            (int) (location.getLongitude() * 1e6));
                    mController.animateTo(point);
                }
            }
        };
    }

    public void triggerGpsSearch(View view) {
        mBMapManager.getLocationManager().requestLocationUpdates(mLocListener);
        mUserLocationOverlay.enableMyLocation();
        mController.zoomIn();
    }

    public void renderCustomPoints(View view) {
        Drawable markerIcon = getResources().getDrawable(R.drawable.custom_pin_icon);
        CustomMarkerOverlay customOverlay = new CustomMarkerOverlay(markerIcon);
        mBaiduMapView.getOverlays().add(customOverlay);
        mController.zoomIn();
    }

    // Inner class for managing multiple map markers
    public class CustomMarkerOverlay extends ItemizedOverlay<OverlayItem> {
        private List<OverlayItem> mItems = new ArrayList<>();

        public CustomMarkerOverlay(Drawable marker) {
            super(marker);
            
            // Sample coordinates
            double[][] coordinates = {
                {31.15443, 121.57428}, {31.23443, 121.657428},
                {31.22777, 121.59000}, {31.22477, 121.63000}
            };

            for (int i = 0; i < coordinates.length; i++) {
                GeoPoint gp = new GeoPoint((int) (coordinates[i][0] * 1e6), (int) (coordinates[i][1] * 1e6));
                mItems.add(new OverlayItem(gp, "Location " + (i + 1), "Details for point " + (i + 1)));
            }
            populate();
        }

        @Override
        protected OverlayItem createItem(int index) {
            return mItems.get(index);
        }

        @Override
        public int size() {
            return mItems.size();
        }

        @Override
        public boolean onTap(int index) {
            Toast.makeText(LocationTrackingActivity.this, mItems.get(index).getSnippet(), Toast.LENGTH_SHORT).show();
            return true;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mBMapManager != null) {
            mBMapManager.getLocationManager().requestLocationUpdates(mLocListener);
            mUserLocationOverlay.enableMyLocation();
            mUserLocationOverlay.enableCompass();
            mBMapManager.start();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mBMapManager != null) {
            mBMapManager.getLocationManager().removeUpdates(mLocListener);
            mUserLocationOverlay.disableMyLocation();
            mUserLocationOverlay.disableCompass();
            mBMapManager.stop();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBMapManager != null) {
            mBMapManager.destroy();
            mBMapManager = null;
        }
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

Resource Management

It is critical to manage the BMapManager lifecycle correctly. Failure to call stop() and removeUpdates() in onPause, or destroy() in onDestroy, can lead to memory leaks and unnnecessary battery consumption by keeping GPS services active in the background.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.