android - 永远每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,但错误仍然存在。当错误发生时,应用程序继续运行(也是相机预览),但没有发送图像(有允许执行应用程序的尝试捕获)但是当我按下手机上的“返回”按钮时,应用程序根本没有响应。
解决方案
推荐阅读
- python - 如何从 pyjet 导入编译而不会出现编译错误?
- powershell - Powershell 错误提示库不可用稍后再试
- python - 在 SQL 中存储 struct_time
- java - 如果数据库中没有数据,则 REST API java 类设置 setter getter 的初始值
- python - Scikit skimage regionprops 获取连接区域(python)
- python - Python(字符串):使用保存在 DataFrame 单元格中的字符串作为熊猫公式
- sql - COALESCE 类型 jsonb 和 boolean 无法匹配
- kotlin - 在 Kotlin 中使用来自不同上下文的扩展函数
- c# - 如何使用 linq 绑定枚举类
- ios - watchOS 7 中不再更新的并发症