java - 此代码有什么问题?应用程序应获取位置

标签 java android crash location

当我尝试启动该应用程序时(它应该读取我的位置)崩溃:

我已尽力修复了该问题,但我认为我监督了一些基本问题。

主要 Activity :

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.support.v4.content.LocalBroadcastManager;
import java.util.Locale;

public class MainActivity extends Activity {
    public static final String TAG = "MainActivity";
    private LocalBroadcastManager mLocalBroadcastManager;
    private BroadcastReceiver mBroadcastReceiver;
    private Intent mServiceIntent;
    private TextView mLatitude;
    private TextView mLongitude;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mLatitude = (TextView) findViewById(R.id.latitude);
        mLongitude = (TextView) findViewById(R.id.longitude);

        mServiceIntent = new Intent(this, LocationService.class);

        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
        mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onReceive()");
            mLatitude.setText(String.format(Locale.getDefault(), "%.6f", intent.getDoubleExtra(LocationService.EXTRA_LATITUDE, 0.0)));
            mLongitude.setText(String.format(Locale.getDefault(), "%.6f", intent.getDoubleExtra(LocationService.EXTRA_LONGITUDE, 0.0)));
        }
    };

    mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, new IntentFilter(LocationService.INTENT_NAME));

    mLatitude.setText(savedInstanceState.getString(LocationService.EXTRA_LATITUDE, "0.0"));
    mLongitude.setText(savedInstanceState.getString(LocationService.EXTRA_LONGITUDE, "0.0"));
}

@Override
protected void onSaveInstanceState(Bundle bundle){
    super.onSaveInstanceState(bundle);
    bundle.putString(LocationService.EXTRA_LONGITUDE, mLatitude.getText().toString());
    bundle.putString(LocationService.EXTRA_LATITUDE, mLongitude.getText().toString());
    Log.d(TAG, bundle.toString());
}

@Override
protected void onDestroy(){
    mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);
}

public void startGps(){
    startService(mServiceIntent);
}

public void stopGps(){
    stopService(mServiceIntent);
}

}

定位服务:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class LocationService extends Service {
    public static final String TAG = "LocationService";
    public static final String INTENT_NAME = "location_changed";
    public static final String EXTRA_LATITUDE = "latitude";
    public static final String EXTRA_LONGITUDE = "longitude";
    private LocationManager mLocationManager;
    private LocationListener mLocationListener;
    private LocalBroadcastManager mLocalBroadcastManager;

    public void onCreate(Bundle bundle){
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);

        mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        mLocationListener = new LocationListener() {
            @Override
            public void onLocationChanged(final Location location) {
                Log.d(TAG, "onLocationChanged()");

                Intent intent = new Intent(INTENT_NAME);
                intent.putExtra("Latitude", location.getLatitude());
                intent.putExtra("Longitude", location.getLongitude());

                mLocalBroadcastManager.sendBroadcast(intent);
            }

            // we do not need the following function, but they have to be implemented (even if they are just empty)
            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {}
            @Override
            public void onProviderEnabled(String provider) {}
            @Override
            public void onProviderDisabled(String provider) {}
        };
    }

    @Override
    public void onDestroy() throws SecurityException{
        mLocationManager.removeUpdates(mLocationListener);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) throws SecurityException{
        super.onStartCommand(intent, flags, startId);
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
        return Service.START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent){
        return null;
    }
}

最佳答案

onCreate(savedInstanceState)的Javadoc指出:

savedInstanceState Bundle: If the activity is being re-initialized after previously being shut down then this Bundle contains the data it most recently supplied in onSaveInstanceState(Bundle). Note: Otherwise it is null.



调用savedInstanceState.getString时会得到NPE,并带有一条消息告诉您savedInstanceState

解决方案:修改onCreate方法以解决尚无保存实例的情况;即当savedInstanceStatenull时。

关于java - 此代码有什么问题?应用程序应获取位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44387491/

相关文章:

java - 根据时基设置时间选择器

Android 检查 EditText 中的空格

objective-c - 无法解释的崩溃 iOS

crash - Nuget PM崩溃VS 2019

iPhone 应用程序在没有正当理由的情况下崩溃?

java - 如何返回链表中的元素数量

java - java.io.FileDescriptor#sync() 是否特定于单个 FileDescriptor

android - 当 Active Android 包含在库中时,无法解析 Gradle 中的 Active Android 依赖项

java - 为什么新线程立即操作UI时没有CalledFromWrongThreadException?

java - 内部锁定、客户端锁定和外部锁定之间的区别?