2015-11-25 37 views
11

我正在製作一個增強現實應用程序,其中我有一個相機預覽屏幕,在該屏幕上繪製了與設備移動相關的一些標記。屏幕鎖定和解鎖後,畫布繪製功能無法正常工作

當我lock and unlock該設備,標記凍結,並不會進一步移動。我無法找到發生這種情況的原因。是否有任何可能的解決方法?任何幫助將不勝感激。

我SurfaceView類:

public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback 
    { 
    private static SurfaceHolder holder = null; 
    public static Camera camera = null; 
    Activity ctx; 

    public CameraSurface(Activity context) { 
     super(context); 
     ctx=context; 

     try { 
      holder = getHolder(); 
      holder.addCallback(this); 
      holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public CameraSurface(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 

    } 

    public CameraSurface(Context context, AttributeSet attrs) { 
     super(context, attrs); 

    } 


    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     try { 
      if (camera != null) { 
       try { 
        camera.stopPreview(); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
       try { 
        camera.release(); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
       camera = null; 
      } 

      camera = Camera.open(); 
      setCamFocusMode(); 
      camera.setPreviewDisplay(holder); 
     } catch (Exception ex) { 
      try { 
       if (camera != null) { 
        try { 
         camera.stopPreview(); 
        } catch (Exception ex1) { 
         ex.printStackTrace(); 
        } 
        try { 
         camera.release(); 
        } catch (Exception ex2) { 
         ex.printStackTrace(); 
        } 
        camera = null; 
       } 
      } catch (Exception ex3) { 
       ex.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     try { 
      if (camera != null) { 
       try { 
        camera.stopPreview(); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
       try { 
        camera.release(); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
       camera = null; 
      } 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {   
     if (camera==null) 
      return; 
     try { 
      final Camera.Parameters parameters = camera.getParameters(); 
      try { 
       List<Camera.Size> supportedSizes = null; 
       // On older devices (<1.6) the following will fail 
       // the camera will work nevertheless 
       supportedSizes = CameraCompatibility.getSupportedPreviewSizes(parameters); 

       // preview form factor 
       float ff = (float) w/h; 

       // holder for the best form factor and size 
       float bff = 0; 
       int bestw = 0; 
       int besth = 0; 
       Iterator<Camera.Size> itr = supportedSizes.iterator(); 

       // we look for the best preview size, it has to be the closest 
       // to the 
       // screen form factor, and be less wide than the screen itself     
       while (itr.hasNext()) { 
        Camera.Size element = itr.next(); 
        // current form factor 
        float cff = (float) element.width/element.height; 
        // check if the current element is a candidate to replace 
        // the best match so far 
        // current form factor should be closer to the bff 
        // preview width should be less than screen width 
        // preview width should be more than current bestw 
        // this combination will ensure that the highest resolution 
        // will win 
        if ((ff - cff <= ff - bff) && (element.width <= w) && (element.width >= bestw)) { 
         bff = cff; 
         bestw = element.width; 
         besth = element.height; 
        } 
       } 
       // Some Samsung phones will end up with bestw and besth = 0 
       // because their minimum preview size is bigger then the screen 
       // size. 
       // In this case, we use the default values: 480x320 
       if ((bestw == 0) || (besth == 0)) { 
        bestw = 480; 
        besth = 320; 
       } 
       parameters.setPreviewSize(bestw, besth);     
      } catch (Exception ex) { 
       parameters.setPreviewSize(480, 320); 
      } 
      /// 
      android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); 

      android.hardware.Camera.getCameraInfo(0, info); 

      int rotation = ctx.getWindowManager().getDefaultDisplay() 
        .getRotation(); 

      int degrees = 0; 
      switch (rotation) { 
      case Surface.ROTATION_0: 
       degrees = 0; 
       break; 
      case Surface.ROTATION_90: 
       degrees = 90; 
       break; 
      case Surface.ROTATION_180: 
       degrees = 180; 
       break; 
      case Surface.ROTATION_270: 
       degrees = 270; 
       break; 
      } 

      int result; 
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
       result = (info.orientation + degrees) % 360; 
       result = (360 - result) % 360; 
       // compensate the mirror 
      } else { 
       // back-facing 
       result = (info.orientation - degrees + 360) % 360; 
      } 
      camera.setDisplayOrientation(result); 

      camera.setParameters(parameters); 
      camera.startPreview(); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private void setCamFocusMode(){ 

     if(null == camera) { 
      return; 
     } 

     /* Set Auto focus */ 
     Parameters parameters = camera.getParameters(); 
     List<String> focusModes = parameters.getSupportedFocusModes(); 
     if(focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ 
      parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);  
     } else 
     if(focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)){ 
      parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
     }  

     camera.setParameters(parameters); 
    } 
} 

AugmentedView.java: //這個類繪製攝像頭預覽畫面

/** 
* This class extends the View class and is designed draw the zoom bar, radar 
* circle, and markers on the View. 
* 
*/ 
public class AugmentedView extends View { 

    private static final String TAG = "AugmentedView"; 
    private static final AtomicBoolean drawing = new AtomicBoolean(false); 
    private static final Radar radar = new Radar(); 
    private static final float[] locationArray = new float[3]; 
    private static final List<Marker> cache = new ArrayList<Marker>(); 
    private static final Set<Marker> updated = new HashSet<Marker>(); 

    public AugmentedView(Context context) { 

     super(context); 
     Log.v(TAG, "portrait    = "+CameraPreviewFragment.ui_portrait); 
     Log.v(TAG, "useCollisionDetection = "+CameraPreviewFragment.useCollisionDetection); 
     Log.v(TAG, "useSmoothing   = "+CameraPreviewFragment.useDataSmoothing); 
     Log.v(TAG, "showRadar    = "+CameraPreviewFragment.showRadar); 
     Log.v(TAG, "showZoomBar   = "+CameraPreviewFragment.showZoomBar);  
     //radar = new Radar(context); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    protected void onDraw(Canvas canvas) { 
     if (canvas == null) return; 

     if (drawing.compareAndSet(false, true)) { 
      //Log.v(TAG, "DIRTY flag found, re-populating the cache."); 

      // Get all the markers 
      List<Marker> collection = ARData.getMarkers(); 

      // Prune all the markers that are out of the radar's radius (speeds 
      // up drawing and collision detection) 
      cache.clear(); 
      for (Marker m : collection) { 
       m.update(canvas, 0, 0); 
       if (m.isOnRadar() && m.isInView()&& m.isMarkerToBeShown()) cache.add(m); 
      } 
      /*//Draw only 10 markers 
      if(cache.size()>10) 
       collection = cache.subList(0, 10); 
      else*/ 
       collection = cache; 
      if (CameraPreviewFragment.useCollisionDetection) 
       adjustForCollisions(canvas, collection); 

      // Draw AR markers in reverse order since the last drawn should be 
      // the closest 
      ListIterator<Marker> iter = collection.listIterator(collection.size()); 

      while (iter.hasPrevious()) { 
       Marker marker = iter.previous(); 
       marker.draw(canvas); 
      } 

      // Radar circle and radar markers 
      if (CameraPreviewFragment.showRadar) 
       radar.draw(canvas); 
      drawing.set(false); 
     } 
    } 

    private static void adjustForCollisions(Canvas canvas, List<Marker> collection) { 
     updated.clear(); 

     // Update the AR markers for collisions 
     for (int i=0; i<collection.size(); i++) { 
      Marker marker1 = collection.get(i); 
      if (!marker1.isInView()) { 
       updated.add(marker1); 
       continue; 
      } 
      if (updated.contains(marker1)) 
       continue; 

      int collisions = 1; 
      for (int j=i+1; j<collection.size(); j++) { 
//    Marker marker2 = collection.get(j); 
       Marker marker2 = collection.get(j); 
       if (!marker2.isInView()) { 
        updated.add(marker2); 
        continue; 
       } 
       if (updated.contains(marker2)) 
        continue; 

       float width = marker1.getWidth(); 
       float height = marker1.getHeight(); 
       float max = Math.max(width, height); 

       if (marker1.isMarkerOnMarker(marker2)) { 
        marker2.getLocation().get(locationArray); 
        float y = locationArray[1]; 
        float h = collisions * max; 
        locationArray[1] = y + h; 
        marker2.getLocation().set(locationArray); 
        marker2.update(canvas, 0, 0); 
        collisions++; 
        updated.add(marker2); 
       } 
      } 
      updated.add(marker1); 
     } 


    } 
    } 
+0

其中是onDraw()方法和畫布? –

+0

這涉及到很多類和代碼。無法在這裏發佈全部。發生問題的原因是否有可能? – Jas

+0

如果沒有看到其他代碼,我不能告訴你。至少包含onDraw()方法的類 –

回答

6

上的標記我解決了問題。這是我的SensorManager。當onStart()被執行時,SensorManager爲空。我在onStart()裏初始化它並解決它。