package mil.nga.giat.mage.observation;
import android.Manifest;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import mil.nga.giat.mage.R;
import mil.nga.giat.mage.observation.RemoveAttachmentDialogFragment.RemoveAttachmentDialogListener;
import mil.nga.giat.mage.sdk.datastore.observation.Attachment;
import mil.nga.giat.mage.sdk.datastore.observation.AttachmentHelper;
import mil.nga.giat.mage.sdk.http.resource.ObservationResource;
import mil.nga.giat.mage.sdk.utils.MediaUtility;
public class AttachmentViewerActivity extends AppCompatActivity implements RemoveAttachmentDialogListener {
public final static String EDITABLE = "EDITABLE";
public final static String ATTACHMENT_ID = "ATTACHMENT_ID";
public final static String ATTACHMENT_PATH = "ATTACHMENT_PATH";
public final static String SHOULD_REMOVE = "SHOULD_REMOVE";
private static final String LOG_NAME = AttachmentViewerActivity.class.getName();
private static final int PERMISSIONS_REQUEST_STORAGE = 100;
private ProgressDialog progressDialog;
private Attachment attachment;
private String contentType;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.attachment_viewer);
this.setTitle("Observation Attachment");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
ImageView iv = (ImageView) findViewById(R.id.image);
if (!intent.getBooleanExtra(EDITABLE, false)) {
// findViewById(R.id.remove_btn).setVisibility(View.GONE);
}
String url = null;
String path = getIntent().getStringExtra(ATTACHMENT_PATH);
if (path == null) {
try {
attachment = AttachmentHelper.getInstance(getApplicationContext()).read(getIntent().getLongExtra(ATTACHMENT_ID, 0L));
path = attachment.getLocalPath();
url = attachment.getUrl();
contentType = attachment.getContentType();
// get content type from everywhere I can think of
if (StringUtils.isBlank(contentType) || "application/octet-stream".equalsIgnoreCase(contentType)) {
String name = attachment.getName();
if (name == null) {
name = attachment.getLocalPath();
if (name == null) {
name = attachment.getRemotePath();
}
}
contentType = MediaUtility.getMimeType(name);
}
} catch (Exception e) {
Log.e(LOG_NAME, "Error getting attachment", e);
}
} else {
contentType = MediaUtility.getMimeType(path);
}
if (path != null && new File(path).exists()) {
Uri uri = Uri.fromFile(new File(path));
if (contentType.startsWith("image")) {
Glide.with(getApplicationContext()).load(uri).centerCrop().into(iv);
} else if (contentType.startsWith("video")) {
final VideoView videoView = (VideoView) findViewById(R.id.video);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoURI(uri);
findViewById(R.id.video).setVisibility(View.VISIBLE);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
}
});
} else if (contentType.startsWith("audio")) {
findViewById(R.id.audio_image).setVisibility(View.VISIBLE);
final VideoView videoView = (VideoView) findViewById(R.id.video);
final MediaController mediaController = new MediaController(this) {
@Override
public void hide() {
//Do not hide.
}
};
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoURI(uri);
findViewById(R.id.video).setVisibility(View.VISIBLE);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
mediaController.show();
}
});
}
} else if (url != null) {
if (contentType.startsWith("image")) {
Uri uri = Uri.parse(url);
findViewById(R.id.progress).setVisibility(View.VISIBLE);
Glide.with(getApplicationContext())
.load(attachment)
.listener(new RequestListener<Attachment, GlideDrawable>() {
@Override
public boolean onException(Exception e, Attachment model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, Attachment model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
findViewById(R.id.progress).setVisibility(View.INVISIBLE);
return false;
}
})
.into(iv);
} else if (contentType.startsWith("video")) {
// TODO pass token in header
String token = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getApplicationContext().getString(mil.nga.giat.mage.sdk.R.string.tokenKey), null);
Uri uri = Uri.parse(url + "?access_token=" + token);
final VideoView videoView = (VideoView) findViewById(R.id.video);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoURI(uri);
findViewById(R.id.video).setVisibility(View.VISIBLE);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
}
});
} else if (contentType.startsWith("audio")) {
findViewById(R.id.audio_image).setVisibility(View.VISIBLE);
String token = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getApplicationContext().getString(mil.nga.giat.mage.sdk.R.string.tokenKey), null);
Uri uri = Uri.parse(url + "?access_token=" + token);
final VideoView videoView = (VideoView) findViewById(R.id.video);
videoView.setBackground(ContextCompat.getDrawable(this, R.drawable.ic_mic_gray_48dp));
videoView.setBackgroundColor(ContextCompat.getColor(this, android.R.color.white));
final MediaController mediaController = new MediaController(this) {
@Override
public void hide() {
//Do not hide.
}
};
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoURI(uri);
findViewById(R.id.video).setVisibility(View.VISIBLE);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.start();
mediaController.show();
}
});
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
if (attachment != null && attachment.getLocalPath() == null) {
inflater.inflate(R.menu.attachment_save_menu, menu);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
case R.id.save:
saveAttachment();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_REQUEST_STORAGE: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
new DownloadFileAsync().execute(attachment);
} else {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(this)
.setTitle(R.string.storage_access_title)
.setMessage(R.string.storage_access_message)
.setPositiveButton(R.string.settings, new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", getApplicationContext().getPackageName(), null));
startActivity(intent);
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
}
break;
}
}
}
public void removeImage(View v) {
DialogFragment dialog = new RemoveAttachmentDialogFragment();
dialog.show(getSupportFragmentManager(), "RemoveAttachmentDialogFragment");
}
public void goBack(View v) {
onBackPressed();
}
@Override
public void onDialogPositiveClick(DialogFragment dialog) {
Intent data = new Intent();
data.putExtra(SHOULD_REMOVE, true);
data.putExtra(ATTACHMENT_ID, attachment);
setResult(RESULT_OK, data);
finish();
}
@Override
public void onDialogNegativeClick(DialogFragment dialog) {
}
private void saveAttachment() {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(AttachmentViewerActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_STORAGE);
} else {
new DownloadFileAsync().execute(attachment);
}
}
class DownloadFileAsync extends AsyncTask<Attachment, Integer, Boolean> {
ProgressDialog progressDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(AttachmentViewerActivity.this);
progressDialog.setMessage("Saving file...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.show();
}
@Override
protected Boolean doInBackground(Attachment... attachments) {
InputStream is = null;
OutputStream os = null;
try {
Attachment attachment = attachments[0];
ObservationResource observationResource = new ObservationResource(getApplicationContext());
ResponseBody response = observationResource.getAttachment(attachment);
Long contentLength = response.contentLength();
String type;
if (contentType.startsWith("image")) {
type = Environment.DIRECTORY_PICTURES;
} else if (contentType.startsWith("video")) {
type = Environment.DIRECTORY_MOVIES;
} else if (contentType.startsWith("audio")) {
type = Environment.DIRECTORY_MUSIC;
} else {
type = Environment.DIRECTORY_DOWNLOADS;
}
File directory = MediaUtility.getPublicAttachmentsDirectory(type);
File stagedFile = new File(directory, AttachmentViewerActivity.this.attachment.getName());
AttachmentViewerActivity.this.attachment.setLocalPath(stagedFile.getAbsolutePath());
os = new FileOutputStream(AttachmentViewerActivity.this.attachment.getLocalPath());
byte data[] = new byte[1024];
Long total = 0l;
int count;
is = response.byteStream();
while ((count = is.read(data)) != -1) {
total += count;
publishProgress(((Double)(100.0*(total.doubleValue()/contentLength.doubleValue()))).intValue());
os.write(data, 0, count);
}
} catch (Exception e) {
Log.e(LOG_NAME, "Problem downloading file.", e);
return false;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.flush();
os.close();;
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
protected void onProgressUpdate(Integer... progress) {
progressDialog.setProgress(progress[0]);
}
@Override
protected void onPostExecute(Boolean success) {
progressDialog.dismiss();
if (!success) {
Toast toast = Toast.makeText(getApplicationContext(), "Attachment Failed to Save", Toast.LENGTH_SHORT);
toast.show();
return;
}
try {
AttachmentHelper attachmentHelper = AttachmentHelper.getInstance(getApplicationContext());
Attachment attachment = attachmentHelper.read(AttachmentViewerActivity.this.attachment.getId());
attachment.setLocalPath(AttachmentViewerActivity.this.attachment.getLocalPath());
attachmentHelper.update(attachment);
MediaUtility.addImageToGallery(getApplicationContext(), Uri.fromFile(new File(AttachmentViewerActivity.this.attachment.getLocalPath())));
AttachmentViewerActivity.this.invalidateOptionsMenu();
Toast toast = Toast.makeText(getApplicationContext(), "Attachment Successfully Saved", Toast.LENGTH_SHORT);
toast.show();
} catch (Exception e) {
Log.e(LOG_NAME, "Error saving attachment to DB", e);
}
}
}
}