1

设想:

所以到目前为止我所做的是创建了一个 AsyncTask 来处理我的 GeoCoder,它每 3 分钟更新一次(用于测试目的)。然后我设置了一个 TimerTask,它每 4 分钟显示一条带有用户当前地址的 toast 消息。(TimerTasks 不包含在代码中)

那么问题来了:

当我在我的应用程序中时,一切都很好,但是当我的应用程序在后台运行时,Toast 消息停留在我退出应用程序之前应用程序最后设置的任何地址。我确定 AsyncTask 确实在后台运行(已检查 LogCats),而且似乎一切都在后台运行良好,我只是无法在我的 Toast 上显示当前地址。

所有的想法和意见将不胜感激!

这是我的代码:

 public class statuspage extends MapActivity {

LocationManager locationManager;
MapView mapView;
Criteria criteria;
Location location;
Geocoder gc;
Address address;

String bestProvider;
String LOCATION_SERVICE = "location";
String addressString = "Searching for Nearest Address";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.statuspage);

    // Get Mapping Controllers etc //
    mapView = (MapView) findViewById(R.id.mapView);
    mapController = mapView.getController();
    mapController.setZoom(17);
    mapView.setBuiltInZoomControls(true);

    // Add the MyLocationOverlay //
    myLocation = new MyLocationOverlay(this, mapView);
    mapView.getOverlays().add(myLocation);
    myLocation.enableCompass();
    myLocation.enableMyLocation();

    // Animates the map to GPS Position //
    myLocation.runOnFirstFix(new Runnable() {
        @Override
        public void run() {
            mapController.animateTo(myLocation.getMyLocation());

        }
    });
}

@Override
protected boolean isRouteDisplayed() {

    // Location Manager Intiation
    locationManager = (LocationManager) statuspage.this
            .getSystemService(LOCATION_SERVICE);
    criteria = new Criteria();

    // More accurate, GPS fix.
    criteria.setAccuracy(Criteria.ACCURACY_FINE); // More accurate, GPS fix.
    bestProvider = locationManager.getBestProvider(criteria, true);

    location = locationManager.getLastKnownLocation(bestProvider);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(bestProvider, 60000, 10,
            locationListener); // 1800000 = 30 Min

    return false;
}

class GeoCoder extends AsyncTask<Void, Void, Void> {

    String lat = "Acquiring";
    String lng = "Acquiring";

    @Override
    protected Void doInBackground(Void... params) {
        if (location != null) {

            /**
             * double latitude = myLocation.getMyLocation().getLatitudeE6();
             * double longitude =
             * myLocation.getMyLocation().getLongitudeE6();
             */

            double latitude = location.getLatitude();
            double longitude = location.getLongitude();

            lat = "" + latitude;
            lng = "" + longitude;

            // gc = new Geocoder(statuspage.this, Locale.getDefault());
            Geocoder gc = new Geocoder(getApplicationContext(),
                    Locale.getDefault());
            try {

                List<Address> addresses = gc.getFromLocation(latitude,
                        longitude, 1);

                sb = new StringBuilder();
                if (addresses != null && addresses.size() > 0) {
                    address = addresses.get(0);

                    int noOfMaxAddressLine = address
                            .getMaxAddressLineIndex();
                    if (noOfMaxAddressLine > 0) {
                        for (int i = 0; i < address
                                .getMaxAddressLineIndex(); i++) {
                            sb.append(address.getAddressLine(i)).append(
                                    "\n");
                        }
                        addressString = sb.toString();

                    }
                }
            } catch (Exception e) {

                addressString = "Sorry, we are trying to find information about this location";
            }

        }
        return null;
    }


    @Override
    protected void onPostExecute(Void result) {
        TextView scrollview = (TextView) findViewById(R.id.scrollview);

        // Latitude and Longitude TextView
        TextView etlongitude = (TextView) findViewById(R.id.etlongitude);
        TextView etlatitude = (TextView) findViewById(R.id.etlatitude);

        // TextView to display GeoCoder Address
        scrollview.setGravity(Gravity.CENTER);
        scrollview.setText("Your location:" + "\n"
                + "(Accurate to 500 meters)" + "\n" + (addressString));

        Log.d("Address", (addressString));

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText(lng);
        etlatitude.setText(lat);

        // Log.d("GeoCoder", "In-Task");

        return;
    }
4

2 回答 2

0

我有同样的问题。如果我留在当前活动上,没问题,但如果我在doInBackgroud运行时离开活动,onPostExecute将退出 Toast 行。

要解决问题,您必须使用处理程序:
在类中

private static final int TOAST  = 0;
private Handler mHandler = null;

OnCreate()

// Creation of the handler to display Toasts
if (mHandler == null) {
    mHandler = new Handler() {
        @Override
        public void handleMessage(Message _msg) {
            switch (_msg.what) {
            case TOAST:
            Toast.makeText(ServerTabHost.this, (String)_msg.obj, Toast.LENGTH_LONG).show();
            break;
            default : break;
        }
        super.handleMessage(_msg);
        }
    };
}

onPostExecute()

Message msg = new Message();
msg.what = TOAST;
msg.obj = "my toast message";
mHandler.sendMessage(msg);

在您的代码中,它看起来像这样:

public class statuspage extends MapActivity {

// These two lines are for the handler
private static final int TOAST  = 0;
private Handler mHandler = null;

LocationManager locationManager;
MapView mapView;
Criteria criteria;
Location location;
Geocoder gc;
Address address;

String bestProvider;
String LOCATION_SERVICE = "location";
String addressString = "Searching for Nearest Address";
StringBuilder sb;

private MapController mapController;
private MyLocationOverlay myLocation;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.statuspage);

