2016-04-24 3 views
0

В настоящее время я использую API Google Mobile Vision для обнаружения лиц. Предположительно, после поворота экрана активность будет перезапущена, и все переменные будут повторно инициализированы. Однако я не знаю, почему приложение перестает работать и показывает NullPointerException. Вот мои коды.Android перестает работать после вращения экрана

public class MainActivity extends AppCompatActivity { 

    private ImageView mIvDetected; 
    private Bitmap mImage; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mIvDetected = (ImageView) findViewById(R.id.iv_detected); 

     //Load an image 
     BitmapFactory.Options opts = new BitmapFactory.Options(); 
     opts.inMutable = true; 
     mImage = BitmapFactory.decodeResource(getResources(), R.drawable.face2); 

     //Configure FaceDetector 
     FaceDetector detector = new FaceDetector.Builder(this) 
       .setMode(FaceDetector.ACCURATE_MODE) 
       .setLandmarkType(FaceDetector.ALL_LANDMARKS) 
       .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS) 
       .setTrackingEnabled(false) 
       .build(); 

     if(false == detector.isOperational()){ 
      Toast.makeText(this, "Face detection service is not ready", Toast.LENGTH_SHORT).show(); 
      return; 
     } 

     //Add the image on a Frame object 
     Frame frame = new Frame.Builder().setBitmap(mImage).build(); 

     //Detect all faces from Frame object 
     SparseArray<Face> faceArray = detector.detect(frame); 

     //Do some drawing on faces 
     **Bitmap outBitmap = drawOnFace(faceArray);** 
     mIvDetected.setImageBitmap(outBitmap); 

     //Releasing the detector object 
     detector.release(); 
    } 

    /** Method to do some drawing on faces */ 
    private Bitmap drawOnFace(SparseArray<Face> faceArray){ 

     Paint mIdPaint = new Paint(); 
     mIdPaint.setColor(Color.RED); 
     mIdPaint.setTextSize(40.f); 

     Paint paint = new Paint(); 
     paint.setColor(Color.RED); 
     paint.setStrokeWidth(5); 
     paint.setStyle(Paint.Style.STROKE); 

     Paint mTextPaint = new Paint(); 
     mTextPaint.setAntiAlias(true); 
     mTextPaint.setDither(true); 
     mTextPaint.setTextSize(20); 
     mTextPaint.setColor(Color.GREEN); 
     mTextPaint.setStyle(Paint.Style.FILL); 

     // Create a blank bitmap same size with the source image 
     Bitmap outBitmap = Bitmap.createBitmap(mImage.getWidth(), mImage.getHeight(), Bitmap.Config.RGB_565); 

     // Put the bitmap on canvas for drawing 
     Canvas canvas = new Canvas(outBitmap); 
     canvas.drawBitmap(mImage, 0, 0, null); 

     for(int i=0; i < faceArray.size(); i++){ 
      Face face = faceArray.get(i); 

      //Drawing rectangle on each face 
      **drawRectangle(canvas, face.getPosition(), face.getWidth(), face.getHeight());** 

      //Drawing a point on each face features 
      for(Landmark landmark : face.getLandmarks()) { 
       switch (landmark.getType()){ 
        case Landmark.LEFT_EYE: 
         drawPoint(canvas, landmark.getPosition()); 
         canvas.drawText("Left eye: " + face.getIsLeftEyeOpenProbability(), landmark.getPosition().x, landmark.getPosition().y - 30, mTextPaint); 
         break; 
        case Landmark.RIGHT_EYE: 
         drawPoint(canvas, landmark.getPosition()); 
         canvas.drawText("Right eye: " + face.getIsRightEyeOpenProbability(), landmark.getPosition().x, landmark.getPosition().y - 30, mTextPaint); 
         break; 
        case Landmark.BOTTOM_MOUTH: 
         drawPoint(canvas, landmark.getPosition()); 
         canvas.drawText("Smile: " + face.getIsSmilingProbability(), landmark.getPosition().x, landmark.getPosition().y + 40, mTextPaint); 
         break; 
        case Landmark.LEFT_MOUTH: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.RIGHT_MOUTH: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.NOSE_BASE: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.LEFT_CHEEK: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.RIGHT_CHEEK: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.LEFT_EAR: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.LEFT_EAR_TIP: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.RIGHT_EAR: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
        case Landmark.RIGHT_EAR_TIP: 
         drawPoint(canvas, landmark.getPosition()); 
         break; 
       } 
      } 

      /** Other useful details that may be of your interest */ 
      Log.d("", "FaceDetection- FaceId:" + face.getId() 
        + " Smiling:" + face.getIsSmilingProbability() 
        + " LeftEyeOpen:" + face.getIsLeftEyeOpenProbability() 
        + " RightEyeOpen:" + face.getIsRightEyeOpenProbability()); 


     } 

     return outBitmap; 
    } 

    /** This method draws a rectangle */ 
    private void drawRectangle(Canvas canvas, PointF point, float width, float height){ 
     Paint paint = new Paint(); 
     paint.setColor(Color.RED); 
     paint.setStrokeWidth(5); 
     paint.setStyle(Paint.Style.STROKE); 

     float x1 = point.x; 
     float y1 = point.y; 
     float x2 = x1 + width; 
     float y2 = y1 + height; 

     RectF rect = new RectF(x1, y1, x2, y2); 
     canvas.drawRect(rect, paint); 
    } 

    /** This method draws a point with hole */ 
    private void drawPoint(Canvas canvas, PointF point){ 
     Paint paint = new Paint(); 
     paint.setColor(Color.RED); 
     paint.setStrokeWidth(48); 
     paint.setStyle(Paint.Style.STROKE); 

     float x = point.x; 
     float y = point.y; 

     canvas.drawCircle(x, y, 1, paint); 
    } 
} 

