android - ResultReceiver 给出 Nullpointer 异常

标签 android android-intentservice

我正在使用地理编码来检索纬度、经度值的地址。我在扩展 IntentService 的单独类中实现此 GeoCoding。当我检索地址时,我想将它发送回原始的主要 Activity ,为此我使用 ResultReciever,并且实际上遵循 tutorial .

这是我用于 GeoCode 的类,即将 GPS 坐标传输到物理地址。在 onHandleIntent

中调用函数调用 deliverResultToReceiver 时出现错误
public class FetchAddressIntentService extends IntentService {

    protected ResultReceiver mReceiver;


    public FetchAddressIntentService() {
        super("GPSGame");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Geocoder geocoder = new Geocoder(this, Locale.getDefault());

        String errorMessage = "";

        // Get the location passed to this service through an extra.
        Location location = intent.getParcelableExtra(
                Constants.LOCATION_DATA_EXTRA);
        Log.e("LAT",Double.toString(location.getLatitude()));
        Log.e("LONG",Double.toString(location.getLongitude()));
        List<Address> addresses = null;   /*** ADDRESS CAN BE OF ANOTHER LIBRARY ***/

        try {
            addresses = geocoder.getFromLocation(
                    location.getLatitude(),
                    location.getLongitude(),
                    // In this sample, get just a single address.
                    1);
        } catch (IOException ioException) {
            // Catch network or other I/O problems.
              errorMessage = "service not available";
              Log.e("exception", errorMessage);

        } catch (IllegalArgumentException illegalArgumentException) {
            // Catch invalid latitude or longitude values.
            errorMessage = "IllegalArgumentException";
            Log.e("Exception", errorMessage + ". " +
                    "Latitude = " + location.getLatitude() +
                    ", Longitude = " +
                    location.getLongitude(), illegalArgumentException);

        }

     // Handle case where no address was found.
        if (addresses == null || addresses.size()  == 0) {
            if (errorMessage == "") {
                errorMessage = "no address found";
                Log.e("address", errorMessage);
            }
            deliverResultToReceiver(Constants.FAILURE_RESULT, errorMessage);
        }

        else {
            Address address = addresses.get(0);
            ArrayList<String> addressFragments = new ArrayList<String>();

            // Fetch the address lines using getAddressLine,
            // join them, and send them to the thread.
            for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                addressFragments.add(address.getAddressLine(i));
            }
            Log.i("address", "address found");
            deliverResultToReceiver(Constants.SUCCESS_RESULT,
                    TextUtils.join(System.getProperty("line.separator"), 
                            addressFragments));     TextUtils.join(System.getProperty("line.separator"),addressFragments));

        }

    }

    private void deliverResultToReceiver(int resultCode, String message) {
        Bundle bundle = new Bundle();
        bundle.putString(Constants.RESULT_DATA_KEY, message);
        mReceiver.send(resultCode, bundle);
    }

}

这是我试图在其中获取地址的 MainAcitivty 类。请注意,还有一个私有(private)类 AddressResultReceiver 也扩展了 ResultReciever

public class MainActivity extends Activity implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        latitudeText = (TextView) findViewById(R.id.latitudeText);
        longitudeText = (TextView) findViewById(R.id.longitudeText);
        lastUpdateTimeText = (TextView) findViewById(R.id.lastUpdateText);
        buildGoogleApiClient(); 
    }

    protected void startIntentService() {
        Intent intent = new Intent(this, FetchAddressIntentService.class);
        intent.putExtra(Constants.RECEIVER, mResultReceiver);
        intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
        startService(intent);
        AddressResultReceiver ar = new AddressResultReceiver(null);
        Bundle b = new Bundle();
        ar.onReceiveResult(Constants.SUCCESS_RESULT, b);
    }




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

    }

    @SuppressLint("NewApi")
    @Override
    public void onConnected(Bundle connectionHint) {
        Toast.makeText(this, "onConnected", Toast.LENGTH_LONG).show();
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            String latitude = String.valueOf(mLastLocation.getLatitude());
            String longitude = String.valueOf(mLastLocation.getLongitude());
            latitudeText.setText("latitude: " + latitude);
            longitudeText.setText("longitude: " + longitude);
        }
        if (mLastLocation != null) {
            // Determine whether a Geocoder is available.
            if (!Geocoder.isPresent()) {
                Toast.makeText(this, "No geocoder available",
                        Toast.LENGTH_LONG).show();
                return;
            }    
            if (mAddressRequested) {
                startIntentService();
            }
        }

    }   

    private void updateUI() {
        latitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
        longitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
        lastUpdateTimeText.setText(mLastUpdateTime);
    }

    class AddressResultReceiver extends ResultReceiver {
        public AddressResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {

            // Display the address string
            // or an error message sent from the intent service.
            String mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
            Log.e("RESULT!!!", mAddressOutput);

            // Show a toast message if an address was found.
            if (resultCode == Constants.SUCCESS_RESULT) {
                ;
            }
        }
    }
}

当我调用私有(private)方法 deliverResultToReciever 时,出现空指针异常。如果您能告诉我如何正确获取地址数据,我们将不胜感激

最佳答案

在传递给 Intent Service 之前不初始化 mResultReceiver 对象。按如下方式执行:

protected void startIntentService() {
        Intent intent = new Intent(this, FetchAddressIntentService.class);
        mResultReceiver = new AddressResultReceiver(new Handler());
         .... your code here
    }

并在FetchAddressIntentService 类中初始化mReceiver 对象,方法是在onHandleIntent 方法中获取接收者:

@Override
protected void onHandleIntent(Intent intent) {
  mReceiver = intent.getParcelableExtra(Constants.RECEIVER);
  //...your code here
}

关于android - ResultReceiver 给出 Nullpointer 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29215431/

相关文章:

android - 如何在前台服务中将多个任务排队,以便它们一项一项地执行?

android - IntentService 和 Service 有什么区别?

java - 除非启动应用程序,否则手机重启后 IntentService 不会自动启动

android - 我应该使用 Service 还是 IntentService?

java - 如何在android中将毫秒转换为日期格式?

java - 在android上的javafxports中添加要读写的文件

android - Tab 过渡图标,如 Tinder

php - 使用 PHP 和 MySQL 验证 Android 登录

android - webview 不适用于所有域

android - 如何解决服务类的 ' ANR Reason: executing service ' 错误?