首页 > 解决方案 > 永远每20秒拍一张照片

问题描述

我有一台旧的 Android 设备(Android 4.1.2,API 16),我想将其用作“类似 CCTV”的设备。我需要每 20 秒拍一张照片,为此我在 Activity 上实现了以下代码。onCreate() 方法如下:

//To keep the display on (the phone is always attached to the power supply)  
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

FrameLayout preview = findViewById(R.id.camera_preview);

initializeCamera();

Timer timerPhoto = new Timer();
timerPhoto.schedule(new TimerTask() {
            @Override
            public void run() {
               mCamera.takePicture(null, null, mPictureCallback);
               mCamera.startPreview();
            }
        }, 5000, 20000); //start after 5 seconds, take pic every 20 secs

相机初始化方法如下:

private void initializeCamera() {
        if (mCamera == null) {
            mCamera = getCameraInstance();
            Timber.d("Camera initialized");
        }
        mCameraPreview = new IaCameraHelper(this, mCamera);
        preview.addView(mCameraPreview);
    }

这是处理图片的回调:

 private static Bitmap originalPhotoBitmap = null;

 Camera.PictureCallback mPictureCallback = (data, camera) -> {
        originalPhotoBitmap = addDateTimeToImage(rotateBitmap(BitmapFactory.decodeByteArray(data, 0, data.length), 180));

        //Sending the bitmap string to the server
        controller.sendImage(bitmapToString(originalPhotoBitmap));

        originalPhotoBitmap.recycle();
        BitmapManager.rotatedBitmap.recycle();
        BitmapManager.modBitmap.recycle();

        originalPhotoBitmap = null;
        BitmapManager.rotatedBitmap = null;
        BitmapManager.modBitmap = null;

 };

在 BitmapManager 中,我有以下用于操作位图的方法:

public static Bitmap rotatedBitmap = null;
public static Bitmap modBitmap = null;

public static Bitmap rotateBitmap(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    rotatedBitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
    return rotatedBitmap;
}

public static Bitmap addDateTimeToImage(Bitmap originalPhoto) {

    modBitmap = Bitmap.createBitmap(originalPhoto.getWidth(), originalPhoto.getHeight(), Bitmap.Config.ARGB_8888);
    String dateTime = sdf.format(Calendar.getInstance().getTime());
    Canvas cs = new Canvas(modBitmap);
    Paint tPaint = new Paint();
    tPaint.setTextSize(30);
    tPaint.setColor(Color.RED);
    tPaint.setStyle(Paint.Style.FILL);
    cs.drawBitmap(originalPhoto, 0f, 0f, null);
    float height = tPaint.measureText("yY");
    cs.drawText(dateTime, 20f, height + 15f, tPaint);
    return modBitmap;
}

public static String bitmapToString(Bitmap bitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
    byte[] b = baos.toByteArray();
    return Base64.encodeToString(b, Base64.DEFAULT);
}

如您所见,我将位图字符串发送到控制器,控制器将图像发送到网络中的本地服务器。通常,该应用程序的工作原理就像一个魅力,但有时(通常在 6-7 小时后)我会遇到以下我不知道如何解决的错误(内存不足)。

02-21 13:12:03.292 29621-29632/com.rbapp E/dalvikvm-heap: Out of memory on a 127547-byte allocation.
02-21 13:12:03.302 29621-29632/com.rbapp E/Camera-JNI: Couldn't allocate byte array for JPEG data

如您所见,我尝试回收所有生成的位图,并在将它们发送到控制器后立即将它们设置为 null,但错误仍然存​​在。当错误发生时,应用程序继续运行(也是相机预览),但没有发送图像(有允许执行应用程序的尝试捕获)但是当我按下手机上的“返回”按钮时,应用程序根本没有响应。

标签: androidbitmapcameraout-of-memory

解决方案


推荐阅读