Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android - 自帶gps定位Location相關知識

android - 自帶gps定位Location相關知識

編輯:關於Android編程

android自帶gps定位功能相信大家都不會太陌生了,都有所涉及。簡單的寫了一個示例程序,獲取經緯度還有其它相關數據的代碼,還有其他相關的知識,比如直接跳轉到打開系統gps設置的界面。還有一個bug的處理,異常信息:Incomplete location object, missing timestamp or accuracy

1、獲取location 示例程序

package com.example.locationexample;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.widget.TextView;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;

public class MainActivity extends Activity {
	LocationManager mLocationManager;
	Location mlocation;
	TextView mTextView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mTextView = (TextView)findViewById(R.id.textView1);
		
		getLocation();
		
		
//		mlocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
//		mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation);
	}
	
	public Location getLocation(){
		mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		mlocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		if (mlocation == null) {
			mlocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		}
		mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, mLocationListener);
		return mlocation;
	}
	
	LocationListener mLocationListener = new LocationListener() {
		@TargetApi(17)
		@Override
		public void onLocationChanged(Location mlocal) {
			if(mlocal == null) return;
			String strResult = "getAccuracy:" + mlocal.getAccuracy() + "\r\n"
					+ "getAltitude:" + mlocal.getAltitude() + "\r\n"
					+ "getBearing:" + mlocal.getBearing() + "\r\n"
					+ "getElapsedRealtimeNanos:" + String.valueOf(mlocal.getElapsedRealtimeNanos()) + "\r\n"
					+ "getLatitude:" + mlocal.getLatitude() + "\r\n"
					+ "getLongitude:" + mlocal.getLongitude() + "\r\n"
					+ "getProvider:" + mlocal.getProvider()+ "\r\n"
					+ "getSpeed:" + mlocal.getSpeed() + "\r\n"
					+ "getTime:" + mlocal.getTime() + "\r\n";
			Log.i("Show", strResult);
			if (mTextView != null) {
				mTextView.setText(strResult);
				}
		}

		@Override
		public void onProviderDisabled(String arg0) {
		}

		@Override
		public void onProviderEnabled(String arg0) {
		}

		@Override
		public void onStatusChanged(String provider, int event, Bundle extras) {
		}
	};


}

在這裡提醒一下,最好activity銷毀時候onDestroy(),移除mLocationManager這個變量。

權限如下:

    
    
    

還有重點看這行代碼參數mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, mLocationListener);

LocationManager.GPS_PROVIDER是gps提供,100是時間,多久刷新一次,0是距離,如果你不動的話,測試最好寫0

mLocationListener是接口啦,數據就是那裡來的。

2、異常

如果你使用mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation);這行代碼報出下面的堆棧錯誤信息

 java.lang.IllegalArgumentException: Incomplete location object, missing timestamp or accuracy? Location[gps 23.126704,113.365648 acc=1 et=?!? alt=-7.422 vel=0.008333334 bear=237.76]

解決辦法:

方法一:
主要是這句,location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());,其實加上這句就可以了。

例如:

    @SuppressLint("NewApi")
    private Location getLoc(String provider)
    {
        Location location = new Location(provider);
        location.setLatitude(lat);
        location.setLongitude(lng);
        location.setAltitude(altitude);
        location.setBearing(bearing);
        location.setSpeed(speed);
        location.setAccuracy(accuracy);
        location.setTime(System.currentTimeMillis());
        location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
        return location;
    }
主要是這句,location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());,其實加上這句就可以了。如下
		mlocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
		mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation);

方法二,加上下面的反射調用:
    try
    {
        Method method = Location.class.getMethod("makeComplete");
        if (method != null)
        {
            method.invoke(localLocation);
        }
    }
    catch (NoSuchMethodException e)
    {
        e.printStackTrace();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

方法二使用,是借鑒android系統源碼的反射作用

源碼如下:

   /**
     * Helper to fill incomplete fields.
     *
     * 
Used to assist in backwards compatibility with
     * Location objects received from applications.
     *
     * @see #isComplete
     * @hide
     */
    public void makeComplete() {
        if (mProvider == null) mProvider = "?";
        if (!mHasAccuracy) {
            mHasAccuracy = true;
            mAccuracy = 100.0f;
        }
        if (mTime == 0) mTime = System.currentTimeMillis();
        if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
    }

建議使用第一個方法。

3、是否已打開自身GPS

	//獲取是否已打開自身GPS
	public boolean isGpsEnable() {
		String providers = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

		if (providers.contains(LocationManager.GPS_PROVIDER)) {
			return true;
		} else {
			return false;
		}
	}

4、直接跳轉到系統設置gps界面

	Intent callGPSSettingIntent = new Intent(
		android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
		this.startActivity(callGPSSettingIntent);


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved