package com.yydcdut.note.presenters.service.impl; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Rect; import android.graphics.YuvImage; import android.media.ExifInterface; import android.os.Handler; import android.os.Message; import com.yydcdut.note.entity.PhotoNote; import com.yydcdut.note.entity.SandExif; import com.yydcdut.note.entity.SandPhoto; import com.yydcdut.note.model.rx.RxPhotoNote; import com.yydcdut.note.model.rx.RxSandBox; import com.yydcdut.note.presenters.service.ISandBoxServicePresenter; import com.yydcdut.note.utils.Const; import com.yydcdut.note.utils.FilePathUtils; import com.yydcdut.note.utils.Utils; import com.yydcdut.note.utils.YLog; import com.yydcdut.note.views.IView; import com.yydcdut.note.views.service.ISandBoxServiceView; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import javax.inject.Inject; import rx.Observable; /** * Created by yuyidong on 15/11/22. * //todo OOM */ public class SandBoxServicePresenterImpl implements ISandBoxServicePresenter { private static final String TAG = SandBoxServicePresenterImpl.class.getSimpleName(); private ISandBoxServiceView mSandBoxServiceView; private RxPhotoNote mRxPhotoNote; private RxSandBox mRxSandBox; private Handler mHandler; @Inject public SandBoxServicePresenterImpl(RxSandBox rxSandBox, RxPhotoNote rxPhotoNote) { mRxPhotoNote = rxPhotoNote; mRxSandBox = rxSandBox; } @Override public Context getContext() { return null; } @Override public void attachView(IView iView) { mSandBoxServiceView = (ISandBoxServiceView) iView; mSandBoxServiceView.notification(); mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); finishSandBoxService(); } }; mRxSandBox.findAll() .flatMap(sandPhotos -> Observable.from(sandPhotos)) .subscribe((sandPhoto -> makePhoto(sandPhoto)), (throwable -> YLog.e(throwable)), (() -> mHandler.sendEmptyMessageDelayed(0, 4000))); } /** * 做图 * * @param sandPhoto */ private void makePhoto(SandPhoto sandPhoto) { byte[] rowData = getDataFromFile(sandPhoto.getFileName(), sandPhoto.getSize()); if (rowData == null) { return; } byte[] data; if (sandPhoto.getImageFormat() == ImageFormat.JPEG) { data = rowData; } else { data = decodeNV21(rowData, sandPhoto.getSandExif().getImageWidth(), sandPhoto.getSandExif().getImageLength()); } if (data == null) { return; } Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); } catch (OutOfMemoryError e) { YLog.e(e); } String fileName = sandPhoto.getTime() + ".jpg"; if (FilePathUtils.savePhoto(fileName, bitmap)) { FilePathUtils.saveSmallPhoto(fileName, bitmap); } PhotoNote photoNote = new PhotoNote(fileName, sandPhoto.getTime(), sandPhoto.getTime(), "", "", sandPhoto.getTime(), sandPhoto.getTime(), sandPhoto.getCategoryId()); photoNote.setPaletteColor(Utils.getPaletteColor(bitmap)); mRxPhotoNote.savePhotoNote(photoNote).subscribe(photoNote1 -> { }, (throwable -> YLog.e(throwable))); try { setExif(photoNote, sandPhoto.getSandExif(), sandPhoto.getCameraId(), sandPhoto.isMirror()); } catch (IOException e) { YLog.e(e); } deleteFromDBAndSDCard(sandPhoto); // bitmap.recycle(); System.gc(); } private byte[] decodeNV21(byte[] data, int width, int height) { YuvImage yuv = new YuvImage(data, ImageFormat.NV21, width, height, null); ByteArrayOutputStream bos = new ByteArrayOutputStream(); yuv.compressToJpeg(new Rect(0, 0, width, height), 100, bos); byte[] bytes = bos.toByteArray(); FilePathUtils.closeStream(bos); return bytes; } //todo isMirror不好做啊! private void setExif(PhotoNote photoNote, SandExif sandExif, String cameraId, boolean isMirror) throws IOException { ExifInterface exif = new ExifInterface(photoNote.getBigPhotoPathWithoutFile()); if (cameraId.equals(Const.CAMERA_BACK)) { exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90)); } else { exif.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_270)); } exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, sandExif.getLatitude()); exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, sandExif.getLongitude()); exif.setAttribute(ExifInterface.TAG_WHITE_BALANCE, String.valueOf(sandExif.getWhiteBalance())); exif.setAttribute(ExifInterface.TAG_FLASH, String.valueOf(sandExif.getFlash())); exif.setAttribute(ExifInterface.TAG_IMAGE_LENGTH, String.valueOf(sandExif.getImageLength())); exif.setAttribute(ExifInterface.TAG_IMAGE_WIDTH, String.valueOf(sandExif.getImageWidth())); exif.setAttribute(ExifInterface.TAG_MAKE, sandExif.getMake()); exif.setAttribute(ExifInterface.TAG_MODEL, sandExif.getModel()); exif.saveAttributes(); ExifInterface exif2 = new ExifInterface(photoNote.getSmallPhotoPathWithoutFile()); if (cameraId.equals(Const.CAMERA_BACK)) { exif2.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90)); } else { exif2.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_270)); } exif2.saveAttributes(); } private byte[] getDataFromFile(String fileName, int size) { boolean bool = true; File file = new File(FilePathUtils.getSandBoxDir() + fileName); byte[] data; if (!file.exists()) { return null; } data = new byte[size]; InputStream inputStream = null; try { inputStream = new FileInputStream(file); inputStream.read(data); } catch (FileNotFoundException e) { YLog.e(e); bool = false; } catch (IOException e) { YLog.e(e); bool = false; } finally { FilePathUtils.closeStream(inputStream); } if (!bool) { return null; } else { return data; } } /** * 从数据库中删数据 * * @param sandPhoto * @return */ private void deleteFromDBAndSDCard(SandPhoto sandPhoto) { String path = FilePathUtils.getSandBoxDir() + sandPhoto.getFileName(); mRxSandBox.deleteOne(sandPhoto) .subscribe(integer -> new File(path).delete(), (throwable -> YLog.e(throwable))); } @Override public void detachView() { } private void finishSandBoxService() { mSandBoxServiceView.sendBroadCast(); mSandBoxServiceView.cancelNotification(); mSandBoxServiceView.stopService(); mSandBoxServiceView.killProgress(); } }