4

我尝试使用 GPS 制作一个用于地理定位的 Android 应用程序,但是当我运行模拟器时,我收到此消息:appname HAS unfortunately stopped.为什么会收到此消息?我的代码没有错误。

我的.java:

package com.android.geolocalisation3;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;

import android.os.Bundle;

import android.view.KeyEvent;
import android.view.Menu;

import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class Geo3MainActivity extends MapActivity implements LocationListener {

    private MapView mapView;
    private MapController mc;

    private LocationManager lm;

    private double latitude=122;
    private double longitude=37;
    private double altitude=0;
    private float accuracy=0;

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

        mapView = (MapView) this.findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);

        mc = mapView.getController();
        mc.setZoom(17);
    }

    @Override
    protected void onResume() {
        super.onResume();
        lm = (LocationManager) this.getSystemService(LOCATION_SERVICE);
        if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER))
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0,
                    this);
        lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0,
                this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        lm.removeUpdates(this);
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            mapView.setSatellite(true);
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            mapView.setSatellite(false);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_geo3_main, menu);
        return true;
    }

    @Override
    public void onLocationChanged(Location location) {

        //altitude = location.getAltitude();
        ///accuracy = location.getAccuracy();

        String msg = String.format(
                getResources().getString(R.string.new_location), latitude,
                longitude, altitude, accuracy);
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();

        GeoPoint p = new GeoPoint((int) (latitude * 1E6), (int) (longitude * 1E6));
        mc.animateTo(p);
        mc.setCenter(p);
    }

    @Override
    public void onProviderDisabled(String provider) {
        String msg = String.format(
                getResources().getString(R.string.provider_disabled), provider);
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderEnabled(String provider) {
        String msg = String.format(
                getResources().getString(R.string.provider_enabled), provider);
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        String newStatus = "";
        switch (status) {
        case LocationProvider.OUT_OF_SERVICE:
            newStatus = "OUT_OF_SERVICE";
            break;
        case LocationProvider.TEMPORARILY_UNAVAILABLE:
            newStatus = "TEMPORARILY_UNAVAILABLE";
            break;
        case LocationProvider.AVAILABLE:
            newStatus = "AVAILABLE";
            break;
        }
        String msg = String.format(
                getResources().getString(R.string.provider_disabled), provider,
                newStatus);
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
}

我的日志错误:

07-28 00:00:01.054: E/StrictMode(621): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
07-28 00:00:01.054: E/StrictMode(621): java.lang.Throwable: Explicit termination method 'close' not called
07-28 00:00:01.054: E/StrictMode(621):  at dalvik.system.CloseGuard.open(CloseGuard.java:184)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.CursorWindow.<init>(CursorWindow.java:137)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.CursorWindow.<init>(CursorWindow.java:41)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.CursorWindow$1.createFromParcel(CursorWindow.java:681)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.CursorWindow$1.createFromParcel(CursorWindow.java:679)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.BulkCursorDescriptor.readFromParcel(BulkCursorDescriptor.java:75)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.BulkCursorDescriptor$1.createFromParcel(BulkCursorDescriptor.java:34)
07-28 00:00:01.054: E/StrictMode(621):  at android.database.BulkCursorDescriptor$1.createFromParcel(BulkCursorDescriptor.java:30)
07-28 00:00:01.054: E/StrictMode(621):  at android.content.ContentProviderProxy.query(ContentProviderNative.java:369)
07-28 00:00:01.054: E/StrictMode(621):  at android.content.ContentResolver.query(ContentResolver.java:370)
07-28 00:00:01.054: E/StrictMode(621):  at android.content.CursorLoader.loadInBackground(CursorLoader.java:65
07-28 00:00:01.054: E/StrictMode(621):  at android.content.CursorLoader.loadInBackground(CursorLoader.java:43)
07-28 00:00:01.054: E/StrictMode(621):  at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:301)
07-28 00:00:01.054: E/StrictMode(621):  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:68)
07-28 00:00:01.054: E/StrictMode(621):  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:56)
07-28 00:00:01.054: E/StrictMode(621):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-28 00:00:01.054: E/StrictMode(621):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-28 00:00:01.054: E/StrictMode(621):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-28 00:00:01.054: E/StrictMode(621):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-28 00:00:01.054: E/StrictMode(621):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-28 00:00:01.054: E/StrictMode(621):  at java.lang.Thread.run(Thread.java:856)
07-28 00:00:01.144: E/StrictMode(621): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
07-28 00:00:01.144: E/StrictMode(621): java.lang.Throwable: Explicit termination method 'close' not called
07-28 00:00:01.144: E/StrictMode(621):  at dalvik.system.CloseGuard.open(CloseGuard.java:184)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.ContentResolver$CursorWrapperInner.<init>(ContentResolver.java:1835)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.ContentResolver.query(ContentResolver.java:392)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.CursorLoader.loadInBackground(CursorLoader.java:65)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.CursorLoader.loadInBackground(CursorLoader.java:43)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:301)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:68)
07-28 00:00:01.144: E/StrictMode(621):  at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:56)
07-28 00:00:01.144: E/StrictMode(621):  at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-28 00:00:01.144: E/StrictMode(621):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-28 00:00:01.144: E/StrictMode(621):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-28 00:00:01.144: E/StrictMode(621):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-28 00:00:01.144: E/StrictMode(621):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-28 00:00:01.144: E/StrictMode(621):  at java.lang.Thread.run(Thread.java:856)
07-28 00:00:45.364: E/PowerManagerService(157): Excessive delay setting brightness: 144ms, mask=2
07-28 00:00:45.544: E/PowerManagerService(157): Excessive delay setting brightness: 139ms, mask=2
07-28 00:00:45.764: E/PowerManagerService(157): Excessive delay setting brightness: 211ms, mask=2
07-28 00:00:45.994: E/PowerManagerService(157): Excessive delay setting brightness: 224ms, mask=2
07-28 00:05:21.293: E/ThrottleService(157): problem during onPollAlarm: java.lang.IllegalStateException: problem parsing stats: java.io.FileNotFoundException: /proc/net/xt_qtaguid/iface_stat_all: open failed: ENOENT (No such file or directory)
4

