/* © 2010 Stephan Reichholf <stephan at reichholf dot net>
*
* Licensed under the Create-Commons Attribution-Noncommercial-Share Alike 3.0 Unported
* http://creativecommons.org/licenses/by-nc-sa/3.0/
*/
package net.reichholf.dreamdroid.fragment;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.ShareActionProvider;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import net.reichholf.dreamdroid.DreamDroid;
import net.reichholf.dreamdroid.R;
import net.reichholf.dreamdroid.fragment.abs.BaseFragment;
import net.reichholf.dreamdroid.fragment.helper.HttpFragmentHelper;
import net.reichholf.dreamdroid.helpers.NameValuePair;
import net.reichholf.dreamdroid.helpers.Statics;
import net.reichholf.dreamdroid.helpers.enigma2.URIStore;
import net.reichholf.dreamdroid.loader.AsyncByteLoader;
import net.reichholf.dreamdroid.loader.LoaderResult;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import uk.co.senab.photoview.PhotoViewAttacher;
/**
* Allows fetching and showing the actual TV-Screen content
*
* @author sre
*/
public class ScreenShotFragment extends BaseFragment implements
LoaderCallbacks<LoaderResult<byte[]>>, SwipeRefreshLayout.OnRefreshListener {
public static final int TYPE_OSD = 0;
public static final int TYPE_VIDEO = 1;
public static final int TYPE_ALL = 2;
public static final int FORMAT_JPG = 0;
public static final int FORMAT_PNG = 1;
public static final String KEY_TYPE = "type";
public static final String KEY_FORMAT = "format";
public static final String KEY_SIZE = "size";
public static final String KEY_FILENAME = "filename";
private static final String BUNDLE_KEY_RETAIN = "retain";
private boolean mSetTitle;
private boolean mActionsEnabled;
private ImageView mImageView;
private int mType;
private int mFormat;
private int mSize;
private String mFilename;
private byte[] mRawImage;
private MediaScannerConnection mScannerConn;
private PhotoViewAttacher mAttacher;
private HttpFragmentHelper mHttpHelper;
private ShareActionProvider mShareActionProvider;
@Override
public void onRefresh() {
reload();
}
@Override
public boolean hasHeader() {
return false;
}
private class DummyMediaScannerConnectionClient implements MediaScannerConnectionClient {
@Override
public void onMediaScannerConnected() {
}
@Override
public void onScanCompleted(String arg0, Uri arg1) {
}
}
public ScreenShotFragment() {
super();
shouldRetain(true);
mHttpHelper = new HttpFragmentHelper();
mActionsEnabled = true;
mSetTitle = true;
}
public ScreenShotFragment(boolean retainInstance, boolean actionsEnabled, boolean setTitle) {
super();
shouldRetain(retainInstance);
mActionsEnabled = actionsEnabled;
mSetTitle = setTitle;
}
private void shouldRetain(boolean retainInstance) {
Bundle args = new Bundle();
args.putBoolean(BUNDLE_KEY_RETAIN, retainInstance);
setArguments(args);
}
@Override
public void onCreate(Bundle savedInstanceState) {
mShouldRetainInstance = getArguments().getBoolean(BUNDLE_KEY_RETAIN);
super.onCreate(savedInstanceState);
if (mHttpHelper == null)
mHttpHelper = new HttpFragmentHelper(this);
else
mHttpHelper.bindToFragment(this);
setHasOptionsMenu(true);
if (mSetTitle)
initTitles(getString(R.string.screenshot));
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getAppCompatActivity().setTitle(getText(R.string.screenshot));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.screenshot, null);
mImageView = (ImageView) view.findViewById(R.id.screenshoot);
mImageView.setBackgroundColor(Color.BLACK);
Bundle extras = getArguments();
if (extras == null) {
extras = new Bundle();
}
mType = extras.getInt(KEY_TYPE, TYPE_ALL);
mFormat = extras.getInt(KEY_FORMAT, FORMAT_PNG);
mSize = extras.getInt(KEY_SIZE, 720);
mFilename = extras.getString(KEY_FILENAME);
if (savedInstanceState != null) {
mRawImage = savedInstanceState.getByteArray("rawImage");
} else if (mRawImage == null) {
mRawImage = new byte[0];
}
mAttacher = new PhotoViewAttacher(mImageView);
return view;
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mHttpHelper.onViewCreated(view, savedInstanceState);
SwipeRefreshLayout SwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.ptr_layout);
SwipeRefreshLayout.setEnabled(false);
}
@Override
public void onResume() {
super.onResume();
mScannerConn = new MediaScannerConnection(getAppCompatActivity(), new DummyMediaScannerConnectionClient());
mScannerConn.connect();
if (mRawImage.length == 0) {
reload();
} else {
onScreenshotAvailable(mRawImage);
}
}
@Override
public void onPause() {
mScannerConn.disconnect();
mScannerConn = null;
super.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
mAttacher.cleanup();
}
@Override
public void createOptionsMenu(Menu menu, MenuInflater inflater) {
if (menu.findItem(R.id.menu_reload) == null && mActionsEnabled) {
inflater.inflate(R.menu.reload, menu);
inflater.inflate(R.menu.save, menu);
inflater.inflate(R.menu.share, menu);
}
MenuItem shareItem = menu.findItem(R.id.menu_share);
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
}
private void setShareIntent() {
if (mShareActionProvider != null) {
File file = saveToFile(true);
if (file == null) {
showToast(getString(R.string.error));
return;
}
file.setReadable(true, false);
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType(String.format("image/%s", getFileExtension()));
mShareActionProvider.setShareIntent(intent);
}
}
private String getFileExtension() {
if (mFormat == FORMAT_JPG) {
return "jpg";
} else if (mFormat == FORMAT_PNG) {
return "png";
}
return "";
}
@Override
public void onSaveInstanceState(Bundle outState) {
if (mScannerConn != null)
mScannerConn.disconnect();
outState.putByteArray("rawImage", mRawImage);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Statics.ITEM_RELOAD:
reload();
break;
case Statics.ITEM_SAVE:
saveToFile();
}
return true;
}
/**
* @param bytes
*/
private void onScreenshotAvailable(byte[] bytes) {
if (!isAdded())
return;
mRawImage = bytes;
mImageView.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.length));
mAttacher.update();
setShareIntent();
}
protected void reload() {
mHttpHelper.onLoadStarted();
ArrayList<NameValuePair> params = new ArrayList<>();
switch (mType) {
case (TYPE_OSD):
params.add(new NameValuePair("o", ""));
params.add(new NameValuePair("n", ""));
break;
case (TYPE_VIDEO):
params.add(new NameValuePair("v", ""));
break;
case (TYPE_ALL):
break;
}
switch (mFormat) {
case (FORMAT_JPG):
params.add(new NameValuePair("format", "jpg"));
break;
case (FORMAT_PNG):
params.add(new NameValuePair("format", "png"));
break;
}
params.add(new NameValuePair("r", String.valueOf(mSize)));
if (mFilename == null) {
long ts = (new GregorianCalendar().getTimeInMillis()) / 1000;
mFilename = "/tmp/dreamDroid-" + ts;
}
params.add(new NameValuePair("filename", mFilename));
Bundle args = new Bundle();
args.putString("uri", URIStore.SCREENSHOT);
args.putSerializable("params", params);
getLoaderManager().restartLoader(0, args, this);
}
/* public void performFileSearch() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image*//*");
startActivity(intent);
}*/
private void saveToFile() {
saveToFile(false);
}
private File saveToFile(boolean inCache) {
// performFileSearch();
if (mRawImage != null) {
long timestamp = GregorianCalendar.getInstance().getTimeInMillis();
File root;
String filepath;
if (inCache) {
root = getAppCompatActivity().getCacheDir();
} else {
root = Environment.getExternalStorageDirectory();
filepath = String.format("%s%s%s", root.getAbsolutePath(), File.separator, "media/screenshots");
root = new File(filepath);
if (!root.exists()) {
root.mkdirs();
}
}
String extension = getFileExtension();
String fileName;
if (inCache) {
fileName = String.format("screenshot.%s", extension);
} else {
fileName = String.format("dreamDroid_%s.%s", timestamp, extension);
}
FileOutputStream out;
try {
File file = new File(root, fileName);
file.createNewFile();
out = new FileOutputStream(file);
out.write(mRawImage);
out.close();
if (!inCache) {
mScannerConn.scanFile(file.getAbsolutePath(), "image/*");
showToast(getString(R.string.screenshot_saved, file.getAbsolutePath()));
}
return file;
} catch (IOException e) {
Log.e(DreamDroid.LOG_TAG, e.getLocalizedMessage());
showToast(e.toString());
}
}
return null;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return false;
}
@Override
public Loader<LoaderResult<byte[]>> onCreateLoader(int id, Bundle args) {
return new AsyncByteLoader(getAppCompatActivity(), args);
}
@Override
public void onLoadFinished(Loader<LoaderResult<byte[]>> loader, LoaderResult<byte[]> result) {
mHttpHelper.onLoadFinished();
if (!result.isError()) {
if (result.getResult().length > 0)
onScreenshotAvailable(result.getResult());
else
showToast(getString(R.string.error));
} else {
showToast(result.getErrorText());
}
}
@Override
public void onLoaderReset(Loader<LoaderResult<byte[]>> loader) {
mHttpHelper.onLoadFinished();
}
protected void showToast(String toastText) {
Toast toast = Toast.makeText(getAppCompatActivity(), toastText, Toast.LENGTH_LONG);
toast.show();
}
}