    // Get Mapping Controllers etc //
    mapView = (MapView) findViewById(R.id.mapView);
    mapController = mapView.getController();
    mapController.setZoom(17);
    mapView.setBuiltInZoomControls(true);

    // Add the MyLocationOverlay //
    myLocation = new MyLocationOverlay(this, mapView);
    mapView.getOverlays().add(myLocation);
    myLocation.enableCompass();
    myLocation.enableMyLocation();

    // Animates the map to GPS Position //
    myLocation.runOnFirstFix(new Runnable() {
        @Override
        public void run() {
            mapController.animateTo(myLocation.getMyLocation());

        }
    });

    // Creation of the handler to display Toasts
    if (mHandler == null) {
        mHandler = new Handler() {
        @Override
        public void handleMessage(Message _msg) {
            switch (_msg.what) {
                case TOAST:
                Toast.makeText(ServerTabHost.this, (String)_msg.obj, Toast.LENGTH_LONG).show();
                break;
                default : break;
            }
            super.handleMessage(_msg);
            }
        };
    }
}

@Override
protected boolean isRouteDisplayed() {

    // Location Manager Intiation
    locationManager = (LocationManager) statuspage.this
            .getSystemService(LOCATION_SERVICE);
    criteria = new Criteria();

    // More accurate, GPS fix.
    criteria.setAccuracy(Criteria.ACCURACY_FINE); // More accurate, GPS fix.
    bestProvider = locationManager.getBestProvider(criteria, true);

    location = locationManager.getLastKnownLocation(bestProvider);
    updateWithNewLocation(location);

    locationManager.requestLocationUpdates(bestProvider, 60000, 10,
            locationListener); // 1800000 = 30 Min

    return false;
}

class GeoCoder extends AsyncTask<Void, Void, Void> {

    String lat = "Acquiring";
    String lng = "Acquiring";

    @Override
    protected Void doInBackground(Void... params) {
        if (location != null) {

            /**
             * double latitude = myLocation.getMyLocation().getLatitudeE6();
             * double longitude =
             * myLocation.getMyLocation().getLongitudeE6();
             */

            double latitude = location.getLatitude();
            double longitude = location.getLongitude();

            lat = "" + latitude;
            lng = "" + longitude;

            // gc = new Geocoder(statuspage.this, Locale.getDefault());
            Geocoder gc = new Geocoder(getApplicationContext(),
                    Locale.getDefault());
            try {

                List<Address> addresses = gc.getFromLocation(latitude,
                        longitude, 1);

                sb = new StringBuilder();
                if (addresses != null && addresses.size() > 0) {
                    address = addresses.get(0);

                    int noOfMaxAddressLine = address
                            .getMaxAddressLineIndex();
                    if (noOfMaxAddressLine > 0) {
                        for (int i = 0; i < address
                                .getMaxAddressLineIndex(); i++) {
                            sb.append(address.getAddressLine(i)).append(
                                    "\n");
                        }
                        addressString = sb.toString();

                    }
                }
            } catch (Exception e) {

                addressString = "Sorry, we are trying to find information about this location";
            }

        }
        return null;
    }


    @Override
    protected void onPostExecute(Void result) {

        // Sending the Toast message through the handler
        Message msg = new Message();
    msg.what = TOAST;
    msg.obj = "My toast message";
    mHandler.sendMessage(msg);

        TextView scrollview = (TextView) findViewById(R.id.scrollview);

        // Latitude and Longitude TextView
        TextView etlongitude = (TextView) findViewById(R.id.etlongitude);
        TextView etlatitude = (TextView) findViewById(R.id.etlatitude);

        // TextView to display GeoCoder Address
        scrollview.setGravity(Gravity.CENTER);
        scrollview.setText("Your location:" + "\n"
                + "(Accurate to 500 meters)" + "\n" + (addressString));

        Log.d("Address", (addressString));

        // Latitude and Longitude TextView Display Coordinates //
        etlongitude.setText(lng);
        etlatitude.setText(lat);

        // Log.d("GeoCoder", "In-Task");

        return;
    }

就个人而言,我在一个片段中,所以我必须在宿主活动中创建处理程序,然后将它传递给片段构造函数。

于 2012-05-04T08:47:29.343 回答
0

当您使用异步任务时,您无法在后台更新 UI。不可能从后台的内部线程连接 UI。连接 UI 的唯一方法是使用 onPostExecute()。并使用这个 onPostExecute() 函数更新 UI。尝试从后台发送消息,并通过检查消息在 postexecute 上执行 UI。这肯定会对您有所帮助。

于 2012-05-04T03:48:18.457 回答