2 回答 2

3

Somehow the formatting of your log messages was lost, making them very hard to read.

The first lines of the log messages give the clue:

07-28 00:00:01.054: E/StrictMode(621): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
07-28 00:00:01.054: E/StrictMode(621): java.lang.Throwable: Explicit termination method 'close' not called

Certain objects such as files or cursors need to be explicitly closed. Simply dropping the reference to them isn't good enough. Failing to close the object causes a resource leak, which the system detects and reacts to by killing your app.

Unfortunately, the stack trace only shows you where the leak was detected, not what originally caused it.

Are there parts of your code you're not showing us that relate to databases? The log messages indicate a problem with a Cursor object.

Assuming you are using databases, look into your database access code and make SURE you close every cursor and database you open. Make sure all 'return' statements in your database-handling functions close the relevant objects before returning. Make sure you catch all possible exceptions and close your cursor objects before letting the exception go up the stack. I make liberal use of finally{} blocks for this.

My database code typically looks like this:

protected DbRec findById(String ident) {
    DbRec rval;
    Cursor cursor = null;
    try {
        if( (cursor = findCursorById(ident)) == null )
            return null;
        rval = newRecord();
        rval.fillFromCursor(cursor);
    } catch (Exception e) {
        Log.w(TAG, "Failed to read database record: " + e);
        rval = null;
    } finally {
        if( cursor != null ) cursor.close();
    }
    return rval;
}

ETA: I've taken the liberty of pasting the log messages from your comments:

E/AndroidRuntime(808): java.lang.RuntimeException: Unable to resume activity {com.android.geolocalisation3/com.android.geolocalisation3.Geo3MainActivity}: java.lang.IllegalArgumentException: requested provider network doesn't exisit
E/AndroidRuntime(808): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)
E/AndroidRuntime(808): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
E/AndroidRuntime(808): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
E/AndroidRuntime(808): at android.app.ActivityThread.access$600(ActivityThread.java:130)
E/AndroidRuntime(808): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
E/AndroidRuntime(808): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(808): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(808): at android.app.ActivityThread.main(ActivityThread.java:4745)
E/AndroidRuntime(808): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(808): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(808): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
E/AndroidRuntime(808): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
E/AndroidRuntime(808): at dalvik.system.NativeStart.main(Native Method)

E/AndroidRuntime(808): Caused by: java.lang.IllegalArgumentException: requested provider network doesn't exisit
E/AndroidRuntime(808): at android.os.Parcel.readException(Parcel.java:1429)
E/AndroidRuntime(808): at android.os.Parcel.readException(Parcel.java:1379)
E/AndroidRuntime(808): at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:646)
E/AndroidRuntime(808): at android.location.LocationManager._requestLocationUpdates(LocationManager.java:660)
E/AndroidRuntime(808): at android.location.LocationManager.requestLocationUpdates(LocationManager.java:482)
E/AndroidRuntime(808): at com.android.geolocalisation3.Geo3MainActivity.onResume(Geo3MainActivity.java:49)
E/AndroidRuntime(808): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
E/AndroidRuntime(808): at android.app.Activity.performResume(Activity.java:5082)
E/AndroidRuntime(808): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)
E/AndroidRuntime(808): ... 12 more

This is a different error than before. It looks like the name of the location provider (e.g. "gps" was saved wrong in onSaveInstanceState() which caused a crash when the application restarted.

于 2012-07-28T01:44:11.627 回答
0

由于某种原因,API 级别 16 的模拟器无法注册 NETWORK_PROVIDER 侦听器。它在 10 级模拟器中运行良好。我没有测试任何其他 SDK 版本。

我刚刚添加了对网络提供商可用性的检查以避免此问题。您已经为 GPS 提供商做到了。

if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER))

我希望这有帮助。

Ĵ

于 2012-08-22T13:02:59.297 回答