Android 显示Location.getLatitude()为空对象,尽管使用了请求位置更新?

Android 显示Location.getLatitude()为空对象,尽管使用了请求位置更新?,android,Android,我是android编程的新手,我一直在尝试使用geofence在我的应用程序中激活alaram服务。它工作得很好,直到有一天它显示了对double.getlatitude()的空指针引用。我搜索了一些网站,但没有结果。我使用RequestLocationUpdate从用户位置获取更新。 这是我的密码- package saksham.geofencing; import android.Manifest; import android.app.Service; import android.c

我是android编程的新手,我一直在尝试使用geofence在我的应用程序中激活alaram服务。它工作得很好,直到有一天它显示了对double.getlatitude()的空指针引用。我搜索了一些网站,但没有结果。我使用RequestLocationUpdate从用户位置获取更新。 这是我的密码-

package saksham.geofencing;

import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.google.android.gms.location.Geofence;
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.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.util.ArrayList;

public class MapsActivity extends FragmentActivity implements LocationListener{

    private GoogleMap googleMap; // Might be null if Google Play services APK is not available.
    public SQLiteDatabase db;
    ArrayList<Geofence> mGeofences;
    public double latitude=77.80;
    public double longitude=55.76;
    Double valueindex=0.0;
    private int request=0;
    /**
     * Geofence Coordinates
     */
    ArrayList<LatLng> mGeofenceCoordinates;
    /**
     * Geofence Store
     */
    private GeofenceStore mGeofenceStore;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGeofences = new ArrayList<Geofence>();
        mGeofenceCoordinates = new ArrayList<LatLng>();
        db = openOrCreateDatabase("CoordsDB", Context.MODE_PRIVATE, null);
//        db.execSQL("CREATE TABLE IF NOT EXISTS Coordinates(number DOUBLE,latitude DOUBLE,longitude DOUBLE);");
//        db.execSQL("INSERT INTO Coordinates VALUES('Fixed', 28.61,77.20)");
        setContentView(R.layout.activity_maps);
        SupportMapFragment supportMapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
        /**
         * SupportMapFragment belongs to the v4 support library, contrary to the default MagFragment that is a native component in Android.
         SupportMapFragment will support more Android versions, but it is also an additional library you have to add in your project,
         so I think it really depends on the Android versions you are targeting:
         •  On recent versions, the default components should be enough
         •  On older versions you will need to install the v4 support library and maybe others
         *
         */
        googleMap = supportMapFragment.getMap();
        Log.i("My activity", "maps=" + googleMap);
        googleMap.setMyLocationEnabled(true);
        /**
         * setMyLocationEnabled(true/false) shows the true location when the GPS is switched on from the device. It is an inbuilt feature of the googlemaps .
         */

        LocationManager locationManager = (LocationManager) getSystemService(Service.LOCATION_SERVICE);
        // getting GPS status
        boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        Log.i("My activity", "gps is" +isGPSEnabled);

        // getting network status
        boolean isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        Log.i("My activity", "network is" +isNetworkEnabled);

