package ca.josephroque.bowlingcompanion.utilities;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import ca.josephroque.bowlingcompanion.R;
/**
* Created by Joseph Roque on 15-03-26. Provides methods for sharing the statistics and games tracked by the
* application.
*/
@SuppressWarnings("Convert2Lambda")
public final class ShareUtils {
/** Identifies output from this class in Logcat. */
@SuppressWarnings("unused")
private static final String TAG = "ShareUtils";
/**
* Shows a dialog to prompt user to share the series or save it to the device.
*
* @param activity parent activity for the dialog
* @param seriesId id of the series to share
*/
public static void showShareDialog(final Activity activity, final long seriesId) {
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
PermissionUtils.requestExternalStoragePermission(activity);
} else {
final CharSequence[] options = {"Save", "Share"};
AlertDialog.Builder shareBuilder = new AlertDialog.Builder(activity);
shareBuilder.setTitle("Save to device or share?")
.setSingleChoiceItems(options, 0, null)
.setPositiveButton(R.string.dialog_okay, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int selectedItem =
((AlertDialog) dialog).getListView().getCheckedItemPosition();
if (selectedItem == 0)
saveSeriesToDevice(activity, seriesId);
else
shareSeries(new WeakReference<Context>(activity), seriesId);
dialog.dismiss();
}
})
.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create()
.show();
}
}
/**
* Creates a task to save an image of the series to the device and prompt the user to share it with another
* service.
*
* @param context the current context
* @param seriesId id of the series to share
*/
@SuppressWarnings("unchecked")
private static void shareSeries(WeakReference<Context> context, long seriesId) {
new ShareSeriesTask().execute(Pair.create(context, seriesId));
}
/**
* Creates an image of the series and saves it to the device.
*
* @param activity parent activity for the dialog
* @param seriesId id of the series to share
*/
private static void saveSeriesToDevice(final Activity activity, final long seriesId) {
new Thread(new Runnable() {
@SuppressWarnings("UnusedAssignment") // seriesBitmap set to null to free memory
@Override
public void run() {
Bitmap seriesBitmap = ImageUtils.createImageFromSeries(activity, seriesId);
final Uri imageUri = ImageUtils.insertImage(activity.getContentResolver(),
seriesBitmap,
String.valueOf(System.currentTimeMillis()),
"Series: " + seriesId);
seriesBitmap.recycle();
seriesBitmap = null;
System.gc();
activity.runOnUiThread(new Runnable() {
@SuppressWarnings("ConstantConditions")
@Override
public void run() {
MediaScannerConnection.scanFile(activity,
new String[]{imageUri.getPath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
Toast toast;
if (imageUri != null)
toast = Toast.makeText(
activity, "Image successfully saved!", Toast.LENGTH_SHORT);
else
toast = Toast.makeText(
activity, "Unable to save image", Toast.LENGTH_SHORT);
toast.show();
}
});
}
}).start();
}
/**
* Creates an image for the series and prompts user to share it.
*/
private static class ShareSeriesTask
extends AsyncTask<Pair<WeakReference<Context>, Long>, Void, Pair<WeakReference<Context>,
WeakReference<Intent>>> {
@SafeVarargs
@SuppressWarnings("UnusedAssignment") // image set to null to free memory
@Override
public final Pair<WeakReference<Context>, WeakReference<Intent>> doInBackground(
Pair<WeakReference<Context>, Long>... params) {
Context context = params[0].first.get();
if (context == null)
return null;
long seriesId = params[0].second;
Bitmap image = ImageUtils.createImageFromSeries(context, seriesId);
Uri imageUri = ImageUtils.insertImage(context.getContentResolver(),
image,
String.valueOf(System.currentTimeMillis()),
"Series: " + seriesId);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/jpeg");
OutputStream outStream = null;
try {
outStream = context.getContentResolver()
.openOutputStream(imageUri);
//noinspection CheckStyle
image.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
image.recycle();
image = null;
System.gc();
} catch (Exception ex) {
Log.e(TAG, "Could not create output stream", ex);
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (IOException ex) {
// does nothing - could not close output stream
}
}
}
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
return Pair.create(params[0].first, new WeakReference<>(shareIntent));
}
@Override
public void onPostExecute(Pair<WeakReference<Context>, WeakReference<Intent>> params) {
if (params != null) {
Context context = params.first.get();
Intent intent = params.second.get();
if (context == null || intent == null)
return;
context.startActivity(Intent.createChooser(intent, "Share Image"));
}
}
}
/**
* Default private constructor.
*/
private ShareUtils() {
// does nothing
}
}