Вот мои ошибки.

04-24 12: 59: 50,231 2865-2865/com.example.andy318.cameraone Е/AndroidRuntime: неустранимый: Основной процесс: com.example.andy318.cameraone, ПИД: 2865 Java. lang.RuntimeException: невозможно возобновить действие {com.example.andy318.cameraone/com.example.andy318.cameraone.MainActivity}: java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.graphics.PointF com.google.android .gms.vision.face.Face.getPosition() 'на ссылке нулевого объекта на android.app.ActivityThread.performResumeActivity (ActivityThread.java:3103) на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3134) на android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2481) в android.app.ActivityThread.handleRelaunchActivity (ActivityThread.java:4077) в android.app.ActivityThread.-wrap15 (ActivityThread.java) на андроид .app.ActivityThread $ H.handleMessage (ActivityThread.java:1350) на android.os.Handler.dispatchMessage (Handler.java:102) на android.os.Looper.loop (Looper.java:148) на android .app.ActivityThread.main (ActivityThread.java:5417) at java.lang.reflect.Method.invoke (собственный метод) at com.android.internal.os.ZygoteInit $ Метод AndArgsCaller.run (ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616) Вызвано: java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.graphics. PointF com.google.android.gms.vision.face.Face.getPosition() 'на ссылке нулевого объекта на com.example.andy318.cameraone.MainActivity.drawOnFace (MainActivity.java:106) на com.example. andy318.cameraone.MainActivity.onResume (MainActivity.java:69) на android.app.Instrumentation.callActivityOnResume (Instrumentation.java:1258) на android.app.Activity.performResume (Activity.java:6312) на android. app.ActivityThread.performResumeActivity (Acti vityThread.java:3092) на android.app.ActivityThread.handleResumeActivity (ActivityThread.java:3134) в android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2481) в android.app.ActivityThread.handleRelaunchActivity (ActivityThread. java: 4077) на android.app.ActivityThread.-wrap15 (ActivityThread.java) на android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1350) на android.os.Handler.dispatchMessage (Handler.java : 102) на android.os.Looper.loop (Looper.java:148) на android.app.ActivityThread.main (ActivityThread.java:5417) по адресу java.lang.reflect.Method.invoke (собственный метод) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main (ZygoteInit.Java: 616)

Ошибки происходят на

Bitmap outBitmap = drawOnFace (faceArray);

и

DrawRectangle (холст, face.getPosition(), face.getWidth(), face.getHeight());

который я положил ** в кодировке.

Я знаю, где моя ошибка, но я знаю, как ее решить. После поворота экрана SparseArray faceArray имеет нулевое значение. Я попытался использовать, если проверить нулевое состояние, но не обнаружил бы обнаружение. (Показывать только оригинальное изображение)

+0

Возможный дубликат [Что такое исключение нулевого указателя, и как это исправить это?] (http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) –

+0

Вы получаете только ключ, а не объект: http://stackoverflow.com/a/8006994/6247492 – user6247492

ответ

0

java.lang.NullPointerException: Попытка вызвать виртуальный метод «Face.getPosition()» на нулевой ссылки на объект

переменная лицо является недействительным!

http://developer.android.com/reference/android/media/FaceDetector.html

, где вы получите обнаружить() из? nvm, нашел это: https://developers.google.com/android/reference/com/google/android/gms/vision/face/FaceDetector.html#public-methods

Возможно, вам нужно сделать окончательный вариант SparseArray или все лица внутри или что-то в этом роде?