        Criteria crta = new Criteria();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
            crta.setAccuracy(Criteria.ACCURACY_FINE);
        }else{
            crta.setAccuracy(Criteria.ACCURACY_MEDIUM);
        }
        /**
         * we have used .setAccuracy as fine for higher SDks than gingerbread .Gingerbread is used as a reference because in apks lower
         * than gingerbread there is very poor geofencing, with gingerbread google made it a lot easier for locationservices to be used for devleopers.
         * it had improved set of tools for Location Services, which included geofencing and substantially improved location discovery.
         */
        crta.setPowerRequirement(Criteria.POWER_LOW);
        String provider = locationManager.getBestProvider(crta, true);

        /**
         * It request Location updates after every 5 sec or if the user traveled 10m
         */
        Log.i("My activity", "manager is " + locationManager);
        Log.i("My activity", "provider is " + provider);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                    MapsActivity.this.requestPermissions(new  String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for Activity#requestPermissions for more details.
                return;
            }
        }
        Location location = locationManager.getLastKnownLocation(provider);
        Log.i("Location is", location + "");



        if (location != null) {

            onLocationChanged(location);
        }
        else
        {
            locationManager.requestLocationUpdates(provider,
                    ( 1000),0, this);
            Log.i("REached here","here");
            onLocationChanged(location);

        }
        /**
         * the Permission is requested after every 5 sec or at a distance of 2 metres by the user.
         */

    }
    @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                switch (requestCode) {
                        case 100: {
                                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                                        Toast.makeText(this, "Thanks for the permission", Toast.LENGTH_LONG).show();
                                        // permission was granted, yay! do the
                                                // calendar task you need to do.
                                                    } else {
                                        // permission denied, boo! Disable the
                                                // functionality that depends on this permission.
                                                        Toast.makeText(this, "You did not allow to access your current location", Toast.LENGTH_LONG).show();
                                    }
                           }
                     // other 'switch' lines to check for other
                              // permissions this app might request
                                }
         }


    @Override
    public void onLocationChanged(Location location) {
                 CameraPosition INIT =
                new CameraPosition.Builder()
                        .target(new LatLng(location.getLatitude(),location.getLongitude()))
                        .zoom( 17.5F )
                        .bearing( 300F) // orientation
                        .tilt( 50F) // viewing angle
                        .build();
        // use GooggleMap mMap to move camera into position
        googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(INIT));
    }
    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onStop() {
//        mGeofenceStore.disconnect();
        super.onStop();
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
    public  void Add(View view) {
        if (request <= 3) {
            mGeofenceCoordinates.add(new LatLng(latitude, longitude));
            Log.i("The id is", "" + valueindex);
            mGeofences.add(new Geofence.Builder()
                    // The coordinates of the center of the geofence and the radius in meters.
                    .setRequestId("" + valueindex)
                    .setCircularRegion(latitude, longitude, 30)
                    .setExpirationDuration(Geofence.NEVER_EXPIRE)
                            // Required when we use the transition type of GEOFENCE_TRANSITION_DWELL
                    .setLoiteringDelay(50000)
                    .setTransitionTypes(
                            Geofence.GEOFENCE_TRANSITION_ENTER
                                    | Geofence.GEOFENCE_TRANSITION_DWELL
                                    | Geofence.GEOFENCE_TRANSITION_EXIT).build());
            mGeofenceStore = new GeofenceStore(this, mGeofences);
            valueindex++;
            request++;

//            Cursor c = db.rawQuery("SELECT * FROM Coordinates WHERE Id='"+valueindex+"'", null);



            googleMap.addMarker(new MarkerOptions().snippet("Radius:30m").draggable(false).title(valueindex + "").position(new LatLng(latitude,longitude)));
        }
        else{
            Toast.makeText(this,"Maximum limit exceeded",Toast.LENGTH_LONG).show();
        }
    }

}

请帮忙

您正在使用else分支中的空值手动调用
onLocationChanged()

if (location != null) {
    onLocationChanged(location);
}
else
{
    locationManager.requestLocationUpdates(provider,
            ( 1000),0, this);
    Log.i("REached here","here");
    // location is null here
    onLocationChanged(location);
}

当您请求位置更新时,LocationManager将调用onLocationChanged回调。

您正在实现的LocationListener来自google api,导入如下:

import com.google.android.gms.location.LocationListener;
而不是这个:

import android.location.LocationListener;

在执行此操作之前,连接LocationClient也是很重要的。也不要在onCreate或onStart方法中调用它,而是在onResume中调用。有关更多详细信息,请浏览:

使用融合位置api。。。这是一个意向服务,所以你只需要挑选你需要的部分。。。你也在使用模拟器吗?如果是这样的话,最后一个已知的位置总是给我带来麻烦/空值。。您是否正在远程登录并使用geofix

package geoimage.ret.geoimage;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;

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;

/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * <p/>
 * TODO: Customize class - update intent actions, extra parameters and static
 * helper methods.
 */


   public class GetLocationService extends IntentService implements    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    // TODO: Rename actions, choose action names that describe tasks that this
    // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS

    private static final String ACTION_LOCATION = "location";
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;


    public GetLocationService() {
        super("GetLocationService");
    }


    /**
     * Starts this service to perform action Baz with the given parameters. If
     * the service is already performing a task this action will be queued.
     *
     * @see IntentService
     */
    // TODO: Customize helper method
    public static void startGetLocation(Context context) {
        Intent intent = new Intent(context, GetLocationService.class);
        intent.setAction(ACTION_LOCATION);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_LOCATION.equals(action)) {
                handleLocation();
            }
        }
    }


    /**
     * Handle action Baz in the provided background thread with the provided
     * parameters.
     */
    private void handleLocation() {
        // TODO: Handle action Baz
        if (mGoogleApiClient == null) {
            buildGoogleApiClient();
        }
        mGoogleApiClient.connect();

    }


    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }


    @Override
    public void onConnected(Bundle bundle) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1);
        mLocationRequest.setFastestInterval(1);
        mLocationRequest.setNumUpdates(1);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        sendBroadcast(connectionResult.getErrorMessage());
    }

    @Override
    public void onLocationChanged(Location location) {


        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

        App.setLat(location.getLatitude());
        App.setLon(location.getLongitude());
        mGoogleApiClient.disconnect();
        sendBroadcast("LocationObtained");


    }

    private void sendBroadcast(String errStatus) {
        Intent intent = new Intent("location");
        intent.putExtra("status", errStatus);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        stopSelf();
        }


    }
