1

您好,我正在尝试创建一个应用程序来显示您在设施中的位置。首先我让它告诉我我的经度和纬度。然后我将应用程序的背景设为设施的图片,并在地图顶部制作了一个符号(后来成为代表您所在位置的符号,但起初我只是给它随机数字以将其放置在某个位置地图以确保它有效)。然后,当尝试输入符号的坐标时,它会在应用程序打开时崩溃并强制关闭。我该如何解决?

package com.corey.navigationtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 5; // in Meters
    private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Milliseconds

    protected LocationManager locationManager;
    protected Button retrieveLocationButton;
    protected Button buttonSend;

    Canvas canvas; //Your canvas to draw on
    LinearLayout myLayout; //The layout that holds the surfaceview
    SurfaceView surface;
    SurfaceHolder surfaceHolder;

    public double oldlat = 0;
    public double oldlong = 0;
    public double newlat;
    public double newlong;
    public int count = 0;

    DisplayMetrics metrics = this.getResources().getDisplayMetrics();
    int width = metrics.widthPixels;
    int height = metrics.heightPixels;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        retrieveLocationButton = (Button) findViewById(R.id.retrieve_location_button);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(true);
        criteria.setPowerRequirement(Criteria.POWER_LOW);

        String provider = locationManager.getBestProvider(criteria, true);

        locationManager.requestLocationUpdates(
            provider,
            MINIMUM_TIME_BETWEEN_UPDATES,
            MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
            new MyLocationListener()
        );
        buttonSend = (Button) findViewById(R.id.buttonSend);
        retrieveLocationButton.setOnClickListener(onClickListener);
        buttonSend.setOnClickListener(onClickListener);   
        myLayout = (LinearLayout) findViewById(R.id.myLayout);

        LinearLayout.LayoutParams params_surfaceCanvas = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        surface = new SurfaceView(this);
        surface.setLayoutParams(params_surfaceCanvas);

          //Assign a surfaceholder to the surface
        surfaceHolder = surface.getHolder();

        myLayout.addView(surface);
        canvas = new Canvas();

    }   

    private OnClickListener onClickListener = new OnClickListener () {
        @Override
        public void onClick(final View v) {
            switch(v.getId()) {
                case R.id.buttonSend:
                Location location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
                String phoneNo = "8473027766";
                 String sms = String.format(
                            "Current Location \n Longitude: %1$s \n Latitude: %2$s",
                            location.getLongitude(), location.getLatitude()
                 );
                 try {
                    SmsManager smsManager = SmsManager.getDefault();
                    smsManager.sendTextMessage(phoneNo, null, sms, null, null);
                    Toast.makeText(getApplicationContext(), "SMS Sent!",
                                Toast.LENGTH_SHORT).show();
                 } catch (Exception e) {
                    Toast.makeText(getApplicationContext(),
                        "SMS failed, please try again later!",
                        Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                 }
            break;
            case R.id.retrieve_location_button:             
                    showCurrentLocation();              
            break;
        }

    }
};

protected void showCurrentLocation() {
    Location location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
    if (location != null) {

         String message = String.format(
                "Current Location \n Longitude: %1$s \n Latitude: %2$s",
                location.getLongitude(), location.getLatitude()
         );
         Toast.makeText(MainActivity.this, message,
                Toast.LENGTH_SHORT).show();
    }
}  
private class MyLocationListener implements LocationListener {
    public void onLocationChanged(Location location) {
        newlat = location.getLatitude();
        newlong = location.getLatitude();
        String message1 = String.format(
                "New Location \n Longitude: %1$s \n Latitude: %2$s",
                location.getLongitude(), location.getLatitude()
         );
         Toast.makeText(MainActivity.this, message1,
                Toast.LENGTH_SHORT).show();
        double x;
        double y;
        x = ((newlong - (-81.366553))/.003803)*width;
        y = ((newlat - 41.273816)/.001709)*height;

        if ((newlat < 41.274871 & newlong > -81.3659) & (oldlong < -81.3659 || oldlat > 41.274871)) {
            String phoneNo = "8473027766";
            count++;
            String sms = String.format(
                    "You are behind enemy lines \n Longitude: %1$s \n Latitude: %2$s \n Count: %3$s",
                    location.getLongitude(), location.getLatitude(), count
            );
            try {
                SmsManager smsManager = SmsManager.getDefault();
                smsManager.sendTextMessage(phoneNo, null, sms, null, null);
                Toast.makeText(getApplicationContext(), "SMS Sent!",
                Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(),
                "SMS failed, please try again later!",
                Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }

        }
        onDraw();
        oldlat = newlat;
        oldlong = newlong;    
    }
    public void onStatusChanged(String s, int i, Bundle b) {
        Toast.makeText(MainActivity.this, "Provider status changed",
                Toast.LENGTH_SHORT).show();
    }
    public void onProviderDisabled(String s) {
        Toast.makeText(MainActivity.this,
                "Provider disabled by the user. GPS turned off",
                Toast.LENGTH_SHORT).show();
    }
    public void onProviderEnabled(String s) {
        Toast.makeText(MainActivity.this,
                "Provider enabled by the user. GPS turned on",
                Toast.LENGTH_SHORT).show();
    }
}

public void onDraw() {
    //Starts a thread
    new Thread(new Runnable() {
        public void run() {
            while(true) {
                //Loops until surfaceHolder is valid to use
                if (surfaceHolder.getSurface().isValid()) {
                    Log.i("Drawing","Drawing"); 
                    //Always lock the canvas if you want to draw in surfaceview
                    canvas = surfaceHolder.lockCanvas();

                    Bitmap image2 = BitmapFactory.decodeResource(getResources(), R.drawable.vertical);
                    Bitmap image1 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
                    canvas.drawColor(Color.WHITE); //The background color of the canvas
                    canvas.drawBitmap(image2,0,0, null);                        
                    canvas.drawBitmap(image1, x, y, null);

                    //Don't forget to unlock it after you draw in the surfaceview
                    surfaceHolder.unlockCanvasAndPost(canvas);

                    //breaks the while and end the thread.
                    break;
                }   
            }   
        }
    }).start();
}

日志猫:

02-15 10:18:30.979: D/AndroidRuntime(24227): Shutting down VM
02-15 10:18:30.989: W/dalvikvm(24227): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
02-15 10:18:30.999: E/AndroidRuntime(24227): FATAL EXCEPTION: main
02-15 10:18:30.999: E/AndroidRuntime(24227): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.corey.navigationtest/com.corey.navigationtest.MainActivity}: java.lang.NullPointerException
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1746)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1854)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.ActivityThread.access$1500(ActivityThread.java:135)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1041)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.os.Looper.loop(Looper.java:150)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.ActivityThread.main(ActivityThread.java:4333)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at java.lang.reflect.Method.invokeNative(Native Method)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at java.lang.reflect.Method.invoke(Method.java:507)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at dalvik.system.NativeStart.main(Native Method)
02-15 10:18:30.999: E/AndroidRuntime(24227): Caused by: java.lang.NullPointerException
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.content.ContextWrapper.getResources(ContextWrapper.java:80)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at com.corey.navigationtest.MainActivity.<init>(MainActivity.java:47)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at java.lang.Class.newInstanceImpl(Native Method)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at java.lang.Class.newInstance(Class.java:1409)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.Instrumentation.newActivity(Instrumentation.java:1040)
02-15 10:18:30.999: E/AndroidRuntime(24227):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1738)
02-15 10:18:30.999: E/AndroidRuntime(24227):    ... 11 more
02-15 10:18:36.425: I/Process(24227): Sending signal. PID: 24227 SIG: 9
4

1 回答 1

1

你需要拆分:

DisplayMetrics metrics = this.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;

分成两个块。将以下内容保留为全局语句:

DisplayMetrics metrics;
int width;
int height;

并将以下内容移入 onCreate():

metrics = this.getResources().getDisplayMetrics();
width = metrics.widthPixels;
height = metrics.heightPixels;

您收到错误是因为您getResources()在初始化 Activity 之前调用,导致 NullPointerException。

于 2013-02-15T15:45:31.623 回答