Функции рисования холста не работают после блокировки экрана и разблокировки

Я работаю над приложением дополненной реальности, в котором у меня есть экран предварительного просмотра камеры, на котором я рисую некоторые маркеры, которые перемещаются относительно движения устройства.

Когда я 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 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);
        }


   }
  }

Ответ 1

Я решил проблему. Это было с моим SensorManager. SensorManager имеет значение null, когда выполняется onStart(). Я инициализировал его внутри onStart() и разрешил его.