我是安卓编程的新手,我一直在尝试使用地理围栏在我的应用程序中激活 alaram 服务。它工作正常,直到有一天它显示了对double.getlatitude()的空指针引用。我搜索过网站,但没有结果。我使用请求位置更新从用户位置获取更新。这是我的代码-
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();
}
}
}
这是我的日志猫-
Process: saksham.geofencing, PID: 12102
java.lang.RuntimeException: Unable to start activity ComponentInfo{saksham.geofencing/saksham.geofencing.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at saksham.geofencing.MapsActivity.onCreate(MapsActivity.java:122)
at android.app.Activity.performCreate(Activity.java:6245)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-24 02:11:14.268 12102-12102/saksham.geofencing I/Process﹕ Sending signal. PID: 12102 SIG: 9
请帮忙!!
使用融合的位置 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();
}
}
您在此处的 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);
}
当您请求位置更新时,位置管理器将调用 onLocationChanged 回调。
您正在实现的LocationListener来自Google api,导入是这样的:
import com.google.android.gms.location.LocationListener;
而不是这个:
import android.location.LocationListener;
在执行此操作之前,连接位置客户端也很重要。也不要在 onCreate 或 onStart 方法中调用它,而是在 onResume 中调用它。有关更多详细信息,请访问:https://developer.android.com/training/location/index.html