地图API与位置设置GPS只加载 [英] Maps API only loads with location setting GPS

查看:291
本文介绍了地图API与位置设置GPS只加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用谷歌地图API在我的Andr​​oid应用程序,并找到与用户
的LocationManager getLongitude() getLatitude()
但是,现在必须要在手机上陌生的设置,以获得一张地图。位置设置已被更改为只使用GPS,甚则它不工作的时候,有时地图未加载。如果没有加载应用程序在该点关闭第一个标记,因为 NullPointerException异常设置。

这是为什么,我该如何prevent呢?
我已经尝试过用 getMapAsync ,但它并没有帮助。

  GoogleMap的GoogleMap的;
的LocationManager的LocationManager;
串供应商;
标准标准;
位置myLocation;
@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_map);   尝试{
        如果(GoogleMap的== NULL){
            使用GoogleMap =((MapFragment)getFragmentManager()findFragmentById(R.id.map)。)的GetMap();
        }
        googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        googleMap.setMyLocationEnabled(真);
        googleMap.setTrafficEnabled(真);
        googleMap.setIndoorEnabled(真);
        googleMap.setBuildingsEnabled(真);
        googleMap.getUiSettings()setZoomControlsEnabled(真)。        的LocationManager =(的LocationManager)getSystemService(Context.LOCATION_SERVICE);
        标准=新标准();
        供应商= locationManager.getBestProvider(标准,真正的);
        myLocation = locationManager.getLastKnownLocation(供应商);
        双纬度= myLocation.getLatitude();
        双经度= myLocation.getLongitude();
        经纬度的latLng =新的经纬度(纬度,经度);
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(的latLng));
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(14));
        iconDone = R.drawable.markerdone;
        图标= R.drawable.marker;
    }
    赶上(例外五){
        e.printStackTrace();
    }    标记MARKER1 = googleMap.addMarker(新的MarkerOptions()
            .POSITION(新经纬度(49.793012,9.926201))
            .title伪(的getString(R.string.Title1))
            是.snippet()
            .icon(BitmapDesc​​riptorFactory.fromResource(图标)));


解决方案

现在的问题是,我们在调用 getLastKnownLocation(),它经常会返回一个空位置,因为它不明确地请求一个新的位置锁定。

所以,当你的应用程序崩溃,它试图反引用位置对象时,是由于一个NullPointerException异常。

这是最好的请求位置更新,如果你只需要一个,只是一旦第一 onLocationChanged()回调来自于未注册位置更新。

下面是一个使用FusedLocationProvider的API,它会自动使用网络位置以及GPS定位一个例子,如果需要的:

相关进口活动:

 进口com.google.android.gms.common.ConnectionResult;
进口com.google.android.gms.common.api.GoogleApiClient;
进口com.google.android.gms.location.LocationListener;
进口com.google.android.gms.location.LocationRequest;
进口com.google.android.gms.location.LocationServices;
进口com.google.android.gms.maps.CameraUpdateFactory;
进口com.google.android.gms.maps.GoogleMap;
进口com.google.android.gms.maps.SupportMapFragment;
进口com.google.android.gms.maps.OnMa preadyCallback;
进口com.google.android.gms.maps.model.BitmapDesc​​riptorFactory;
进口com.google.android.gms.maps.model.CameraPosition;
进口com.google.android.gms.maps.model.LatLng;
进口com.google.android.gms.maps.model.Marker;
进口com.google.android.gms.maps.model.MarkerOptions;

活动:

 公共类MainActivity扩展AppCompatActivity
        实现OnMa preadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,LocationListener的{
    GoogleMap的GoogleMap的;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    标记标记;    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }    @覆盖
    保护无效onResume(){
        super.onResume();        SupportMapFragment mapFragment =(SupportMapFragment)getSupportFragmentManager()
                .findFragmentById(R.id.map);        mapFragment.getMapAsync(本);
    }    保护同步无效buildGoogleApiClient(){
        Toast.makeText(这一点,buildGoogleApiClient,Toast.LENGTH_SHORT).show();
        mGoogleApiClient =新GoogleApiClient.Builder(本)
                .addConnectionCallbacks(本)
                .addOnConnectionFailedListener(本)
                .addApi(LocationServices.API)
                。建立();
    }    @覆盖
    公共无效onMa pready(GoogleMap的地图){        GoogleMap的地图=;        setUpMap();    }    公共无效setUpMap(){        googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        googleMap.setMyLocationEnabled(真);
        googleMap.getUiSettings()setZoomControlsEnabled(真)。    }    @覆盖
    公共无效onConnected(束束){        mLocationRequest =新LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setSmallestDisplacement(0.1F);        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,这一点);
    }    @覆盖
    公共无效onConnectionSuspended(int i)以{    }    @覆盖
    公共无效onLocationChanged(地点){        //注销位置更新
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,这一点);        //删除previously放置标记
        如果(标记!= NULL){
            marker.remove();
        }        经纬度的latLng =新的经纬度(location.getLatitude(),location.getLongitude());
        //位置标记,其中用户刚刚点击
        标记= googleMap.addMarker(新的MarkerOptions()
                .POSITION(的latLng)
                .title伪(当前位置)
                .icon(BitmapDesc​​riptorFactory.defaultMarker(BitmapDesc​​riptorFactory.HUE_MAGENTA)));        CameraPosition cameraPosition =新CameraPosition.Builder()
                .TARGET(的latLng).zoom(5).build();        googleMap.animateCamera(CameraUpdateFactory
                .newCameraPosition(cameraPosition));
    }    @覆盖
    公共无效onConnectionFailed(ConnectionResult connectionResult){    }}