package geoimage.ret.geoimage;
导入android.app.IntentService;
导入android.content.Context;
导入android.content.Intent;
导入android.location.location;
导入android.os.Bundle;
导入android.support.v4.content.LocalBroadcastManager;
导入com.google.android.gms.common.ConnectionResult;
导入com.google.android.gms.common.api.GoogleAppClient;
导入com.google.android.gms.location.LocationListener;
导入com.google.android.gms.location.LocationRequest;
导入com.google.android.gms.location.LocationServices;
/**
*用于在中处理异步任务请求的{@link IntentService}子类
*独立处理程序线程上的服务。
*

*TODO:自定义类-更新意图操作、额外参数和静态 *助手方法。 */ 公共类GetLocationService扩展IntentService实现GoogleAppClient.ConnectionCallbacks、GoogleAppClient.OnConnectionFailedListener、LocationListener{ //TODO:重命名操作,选择描述此任务的操作名称 //IntentService可以执行,例如,获取新项目的操作 私有静态最终字符串操作\u LOCATION=“LOCATION”; 位置请求mLocationRequest; GoogleapClient MGoogleapClient; 公共GetLocationService(){ 超级(“GetLocationService”); } /** *启动此服务以使用给定参数执行操作Baz。如果 *服务已在执行此操作将排队的任务。 * *@see IntentService */ //TODO:自定义帮助器方法 公共静态void startGetLocation(上下文){ 意向意向=新意向(上下文,GetLocationService.class); 意图.设置动作(动作位置); 上下文。startService(意图); } @凌驾 受保护的手部内容无效(意图){ if(intent!=null){ 最后一个字符串action=intent.getAction(); if(作用位置等于(作用)){ handleLocation(); } } } /** *在提供的后台线程中使用提供的 *参数。 */ 私有无效handleLocation(){ //TODO:处理动作Baz if(mGoogleApiClient==null){ buildGoogleAppClient(); } mGoogleApiClient.connect(); } 受保护的同步无效BuildGoogleAppClient(){ mgoogleapclient=新的Googleapclient.Builder(此) .addConnectionCallbacks(此) .addOnConnectionFailedListener(此) .addApi(LocationServices.API) .build(); } @凌驾 未连接的公共空间(捆绑包){ mlLocationRequest=新位置请求(); mlLocationRequest.setInterval(1); mlLocationRequest.setFastTestInterval(1); mLocationRequest.SetNumUpdate(1); mLocationRequest.setPriority(位置请求.优先级高精度); LocationServices.FusedLocationApi.RequestLocationUpdate(mgoogleapClient、mlLocationRequest、this); } @凌驾 公共空间连接暂停(int i){ } @凌驾 公共无效onConnectionFailed(ConnectionResult ConnectionResult){ sendBroadcast(connectionResult.getErrorMessage()); } @凌驾 已更改位置上的公共无效(位置){ LocationServices.FusedLocationApi.RemovelocationUpdate(mgoogleapClient,this); App.setLat(location.getLatitude()); App.setLon(location.getLongitude()); mGoogleApiClient.disconnect(); 发送广播(“获得位置”); } 私有void sendBroadcast(字符串状态){ 意向=新意向(“位置”); 意图。putExtra(“状态”,errStatus); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); stopSelf(); } }


如果最后一个已知位置返回null,则似乎调用onLocationChanged with null对象。我认为您应该在location的else分支中从代码中删除该行!=null。仍然返回null值
package geoimage.ret.geoimage;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;

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;

/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * <p/>
 * TODO: Customize class - update intent actions, extra parameters and static
 * helper methods.
 */


   public class GetLocationService extends IntentService implements    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    // TODO: Rename actions, choose action names that describe tasks that this
    // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS

    private static final String ACTION_LOCATION = "location";
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;


    public GetLocationService() {
        super("GetLocationService");
    }


    /**
     * Starts this service to perform action Baz with the given parameters. If
     * the service is already performing a task this action will be queued.
     *
     * @see IntentService
     */
    // TODO: Customize helper method
    public static void startGetLocation(Context context) {
        Intent intent = new Intent(context, GetLocationService.class);
        intent.setAction(ACTION_LOCATION);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_LOCATION.equals(action)) {
                handleLocation();
            }
        }
    }


    /**
     * Handle action Baz in the provided background thread with the provided
     * parameters.
     */
    private void handleLocation() {
        // TODO: Handle action Baz
        if (mGoogleApiClient == null) {
            buildGoogleApiClient();
        }
        mGoogleApiClient.connect();

    }


    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }


    @Override
    public void onConnected(Bundle bundle) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1);
        mLocationRequest.setFastestInterval(1);
        mLocationRequest.setNumUpdates(1);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        sendBroadcast(connectionResult.getErrorMessage());
    }

    @Override
    public void onLocationChanged(Location location) {


        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

        App.setLat(location.getLatitude());
        App.setLon(location.getLongitude());
        mGoogleApiClient.disconnect();
        sendBroadcast("LocationObtained");


    }

    private void sendBroadcast(String errStatus) {
        Intent intent = new Intent("location");
        intent.putExtra("status", errStatus);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        stopSelf();
        }


    }