package net.hockeyapp.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
import android.widget.Toast;
import net.hockeyapp.android.utils.HockeyLog;
import net.hockeyapp.android.views.PaintView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class PaintActivity extends Activity {
/**
* URI of the image to annotate
*/
public static final String EXTRA_IMAGE_URI = "imageUri";
private static final int MENU_SAVE_ID = Menu.FIRST;
private static final int MENU_UNDO_ID = Menu.FIRST + 1;
private static final int MENU_CLEAR_ID = Menu.FIRST + 2;
private PaintView mPaintView;
private String mImageName;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Get image path. */
Bundle extras = getIntent().getExtras();
if (extras == null || extras.getParcelable(EXTRA_IMAGE_URI) == null) {
HockeyLog.error("Can't set up PaintActivity as image extra was not provided!");
return;
}
Uri imageUri = extras.getParcelable(EXTRA_IMAGE_URI);
mImageName = determineFilename(imageUri, imageUri.getLastPathSegment());
int displayWidth = getResources().getDisplayMetrics().widthPixels;
int displayHeight = getResources().getDisplayMetrics().heightPixels;
int currentOrientation = displayWidth > displayHeight ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE :
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
int desiredOrientation = PaintView.determineOrientation(getContentResolver(), imageUri);
//noinspection ResourceType
setRequestedOrientation(desiredOrientation);
if (currentOrientation != desiredOrientation) {
/* Activity will be destroyed again.. skip the following expensive operations. */
HockeyLog.debug("Image loading skipped because activity will be destroyed for orientation change.");
return;
}
/* Create view and find out which orientation is needed. */
mPaintView = new PaintView(this, imageUri, displayWidth, displayHeight);
LinearLayout vLayout = new LinearLayout(this);
LinearLayout.LayoutParams vParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
vLayout.setLayoutParams(vParams);
vLayout.setGravity(Gravity.CENTER);
vLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout hLayout = new LinearLayout(this);
LinearLayout.LayoutParams hParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
hLayout.setLayoutParams(hParams);
hLayout.setGravity(Gravity.CENTER);
hLayout.setOrientation(LinearLayout.HORIZONTAL);
vLayout.addView(hLayout);
hLayout.addView(mPaintView);
setContentView(vLayout);
Toast toast = Toast.makeText(this, getString(R.string.hockeyapp_paint_indicator_toast), Toast.LENGTH_LONG);
toast.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_SAVE_ID, 0, getString(R.string.hockeyapp_paint_menu_save));
menu.add(0, MENU_UNDO_ID, 0, getString(R.string.hockeyapp_paint_menu_undo));
menu.add(0, MENU_CLEAR_ID, 0, getString(R.string.hockeyapp_paint_menu_clear));
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_SAVE_ID:
makeResult();
return true;
case MENU_UNDO_ID:
mPaintView.undo();
return true;
case MENU_CLEAR_ID:
mPaintView.clearImage();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (!mPaintView.isClear()) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
makeResult();
break;
case DialogInterface.BUTTON_NEGATIVE:
PaintActivity.this.finish();
break;
case DialogInterface.BUTTON_NEUTRAL:
/* No action. */
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.hockeyapp_paint_dialog_message)
.setPositiveButton(R.string.hockeyapp_paint_dialog_positive_button, dialogClickListener)
.setNegativeButton(R.string.hockeyapp_paint_dialog_negative_button, dialogClickListener)
.setNeutralButton(R.string.hockeyapp_paint_dialog_neutral_button, dialogClickListener)
.show();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
private void makeResult() {
File hockeyAppCache = new File(getCacheDir(), "HockeyApp");
hockeyAppCache.mkdir();
String filename = mImageName + ".jpg";
File result = new File(hockeyAppCache, filename);
int suffix = 1;
while (result.exists()) {
result = new File(hockeyAppCache, mImageName + "_" + suffix + ".jpg");
suffix++;
}
mPaintView.setDrawingCacheEnabled(true);
final Bitmap bitmap = mPaintView.getDrawingCache();
new AsyncTask<File, Void, Void>() {
@Override
protected Void doInBackground(File... args) {
try {
FileOutputStream out = new FileOutputStream(args[0]);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
} catch (IOException e) {
e.printStackTrace();
HockeyLog.error("Could not save image.", e);
}
return null;
}
}.execute(result);
Intent intent = new Intent();
Uri uri = Uri.fromFile(result);
intent.putExtra(EXTRA_IMAGE_URI, uri);
if (getParent() == null) {
setResult(Activity.RESULT_OK, intent);
} else {
getParent().setResult(Activity.RESULT_OK, intent);
}
finish();
}
private String determineFilename(Uri uri, String fallback) {
String[] projection = {MediaStore.MediaColumns.DATA};
String path = null;
ContentResolver cr = getApplicationContext().getContentResolver();
Cursor metaCursor = cr.query(uri, projection, null, null, null);
if (metaCursor != null) {
try {
if (metaCursor.moveToFirst()) {
path = metaCursor.getString(0);
}
} finally {
metaCursor.close();
}
}
return path == null ? fallback : new File(path).getName();
}
}