1. 程式人生 > >Android手機智慧定位並在地圖上顯示地址

Android手機智慧定位並在地圖上顯示地址

  最近做的專案用到了GPS、Wifi、基站三種不同方式進行定位,研究一下發現高德地圖提供的智慧選擇定位方式進行定位較好,就寫了下面相關程式碼進行定位並在地圖上顯示。有些寫的不詳細,大家可以去參考官方文件。

1.java程式碼:MyActivity

package com.gu.ALocationByGD;

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.view.View;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.LocationManagerProxy;
import com.amap.api.location.LocationProviderProxy;

/**
 * 本例項採用高德的智慧定位包進行的智慧選擇定位方式進行定位,wifi網路、周圍基站以及gps
 */
public class MyActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.location).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //開始定位
                initLocation();
            }
        });
    }



    //定位管理服務
    private LocationManagerProxy mLocationManagerProxy;

    //停止定位,在定位完不需要再次定位是關閉定位服務,釋放資源
    private void stopLocation() {
        if (mLocationManagerProxy != null) {
            mLocationManagerProxy.removeUpdates(amapLocationListener);
            mLocationManagerProxy.destory();
        }
        mLocationManagerProxy = null;
    }

    //初始化定位
    private void initLocation() {
        mLocationManagerProxy = LocationManagerProxy.getInstance(this);

        //此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網路流量消耗,
        //注意設定合適的定位時間的間隔,並且在合適時間呼叫removeUpdates()方法來取消定位請求
        //在定位結束後,在合適的生命週期呼叫destroy()方法
        //其中如果間隔時間為-1,則定位只定一次
        mLocationManagerProxy.requestLocationUpdates(LocationProviderProxy.AMapNetwork, -1, 1, amapLocationListener);
        mLocationManagerProxy.setGpsEnable(false);
    }

    //定位監聽
    private AMapLocationListener amapLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (aMapLocation != null) {
                saveDisconnectLocation(aMapLocation);
            }
        }

        @Override
        public void onLocationChanged(Location location) {

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    };

    double lat, lon;

    //儲存定位到的座標位置,並跳轉到地圖介面進行定位
    private void saveDisconnectLocation(AMapLocation amaplocation) {
        lon = amaplocation.getLongitude();
        lat = amaplocation.getLatitude();
        // disconnect record
        if (lon != 0 && lat != 0) {
            stopLocation();
            Intent intent = new Intent();
            intent.setClass(MyActivity.this, MapActivity.class);
            intent.putExtra("lat", lat);
            intent.putExtra("lon", lon);
            startActivity(intent);
            finish();
        }
    }
}

相應xml程式碼:

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="自動選擇gps、wifi、基站定位"
        android:textColor="#ff00ff"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp" />

    <Button
        android:id="@+id/location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Location"
        android:textColor="#ff00ff"
        android:padding="10dp"
        android:layout_centerInParent="true" />

</RelativeLayout>
2.java程式碼:MapActivity
package com.gu.ALocationByGD;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Toast;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;

import java.text.SimpleDateFormat;

/**
 * Todo:地圖顯示定位資訊
 *
 * @author moxiang
 * @version V1.0
 * @data 2014/10/14
 */
public class MapActivity extends Activity implements Runnable, AMap.OnMarkerDragListener,
        AMap.OnMapLoadedListener, AMap.OnMarkerClickListener, AMap.OnInfoWindowClickListener, AMap.InfoWindowAdapter,
        GeocodeSearch.OnGeocodeSearchListener {

    private static final String TAG = MapActivity.class.getSimpleName();
    protected LatLonPoint mLatLonPoint = null;
    private double latitude;
    private double longitude;
    private MapView mapView;
    private AMap mAMap;
    private String addressName;
    private GeocodeSearch geocodeSearch;
    private ProgressDialog progDialog = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.map_layout);
        mapView = (MapView) findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);

        init();

        Intent intent = getIntent();
        latitude = intent.getDoubleExtra("lat", 0);
        longitude = intent.getDoubleExtra("lon", 0);
        Log.e(TAG, "lat: " + latitude + " lon: " + longitude);
        if (latitude != 0 && longitude != 0) {
            mLatLonPoint = new LatLonPoint(latitude, longitude);
            getAddressByLatLng(mLatLonPoint);
        }
    }

    private void init() {
        if (mAMap == null) {
            mAMap = mapView.getMap();
            geocodeSearch = new GeocodeSearch(this);
            geocodeSearch.setOnGeocodeSearchListener(this);
            setUpMap();
            progDialog = new ProgressDialog(this);
        }
    }

    private void setUpMap() {
        mAMap.setOnMarkerDragListener(this);
        mAMap.setOnMapLoadedListener(this);
        mAMap.setOnMarkerClickListener(this);
        mAMap.setOnInfoWindowClickListener(this);
        mAMap.setInfoWindowAdapter(this);
    }

    // 根據經緯度獲取地址
    public void getAddressByLatLng(final LatLonPoint latLngPoint) {
        showDialog();
        RegeocodeQuery query = new RegeocodeQuery(latLngPoint, 200, GeocodeSearch.AMAP);
        geocodeSearch.getFromLocationAsyn(query);
    }

    public void showDialog() {
        progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progDialog.setIndeterminate(false);
        progDialog.setCancelable(true);
        progDialog.setMessage(getString(R.string.map_loading));
        progDialog.show();
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public View getInfoWindow(Marker marker) {
        return null;
    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }

    @Override
    public void onInfoWindowClick(Marker marker) {

    }

    @Override
    public void onMapLoaded() {

    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        return false;
    }

    @Override
    public void onMarkerDragStart(Marker marker) {

    }

    @Override
    public void onMarkerDrag(Marker marker) {

    }

    @Override
    public void onMarkerDragEnd(Marker marker) {

    }

    @Override
    public void run() {

    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
        dismissDialog();
        if (rCode == 0) {
            if (result != null && result.getRegeocodeAddress() != null
                    && result.getRegeocodeAddress().getFormatAddress() != null) {
                addressName = result.getRegeocodeAddress().getFormatAddress() + "\n " + getDate() + " " + getTime();
                addPositionAnnotation(latitude, longitude, addressName);
            }
        } else {
            Toast.makeText(this, getString(R.string.map_neterr), Toast.LENGTH_SHORT).show();
        }
    }

    //獲取系統日期
    public String getDate() {
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return sDateFormat.format(new java.util.Date());
    }

    //獲取系統時間
    public String getTime() {
        SimpleDateFormat sDateFormat = new SimpleDateFormat("hh:mm:ss");
        return sDateFormat.format(new java.util.Date());
    }

    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

    }

    public void addPositionAnnotation(double latitude, double longitude, String address) {

        /*
         *第一個引數是包含經緯度的物件
         * 第二個引數是地圖的放大倍數
         */
        mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 16));

        //地址標註
        Marker marker = mAMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
                .position(new LatLng(latitude, longitude))//地圖上的位置
                .title(address)//要顯示的內容
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
                .draggable(false));
        marker.showInfoWindow();
    }

    public void dismissDialog() {
        if (progDialog != null) {
            progDialog.dismiss();
        }
    }
}

相應xml程式碼:
<?xml version="1.0" encoding="utf-8"?>

<com.amap.api.maps2d.MapView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3.manifest配置:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
 <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="key值" />

顯示效果如下:



轉載註明出處