我是一位经验丰富的 AS3 开发人员,我已经为我的后端使用 Java 做了很多事情,但我是 Native Android 开发的新手,所以我在第一个项目的一些基本任务方面遇到了麻烦。
所以希望你们中的一个裂缝可以在这里帮助我或指出我正确的方向,这将不胜感激,我会报答在 AS3 部分提供帮助。简要介绍一下我,因为这是我的第一篇文章。;)
手头的任务是在应用程序启动时获取用户的邮政编码。我一直在使用 AsyncTask 进行反向地理编码,它通常似乎可以工作。但只有当我在单击按钮时调用 ReverseGeocodingTask 并在我这样做之前给它几秒钟。如果我立即按下它,它有时会起作用,有时不会,所以很明显,当我在 onCreate 方法中调用它时,应用程序也会崩溃。当我在手机上关闭互联网时,它也会崩溃。我认为网络提供商的位置应该足够了,不需要 GPS 精度和额外的权限。
如果用户关闭了 INet,它应该只显示一条消息,指出找不到邮政编码,并让用户可以选择手动输入。
我认为尚未找到要传递给地理编码的 currentLocation 并且正在抛出 NullPointerException,因此我试图通过在调用之前对其进行检查来防止这种情况发生。但这并没有真正的帮助,也不是最终版本的解决方案。
由于总是最好显示代码,所以你们知道发生了什么,这里是:
package com.adix.DroidTest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.*;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import static java.util.Locale.getDefault;
public class MyActivity extends Activity implements View.OnClickListener {
Button getPostCode, confirm;
TextView tvPostcode;
LocationManager locationManager;
Location currentLocation;
double currentLatitude;
double currentLongitude;
private Handler mHandler;
private static final int UPDATE_ADDRESS = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
AtomicReference<LocationListener> locationListener = new AtomicReference<LocationListener>(new LocationListener() {
public void onLocationChanged(Location location) {
updateLocation(location);
}
private void updateLocation(Location location) {
currentLocation = location;
currentLatitude = currentLocation.getLatitude();
currentLongitude = currentLocation.getLongitude();
}
public void onStatusChanged(
String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
});
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener.get());
//getAddress();
mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_ADDRESS:
tvPostcode.setText((String) msg.obj);
break;
}
}
};
}
private void init() {
getPostCode = (Button)findViewById(R.id.bGetPostCode);
confirm = (Button)findViewById(R.id.bConfirm);
tvPostcode = (TextView)findViewById(R.id.tvPostcode);
getPostCode.setOnClickListener(this);
confirm.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bGetPostCode:
currentLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(currentLocation != null) {
Log.d("TRACE",currentLocation.toString());
Toast.makeText(this, "Suche Postleitzahl", Toast.LENGTH_LONG).show();
(new ReverseGeocodingTask(this)).execute(new Location[]{currentLocation});
}
break;
case R.id.bConfirm:
Intent i = new Intent(MyActivity.this, MainMenu.class);
startActivity(i);
finish();
}
}
private class ReverseGeocodingTask extends AsyncTask<Location, Void, Void> {
Context mContext;
public ReverseGeocodingTask(Context context) {
super();
mContext = context;
}
@Override
protected Void doInBackground(Location... locations) {
try{
Geocoder gcd = new Geocoder(mContext, Locale.getDefault());
List<Address> addresses = gcd.getFromLocation(currentLatitude, currentLongitude,100);
Address address = addresses.get(0);
StringBuilder result = new StringBuilder();
result.append(address.getPostalCode());
// tvPostcode.setText(result.toString());
Message.obtain(mHandler, UPDATE_ADDRESS, result.toString()).sendToTarget();
}
catch(IOException ex){
tvPostcode.setText(ex.getMessage().toString());
Message.obtain(mHandler, UPDATE_ADDRESS, ex.getMessage().toString()).sendToTarget();
}
return null;
}
}
}