Android顯示當前位置的Google地圖
在之前的Android Google地圖教程中,我們只是顯示了由MapsActivity.java類文件設置的默認坐標(位置)。愛掏網 - it200.com
現在在這個教程中,我們將顯示并在用戶當前位置放置標記。愛掏網 - it200.com要做到這一點,我們需要生成Google地圖API密鑰。愛掏網 - it200.com生成Google地圖API的過程在Android Google地圖教程中有詳述。愛掏網 - it200.com
要顯示用戶當前位置,我們需要實現一些接口和回調方法。愛掏網 - it200.com
- OnMapRreadyCallback: 當該接口實例被設置在MapFragment對象上時,將調用此回調接口。愛掏網 - it200.com OnMapReadyCallback接口的onMapReady(GoogleMap)方法在地圖準備好使用時被調用。愛掏網 - it200.com在onMapReady(GoogleMap)方法中,我們可以添加標記,監聽器和其他屬性。愛掏網 - it200.com
- LocationListener: 該接口用于接收設備位置發生更改時的通知。愛掏網 - it200.com當位置發生變化時,會調用LocationListener的onLocationChanged(Location)方法。愛掏網 - it200.com
- GoogleApiClient.ConnectionCallbacks: 此接口提供了onConnected(Bundle)和onConnectionSuspended(int)的回調方法,當設備連接和斷開連接時會調用這些方法。愛掏網 - it200.com
- GoogleApiClient.OnConnectionFailedListener: 此接口提供了onConnectionFailed(ConnectionResult)的回調方法,當連接設備與服務時發生錯誤時會調用該方法。愛掏網 - it200.com
GoogleMap的 setMyLocationEnabled() 方法用于啟用位置圖層,允許設備與當前位置進行交互。愛掏網 - it200.com
顯示當前位置的Google地圖示例
讓我們看一個顯示設備當前位置的Google地圖示例。愛掏網 - it200.com
activity_maps.xml
在activity_maps.xml文件中,在片段中添加SupportMapFragment。愛掏網 - it200.com
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="example.com.mapexample.MapsActivity" />
build.gradel
在 build.gradel 文件中添加以下依賴項。愛掏網 - it200.com
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.google.android.gms:play-services-maps:11.8.0'
compile 'com.google.android.gms:play-services-location:11.8.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
MapsActivity.java
在MapsActivity.java文件中添加以下代碼。愛掏網 - it200.com
package example.com.mapexample;
import android.os.Build;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.location.LocationServices;
import android.location.Location;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.content.ContextCompat;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,
LocationListener,GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
private GoogleMap mMap;
Location mLastLocation;
Marker mCurrLocationMarker;
GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
請求運行時權限
需要Android 6.0(Marshmallow)或更高版本的Android設備在運行時訪問設備功能時需要一些權限。愛掏網 - it200.com
在上面的MapsActivity.java文件中,我們添加了一個運行時權限 Manifest.permission.ACCESS_FINE_LOCATION 用于請求訪問設備位置。愛掏網 - it200.com運行時權限使用 checkSelfPermission() 方法進行檢查,返回 PackageManager.PERMISSION_GRANTED 或 PackageManager.PERMISSION_DENIED 。愛掏網 - it200.com如果權限被授予,則應用程序繼續操作。愛掏網 - it200.com
AndroidManifest.xml中需要的權限
在AndroidManifest.xml文件中添加以下用戶權限。愛掏網 - it200.com
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.com.mapexample">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
輸出