的build.gradle(改变谷歌的任何版本的播放您当前使用服务):

  {相关性
    编译文件树(导演:'库',包括:['的* .jar'])
    编译com.android.support:appcompat-v7:22.1.1
    编译com.google.android.gms:播放服务:7.5.0
}

SupportMapFragment在布局XML(您可以使用MapFragment以及):

 <片段
    机器人:ID =@ + ID /图
    类=com.google.android.gms.maps.SupportMapFragment
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent/>

只使用网络位置:

地图移动到当前位置秒后启动:

I use the Google Maps API in my Android app and locate the user with LocationManager and getLongitude(), getLatitude(). But now there have to be strange settings on the mobile phone to get a map. The location setting has to be changed to only use GPS, and even then it's not working all the time, sometimes the map is not loaded. If not loaded the app shuts down at the point the first marker is set because of NullPointerException.

Why is this and how can I prevent it? I already tried with getMapAsync but it didn't help.

GoogleMap googleMap;
LocationManager locationManager;
String provider;
Criteria criteria;
Location myLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map);

   try {
        if(googleMap == null) {
            googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
        }
        googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        googleMap.setMyLocationEnabled(true);
        googleMap.setTrafficEnabled(true);
        googleMap.setIndoorEnabled(true);
        googleMap.setBuildingsEnabled(true);
        googleMap.getUiSettings().setZoomControlsEnabled(true);

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        criteria = new Criteria();
        provider = locationManager.getBestProvider(criteria, true);
        myLocation = locationManager.getLastKnownLocation(provider);
        double latitude = myLocation.getLatitude();
        double longitude = myLocation.getLongitude();
        LatLng latLng = new LatLng(latitude, longitude);
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(14));
        iconDone = R.drawable.markerdone;
        icon = R.drawable.marker;
    }
    catch(Exception e) {
        e.printStackTrace();
    }

    Marker marker1 = googleMap.addMarker(new MarkerOptions()
            .position(new LatLng(49.793012, 9.926201))
            .title(getString(R.string.Title1))
            .snippet("")
            .icon(BitmapDescriptorFactory.fromResource(icon)));

解决方案

The problem is that you're calling getLastKnownLocation(), which will frequently return a null Location, since it doesn't explicitly request a new location lock.

So, when your app is crashing, it's due to a NullPointerException when trying to de-reference the Location object.

It's best to request location updates, and if you only need one, just un-register for location updates once the first onLocationChanged() callback comes in.

Here is an example using the FusedLocationProvider API, which automatically uses Network Location as well as GPS Location if needed:

Relevant imports for the Activity:

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

Activity:

public class MainActivity extends AppCompatActivity 
        implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks, 
        GoogleApiClient.OnConnectionFailedListener, LocationListener {


    GoogleMap googleMap;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Marker marker;

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

        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

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

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);

        mapFragment.getMapAsync(this);
    }

    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this,"buildGoogleApiClient", Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onMapReady(GoogleMap map) {

        googleMap = map;

        setUpMap();

    }

    public void setUpMap() {

        googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        googleMap.setMyLocationEnabled(true);
        googleMap.getUiSettings().setZoomControlsEnabled(true);

    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setSmallestDisplacement(0.1F);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onLocationChanged(Location location) {

        //unregister location updates
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

        //remove previously placed Marker
        if (marker != null) {
            marker.remove();
        }

        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        //place marker where user just clicked
        marker = googleMap.addMarker(new MarkerOptions()
                .position(latLng)
                .title("Current Location")
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));

        CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(latLng).zoom(5).build();

        googleMap.animateCamera(CameraUpdateFactory
                .newCameraPosition(cameraPosition));


    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

}

build.gradle (change to whatever version of Google Play Services you are currently using):

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.1.1'
    compile 'com.google.android.gms:play-services:7.5.0'
}

SupportMapFragment in the layout xml (you can use a MapFragment as well):

    <fragment
    android:id="@+id/map"
    class="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Using only Network Location:

The Map moves to the current location seconds after launch:

这篇关于地图API与位置设置GPS只加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