У меня есть старое устройство 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, как только отправляю их на контроллер, но ошибка сохраняется.Когда возникают ошибки, приложение продолжает работать (также предварительный просмотр камеры), но изображения не отправляются (есть попытки, которые позволяют запускать приложение), но когда я нажимаю кнопку «назад» на телефоне,приложение не отвечает вообще.