Java tutorial
package com.krayzk9s.imgurholo.services; /* * Copyright 2013 Kurt Zimmer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.app.IntentService; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Parcelable; import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.util.Base64; import android.util.Log; import com.krayzk9s.imgurholo.R; import com.krayzk9s.imgurholo.activities.ImgurHoloActivity; import com.krayzk9s.imgurholo.tools.ApiCall; import com.krayzk9s.imgurholo.tools.FileUtils; import com.krayzk9s.imgurholo.tools.GetData; import com.krayzk9s.imgurholo.tools.NewAlbumAsync; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; /** * Copyright 2013 Kurt Zimmer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public class UploadService extends IntentService implements GetData { private ApiCall apiCall; private ArrayList<String> ids; private int totalUpload; public UploadService() { super("UploadService"); } /** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, IntentService * stops the service, as appropriate. */ @Override public void onCreate() { super.onCreate(); apiCall = new ApiCall(); apiCall.setSettings(PreferenceManager.getDefaultSharedPreferences(getApplicationContext())); } public void onGetObject(Object o, String tag) { String id = (String) o; if (id.length() == 7) { if (totalUpload != -1) ids.add(id); if (ids.size() == totalUpload) { ids.add(0, ""); //weird hack because imgur eats the first item of the array for some bizarre reason NewAlbumAsync newAlbumAsync = new NewAlbumAsync("", "", apiCall, ids, this); newAlbumAsync.execute(); } } else if (apiCall.settings.getBoolean("AlbumUpload", true)) { NotificationManager notificationManager = (NotificationManager) this .getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this); Intent viewImageIntent = new Intent(); viewImageIntent.setAction(Intent.ACTION_VIEW); viewImageIntent.setData(Uri.parse("http://imgur.com/a/" + id)); Intent shareIntent = new Intent(); shareIntent.setType("text/plain"); shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); shareIntent.putExtra(Intent.EXTRA_TEXT, "http://imgur.com/a/" + id); PendingIntent viewImagePendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), viewImageIntent, 0); PendingIntent sharePendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), shareIntent, 0); Notification notification = notificationBuilder.setSmallIcon(R.drawable.icon_desaturated) .setContentText("Finished Uploading Album").setContentTitle("imgur Image Uploader") .setContentIntent(viewImagePendingIntent) .addAction(R.drawable.dark_social_share, "Share", sharePendingIntent).build(); Log.d("Built", "Notification built"); notificationManager.cancel(0); notificationManager.notify(1, notification); Log.d("Built", "Notification display"); } else { NotificationManager notificationManager = (NotificationManager) this .getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this); Notification notification = notificationBuilder.setSmallIcon(R.drawable.icon_desaturated) .setContentText("Finished Uploading All Images").setContentTitle("imgur Image Uploader") .build(); Log.d("Built", "Notification built"); notificationManager.cancel(0); notificationManager.notify(1, notification); Log.d("Built", "Notification display"); } } public void handleException(Exception e, String tag) { } @Override protected void onHandleIntent(Intent intent) { ids = new ArrayList<String>(); if (intent.hasExtra("images")) { Log.d("recieving", "handling multiple"); ArrayList<Parcelable> list = intent.getParcelableArrayListExtra("images"); totalUpload = list.size(); for (Parcelable parcel : list) { Uri uri = (Uri) parcel; Log.d("recieving", uri.toString()); SendImage sendImage = new SendImage(apiCall, FileUtils.getPath(this, uri), getApplicationContext(), getResources(), this); Log.d("recieving", "executing"); sendImage.execute(); } } else { totalUpload = -1; SendImage sendImage = new SendImage(apiCall, FileUtils.getPath(getApplicationContext(), intent.getData()), getApplicationContext(), getResources(), this); sendImage.execute(); } } /* From http://stackoverflow.com/users/1946055/tobiel at http://stackoverflow.com/questions/17839388/creating-a-scaled-bitmap-with-createscaledbitmap-in-android */ private static Bitmap lessResolution(String filePath, int width, int height) { BitmapFactory.Options options = new BitmapFactory.Options(); // First decode with inJustDecodeBounds=true to check dimensions options.inPurgeable = true; options.inInputShareable = true; options.inJustDecodeBounds = true; BitmapFactory.decodeFile(filePath, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, width, height); BitmapFactory.decodeFile(filePath, options); float factor = calculateFactor(options, width, height); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return Bitmap.createScaledBitmap(BitmapFactory.decodeFile(filePath, options), (int) Math.floor(options.outWidth * factor), (int) Math.floor(options.outHeight * factor), false); } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { Log.d("reqHeight", "" + reqHeight); Log.d("reqWidth", "" + reqWidth); // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = (heightRatio < widthRatio ? heightRatio : widthRatio); Log.d("inSampleSize", "" + inSampleSize); // We round the value to the highest, always. if ((height / inSampleSize) > reqHeight || (width / inSampleSize > reqWidth)) { inSampleSize++; } } return inSampleSize; } private static float calculateFactor(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; Log.d("reqHeight", reqHeight + ""); Log.d("reqWidth", reqWidth + ""); Log.d(ImgurHoloActivity.IMAGE_DATA_HEIGHT, height + ""); Log.d("width", width + ""); float factor; if (height > reqHeight || width > reqWidth) { final float heightRatio = (float) reqHeight / (float) height; final float widthRatio = (float) reqWidth / (float) width; Log.d("heightRatio", heightRatio + ""); Log.d("widthRatio", widthRatio + ""); factor = heightRatio < widthRatio ? heightRatio : widthRatio; Log.d("factor", factor + ""); } else factor = 1; return factor; } private static class SendImage extends AsyncTask<Void, Void, JSONObject> { Bitmap photo; final ApiCall apiCallStatic; final SharedPreferences settings; final Context context; final Resources resources; String filePath; NotificationManager notificationManager; final UploadService uploadService; private void throwError(String error) { notificationManager.cancel(0); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context); Notification notification = notificationBuilder.setSmallIcon(R.drawable.icon_desaturated) .setContentText(error).setContentTitle(context.getString(R.string.error_upload)).build(); notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, notification); } public SendImage(ApiCall _apiCallStatic, String _filepath, Context _context, Resources _resources, UploadService _uploadService) { uploadService = _uploadService; apiCallStatic = _apiCallStatic; filePath = _filepath; context = _context; settings = PreferenceManager.getDefaultSharedPreferences(context); resources = _resources; NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context); Notification notification = notificationBuilder.setSmallIcon(R.drawable.icon_desaturated) .setContentText("Now Uploading").setProgress(0, 0, true).setContentTitle("imgur Image Uploader") .build(); notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, notification); } @Override protected JSONObject doInBackground(Void... voids) { Log.d("recieved", "in background"); int maxHeight = Integer.MAX_VALUE; if (settings.getBoolean("HeightBoolean", false)) maxHeight = Integer.parseInt(settings.getString("HeightSize", "1080")); int maxWidth = Integer.MAX_VALUE; if (settings.getBoolean("WidthBoolean", false)) maxWidth = Integer.parseInt(settings.getString("WidthSize", "1920")); byte[] byteArray; try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); if (maxHeight != Integer.MAX_VALUE || maxWidth != Integer.MAX_VALUE) { photo = lessResolution(filePath, maxWidth, maxHeight); photo.compress(Bitmap.CompressFormat.PNG, 100, stream); byteArray = stream.toByteArray(); } else { InputStream is = new BufferedInputStream(new FileInputStream(filePath)); ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (is.available() > 0) { bos.write(is.read()); } byteArray = bos.toByteArray(); photo = lessResolution(filePath, 500, 500); photo.compress(Bitmap.CompressFormat.PNG, 100, stream); } if (byteArray == null) Log.d("Image Upload", "NULL :("); String image = Base64.encodeToString(byteArray, Base64.DEFAULT); Log.d("Image Upload", image); HashMap<String, Object> hashMap = new HashMap<String, Object>(); hashMap.put("image", image); hashMap.put(ImgurHoloActivity.IMAGE_DATA_TYPE, "binary"); JSONObject data = apiCallStatic.makeCall("3/image", "post", hashMap); if (data == null) data = apiCallStatic.makeCall("3/image", "post", hashMap); if (data == null) { throwError("imgur Not Responding"); return null; } Log.d("Image Upload", data.toString()); JSONObject returner = apiCallStatic .makeCall("3/image/" + data.getJSONObject("data").getString("id"), "get", null); Log.d("returning", returner.toString()); return returner.getJSONObject("data"); } catch (JSONException e) { Log.e("Error!", e.toString()); } catch (IOException e) { Log.e("Error!", e.toString()); } return new JSONObject(); } @Override protected void onPostExecute(JSONObject data) { NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context); NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(); if (data == null) { Notification notification = notificationBuilder.setSmallIcon(R.drawable.icon_desaturated) .setContentText(context.getString(R.string.error_upload)).setStyle(bigPictureStyle) .setContentTitle(context.getString(R.string.imgur_uploader_title)).build(); notificationManager.cancel(0); notificationManager.notify(1, notification); return; } Log.d("Built", "Notification building"); bigPictureStyle.bigPicture(photo); Log.d("Built", "Picture set"); try { Log.d("data", data.toString()); String id = data.getString("id"); Log.d("id", id); uploadService.onGetObject(id, null); Intent viewImageIntent = new Intent(); viewImageIntent.setAction(Intent.ACTION_VIEW); viewImageIntent.setData(Uri.parse(data.getString(ImgurHoloActivity.IMAGE_DATA_LINK))); String link = ""; if (settings.getString("AutoCopyType", resources.getString(R.string.direct_link)) .equals(resources.getString(R.string.direct_link))) { link = "http://imgur.com/" + data.getString("id"); } else if (settings.getString("AutoCopyType", resources.getString(R.string.direct_link)) .equals(resources.getString(R.string.link))) { link = data.getString(ImgurHoloActivity.IMAGE_DATA_LINK); } else if (settings.getString("AutoCopyType", resources.getString(R.string.direct_link)) .equals(resources.getString(R.string.html_link))) { link = "<a href=\"http://imgur.com/" + data.getString("id") + "\"><img src=\"" + data.getString(ImgurHoloActivity.IMAGE_DATA_LINK) + "\" title=\"Hosted by imgur.com\"/></a>"; } else if (settings.getString("AutoCopyType", resources.getString(R.string.direct_link)) .equals(resources.getString(R.string.bbcode_link))) { link = "[IMG]" + data.getString(ImgurHoloActivity.IMAGE_DATA_LINK) + "[/IMG]"; } else if (settings.getString("AutoCopyType", resources.getString(R.string.direct_link)) .equals(resources.getString(R.string.linked_bbcode_link))) { link = "[URL=http://imgur.com/" + data.getString("id") + "][IMG]" + data.getString(ImgurHoloActivity.IMAGE_DATA_LINK) + "[/IMG][/URL]"; } else if (settings.getString("AutoCopyType", resources.getString(R.string.direct_link)) .equals(resources.getString(R.string.markdown_link))) { link = "[Imgur](http://i.imgur.com/" + data.getString("id") + ")"; } Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND); shareIntent.setType("text/plain"); shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); shareIntent.putExtra(Intent.EXTRA_TEXT, link); PendingIntent viewImagePendingIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), viewImageIntent, 0); PendingIntent sharePendingIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), shareIntent, 0); if (uploadService.totalUpload == -1) { Notification notification = notificationBuilder.setSmallIcon(R.drawable.icon_desaturated) .setContentText(context.getString(R.string.finished_uploading)) .setStyle(bigPictureStyle) .setContentTitle(context.getString(R.string.imgur_uploader_title)) .setContentIntent(viewImagePendingIntent) .addAction(R.drawable.dark_social_share, "Share", sharePendingIntent).build(); Log.d("Built", "Notification built"); notificationManager.cancel(0); notificationManager.notify(1, notification); Log.d("Built", "Notification display"); } } catch (JSONException e) { Log.e("Error!", e.toString()); throwError("imgur Response Malformed"); } } } }