package vandy.mooc.common;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Locale;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
/**
* @class Utils
*
* @brief Helper methods shared by various Activities.
*/
public class Utils {
/**
* Debugging tag.
*/
private static final String TAG =
Utils.class.getCanonicalName();
/**
* Return an uppercase version of the input or null if user gave
* no input. If user gave no input and @a showToast is true a
* toast is displayed to this effect.
*/
public static String uppercaseInput(Context context,
String input,
boolean showToast) {
if (input.isEmpty()) {
if (showToast)
Utils.showToast(context,
"no input provided");
return null;
} else
// Convert the input entered by the user so it's in
// uppercase.
return input.toUpperCase(Locale.ENGLISH);
}
/**
* Show a toast message.
*/
public static void showToast(Context context,
String message) {
Toast.makeText(context,
message,
Toast.LENGTH_SHORT).show();
}
/**
* This method is used to hide a keyboard after a user has
* finished typing the url.
*/
public static void hideKeyboard(Activity activity,
IBinder windowToken) {
InputMethodManager mgr =
(InputMethodManager) activity.getSystemService
(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(windowToken, 0);
}
/**
* Set the result of the Activity to indicate whether the
* operation on the content succeeded or not.
*
* @param activity
* The Activity whose result is being set.
* @param pathToContent
* The pathname to the content file.
* @param failureReason
* String to add to add as an extra to the Intent passed
* back to the originating Activity if the @a
* pathToContent is null.
*/
public static void setActivityResult(Activity activity,
Uri pathToContent,
String failureReason) {
if (pathToContent == null)
// Indicate why the operation on the content was
// unsuccessful or was cancelled.
activity.setResult
(Activity.RESULT_CANCELED,
new Intent("").putExtra("reason",
failureReason));
else
// Set the result of the Activity to designate the path to
// the content file resulting from a successful operation.
activity.setResult(Activity.RESULT_OK,
new Intent("",
pathToContent));
}
/**
* Set the result of the Activity to indicate whether the
* operation on the content succeeded or not.
*
* @param activity
* The Activity whose result is being set.
* @param resultCode
* The result of the Activity, i.e., RESULT_CANCELED or
* RESULT_OK.
* @param failureReason
* String to add to add as an extra to the Intent passed
* back to the originating Activity if the result of the
* Activity is RESULT_CANCELED.
*/
public static void setActivityResult(Activity activity,
int resultCode,
String failureReason) {
if (resultCode == Activity.RESULT_CANCELED)
// Indicate why the operation on the content was
// unsuccessful or was cancelled.
activity.setResult(Activity.RESULT_CANCELED,
new Intent("").putExtra("reason",
failureReason));
else
// Everything is ok.
activity.setResult(Activity.RESULT_OK);
}
/**
* @return True if the caller is running on the UI thread, else
* false.
*/
public static boolean runningOnUiThread() {
return Thread.currentThread() == Looper.getMainLooper().getThread();
}
/**
* Copy the contents of the @a inputStream to the @a outputStream
* in a manner that can be interrupted properly.
*
* @return true if copy completed without being interrupted, else false
*
* @throws IOException
*/
private static boolean interruptibleCopy(InputStream inputStream,
OutputStream outputStream)
throws IOException {
final byte[] buffer = new byte[1024];
try {
// Keep looping until the input stream is finished or the
// thread is interrupted.
for (int n;
(n = inputStream.read(buffer)) >= 0;
) {
if (Thread.interrupted())
return false;
// Write the bytes to the output stream.
outputStream.write(buffer,
0,
n);
}
} finally {
// Flush the contents of the output stream.
outputStream.flush();
}
return true;
}
/**
* Download an image file from the URL provided by the user and
* decode into a Bitmap.
*
* @param url
* The url where a bitmap image is located
*
* @return the image bitmap or null if there was an error
*/
public static Bitmap downloadAndDecodeImage(String url) {
try {
// Check to see if this thread has been interrupted.
if (Thread.interrupted())
return null;
// Connect to a remote server, download the contents of
// the image, and provide access to it via an Input
// Stream.
InputStream is =
(InputStream) new URL(url).getContent();
// Check to see if this thread has been interrupted.
if (Thread.interrupted())
return null;
else
// Decode an InputStream into a Bitmap.
return BitmapFactory.decodeStream(is);
} catch (Exception e) {
Log.e(TAG,
"Exception "
+ e
+ " received in downloadAndDecodeImage()");
throw new RuntimeException(e);
}
}
/**
* Ensure this class is only used as a utility.
*/
private Utils() {
throw new AssertionError();
}
}