Java tutorial
/* * This file is part of RateBeer For Android. RateBeer for Android is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. RateBeer for Android is distributed in the hope that * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU * General Public License along with RateBeer for Android. If not, see <http://www.gnu.org/licenses/>. */ package com.ratebeer.android.gui.components; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.sql.SQLException; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; import com.googlecode.androidannotations.annotations.Bean; import com.googlecode.androidannotations.annotations.EService; import com.googlecode.androidannotations.annotations.SystemService; import com.ratebeer.android.R; import com.ratebeer.android.api.ApiConnection; import com.ratebeer.android.api.CommandFailureResult; import com.ratebeer.android.api.CommandResult; import com.ratebeer.android.api.CommandSuccessResult; import com.ratebeer.android.api.UserSettings; import com.ratebeer.android.api.command.AddAvailabilityCommand; import com.ratebeer.android.api.command.AddToCellarCommand; import com.ratebeer.android.api.command.AddUpcCodeCommand; import com.ratebeer.android.api.command.DeleteTickCommand; import com.ratebeer.android.api.command.ImageUrls; import com.ratebeer.android.api.command.PostRatingCommand; import com.ratebeer.android.api.command.PostTickCommand; import com.ratebeer.android.api.command.SendBeerMailCommand; import com.ratebeer.android.api.command.SendBeerReplyCommand; import com.ratebeer.android.api.command.SetDrinkingStatusCommand; import com.ratebeer.android.api.command.UploadBeerPhotoCommand; import com.ratebeer.android.app.ApplicationSettings; import com.ratebeer.android.app.persistance.OfflineRating; import com.ratebeer.android.gui.Home_; import com.ratebeer.android.gui.components.helpers.DatabaseConsumerService; import com.ratebeer.android.gui.components.helpers.Log; import com.ratebeer.android.gui.fragments.AddToCellarFragment.CellarType; @EService public class PosterService extends DatabaseConsumerService { public static final String ACTION_SETDRINKINGSTATUS = "com.ratebeer.android.SET_DRINKING_STATUS"; public static final String ACTION_POSTRATING = "com.ratebeer.android.POST_RATING"; public static final String ACTION_EDITRATING = "com.ratebeer.android.EDIT_RATING"; public static final String ACTION_POSTTICK = "com.ratebeer.android.POST_TICK"; public static final String ACTION_ADDAVAILABILITY = "com.ratebeer.android.ADD_AVAILABILITY"; public static final String ACTION_ADDTOCELLAR = "com.ratebeer.android.ADD_TO_CELLAR"; public static final String ACTION_SENDMAIL = "com.ratebeer.android.SEND_BEERMAIL"; public static final String ACTION_UPLOADBEERPHOTO = "com.ratebeer.android.UPLOAD_BEER_PHOTO"; public static final String ACTION_ADDUPCCODE = "com.ratebeer.android.ADD_UPCCODE"; public static final String URI_BEER = "http://ratebeer.com/b/%s/"; public static final String EXTRA_MESSENGER = "MESSENGER"; public static final String EXTRA_NEWSTATUS = "NEW_STATUS"; public static final String EXTRA_BEERID = "BEER_ID"; public static final String EXTRA_USERID = "USER_ID"; public static final String EXTRA_OFFLINEID = "OFFLINE_ID"; public static final String EXTRA_ORIGRATINGID = "ORIGRATING_ID"; public static final String EXTRA_ORIGRATINGDATE = "ORIGRATING_DATE"; public static final String EXTRA_BEERNAME = "BEER_NAME"; public static final String EXTRA_AROMA = "AROMA"; public static final String EXTRA_APPEARANCE = "APPEARANCE"; public static final String EXTRA_TASTE = "TASTE"; public static final String EXTRA_PALATE = "PALATE"; public static final String EXTRA_OVERALL = "OVERALL"; public static final String EXTRA_COMMENT = "COMMENT"; public static final String EXTRA_LIKED = "LIKED"; public static final String EXTRA_PLACEID = "EXTRAPLACEID"; public static final String EXTRA_CELLARTYPE = "CELLARTYPE"; public static final String EXTRA_MEMO = "MEMO"; public static final String EXTRA_VINTAGE = "VINTAGE"; public static final String EXTRA_QUANTITY = "QUANTITY"; public static final String EXTRA_SENDTO = "SENDTO"; public static final String EXTRA_SUBJECT = "SUBJECT"; public static final String EXTRA_BODY = "BODY"; public static final String EXTRA_REPLYTO = "REPLYTO"; public static final String EXTRA_RECIPIENT = "RECIPIENT"; public static final String EXTRA_PHOTO = "PHOTO"; public static final String EXTRA_UPCCODE = "UPCCODE"; public static final int EXTRA_TICK_DELETE = -1; public static final int NO_BEER_EXTRA = -1; public static final int NO_OFFLINE_EXTRA = -1; public static final int NO_REPLY_EXTRA = 0; public static final int RESULT_SUCCESS = 0; public static final int RESULT_FAILURE = 1; private static final int NOTIFY_SETDRINKINGSTATUS = 0; private static final int NOTIFY_POSTINGRATING = 1; private static final int NOTIFY_ADDAVAILABILITY = 2; private static final int NOTIFY_ADDTOCELLAR = 3; private static final int NOTIFY_SENDMAIL = 4; private static final int NOTIFY_UPLOADPHOTO = 5; private static final int NOTIFY_ADDUPCCODE = 6; private static final int NOTIFY_POSTINGTICK = 7; private static final int IMAGE_MAX_SIZE = 1280; // Max pixels in one dimension @Bean protected Log Log; @Bean protected ApplicationSettings applicationSettings; @Bean protected ApiConnection apiConnection; @SystemService protected NotificationManager notificationManager; public PosterService() { super(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME + " PosterService"); } public PosterService(String name) { super(name); } @Override protected void onHandleIntent(Intent intent) { // Proper intent received? if (intent == null || intent.getAction() == null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "No intent action to perform"); return; } // Proper user settings? UserSettings user = applicationSettings.getUserSettings(); if (user == null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Canceling " + intent.getAction() + " intent because there are no user settings known."); return; } // Try to set the drinking status if (intent.getAction().equals(ACTION_SETDRINKINGSTATUS)) { // Get new status text String newStatus = intent.getStringExtra(EXTRA_NEWSTATUS); int beerId = intent.getIntExtra(EXTRA_BEERID, NO_BEER_EXTRA); if (newStatus == null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "No new drinking status is intent; cancelling"); return; } // Synchronously set the new drinking status // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Now setting drinking status to " + newStatus); Intent recoverIntent; if (beerId == NO_BEER_EXTRA) { // If no specific beer was tight to this drinking status, assume it was from the home screen's free text // input recoverIntent = new Intent(this, Home_.class); } else { recoverIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(String.format(URI_BEER, Integer.toString(beerId)))); } createNotification(NOTIFY_SETDRINKINGSTATUS, getString(R.string.app_settingdrinking), getString(R.string.home_nowdrinking, newStatus), true, recoverIntent, null, beerId); CommandResult result = new SetDrinkingStatusCommand(user, newStatus).execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_SETDRINKINGSTATUS); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_SUCCESS); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Setting drinking status to " + newStatus + " failed: " + e); createNotification(NOTIFY_SETDRINKINGSTATUS, getString(R.string.app_settingdrinking), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_FAILURE); } } // Try to add a new rating if (intent.getAction().equals(ACTION_POSTRATING)) { // Get rating details int beerId = intent.getIntExtra(EXTRA_BEERID, NO_BEER_EXTRA); String beerName = intent.getStringExtra(EXTRA_BEERNAME); int offlineId = intent.getIntExtra(EXTRA_OFFLINEID, NO_OFFLINE_EXTRA); int ratingId = intent.getIntExtra(EXTRA_ORIGRATINGID, -1); String origDate = intent.getStringExtra(EXTRA_ORIGRATINGDATE); int aroma = intent.getIntExtra(EXTRA_AROMA, -1); int appearance = intent.getIntExtra(EXTRA_APPEARANCE, -1); int taste = intent.getIntExtra(EXTRA_TASTE, -1); int palate = intent.getIntExtra(EXTRA_PALATE, -1); int overall = intent.getIntExtra(EXTRA_OVERALL, -1); String comment = intent.getStringExtra(EXTRA_COMMENT); if (beerId == NO_BEER_EXTRA || aroma <= 0 || appearance <= 0 || taste <= 0 || palate <= 0 || overall <= 0 || beerName == null || comment == null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Missing extras in the POSTRATING intent; cancelling."); return; } // Synchronously post the new rating // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Now posting rating for " + beerName); Intent recoverIntent = new Intent(getApplicationContext(), Home_.class); recoverIntent.replaceExtras(intent.getExtras()); recoverIntent.setAction(ACTION_EDITRATING); createNotification(NOTIFY_POSTINGRATING, getString(R.string.app_postingrating), getString(R.string.app_rated, beerName, PostRatingCommand.calculateTotal(aroma, appearance, taste, palate, overall)), true, recoverIntent, null, beerId); CommandResult result = new PostRatingCommand(user, beerId, ratingId, origDate, beerName, aroma, appearance, taste, palate, overall, comment).execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_POSTINGRATING); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_SUCCESS); // Ratings are usually stored locally as offline rating using the ORM persistence layer // If so, it can now be removed try { if (offlineId != NO_OFFLINE_EXTRA) { OfflineRating offlineRating = getHelper().getOfflineRatingDao().queryForId(offlineId); if (offlineRating != null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Deleted the offline rating for this beer as well."); getHelper().getOfflineRatingDao().delete(offlineRating); } } } catch (SQLException e) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Offline rating not available: " + e.toString()); } } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Posting of rating for " + beerName + " failed: " + e); createNotification(NOTIFY_POSTINGRATING, getString(R.string.app_postingrating), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_FAILURE); } } // Try to post a tick update if (intent.getAction().equals(ACTION_POSTTICK)) { // Get tick details int beerId = intent.getIntExtra(EXTRA_BEERID, NO_BEER_EXTRA); String beerName = intent.getStringExtra(EXTRA_BEERNAME); int userId = intent.getIntExtra(EXTRA_USERID, -1); int liked = intent.getIntExtra(EXTRA_LIKED, EXTRA_TICK_DELETE); if (beerId == NO_BEER_EXTRA || beerName == null || userId <= 0 || liked == 0 || liked > 5 || liked < -1) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Missing extras in the POSTRATING intent; cancelling."); return; } // Synchronously post the tick update // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Now ticking " + beerName); Intent recoverIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(String.format(URI_BEER, Integer.toString(beerId)))); // If liked (the actual tick) is set to -1 we delete this tick instead boolean del = liked == EXTRA_TICK_DELETE; createNotification(NOTIFY_POSTINGTICK, getString(del ? R.string.app_removingtick : R.string.app_postingtick), getString(R.string.app_forbeer, beerName), true, recoverIntent, null, beerId); CommandResult result; if (del) { result = new DeleteTickCommand(user, beerId, userId, beerName).execute(apiConnection); } else { result = new PostTickCommand(user, beerId, userId, beerName, liked).execute(apiConnection); } if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_POSTINGTICK); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_SUCCESS); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, (del ? "Removing of tick for " : "Ticking of ") + beerName + " failed: " + e); createNotification(NOTIFY_POSTINGRATING, getString(del ? R.string.app_removingtick : R.string.app_postingtick), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_FAILURE); } } // Try to add beer availability info if (intent.getAction().equals(ACTION_ADDAVAILABILITY)) { // Get beer and selected places int beerId = intent.getIntExtra(EXTRA_BEERID, -1); String beerName = intent.getStringExtra(EXTRA_BEERNAME); int placeId = intent.getIntExtra(EXTRA_PLACEID, -1); if (beerId <= 0 || beerName == null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Missing extras in the ADDAVAILABILITY intent; cancelling."); return; } // Synchronously post the availability info // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Now adding availability for " + beerName); Intent recoverIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(String.format(URI_BEER, Integer.toString(beerId)))); createNotification(NOTIFY_ADDAVAILABILITY, getString(R.string.app_addingavailability), getString(R.string.app_addingforbeer, beerName), true, recoverIntent, null, beerId); CommandResult result = new AddAvailabilityCommand(user, beerId, placeId).execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_ADDAVAILABILITY); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Adding of availability info for " + beerName + " failed: " + e); createNotification(NOTIFY_ADDAVAILABILITY, getString(R.string.app_addingavailability), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); } } // Try to add a beer to the cellar (a want or a have) if (intent.getAction().equals(ACTION_ADDTOCELLAR)) { // Get beer and notes int beerId = intent.getIntExtra(EXTRA_BEERID, -1); String beerName = intent.getStringExtra(EXTRA_BEERNAME); CellarType cellarType = CellarType.valueOf(intent.getStringExtra(EXTRA_CELLARTYPE)); String memo = intent.getStringExtra(EXTRA_MEMO); String vintage = intent.getStringExtra(EXTRA_VINTAGE); String quantity = intent.getStringExtra(EXTRA_QUANTITY); if (beerId <= 0 || beerName == null) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Missing extras in the ADDAVAILABILITY intent; cancelling."); return; } // Synchronously post the new cellar beer // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Now adding " + beerName + " to the cellar"); Intent recoverIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(String.format(URI_BEER, Integer.toString(beerId)))); createNotification(NOTIFY_ADDTOCELLAR, getString(R.string.app_addingtocellar), getString(cellarType == CellarType.Have ? R.string.app_addhave : R.string.app_addwant, beerName), true, recoverIntent, null, beerId); CommandResult result = new AddToCellarCommand(user, cellarType, beerId, memo, vintage, quantity) .execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_ADDTOCELLAR); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Adding of " + beerName + " to cellar failed: " + e); createNotification(NOTIFY_ADDTOCELLAR, getString(R.string.app_addingtocellar), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); } } // Try to send a mail if (intent.getAction().equals(ACTION_SENDMAIL)) { // Get mail details String sendTo = intent.getStringExtra(EXTRA_SENDTO); String subject = intent.getStringExtra(EXTRA_SUBJECT); String body = intent.getStringExtra(EXTRA_BODY); int replyTo = intent.getIntExtra(EXTRA_REPLYTO, NO_REPLY_EXTRA); int recipient = intent.getIntExtra(EXTRA_RECIPIENT, NO_REPLY_EXTRA); // Synchronously send the mail or reply // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, (replyTo == NO_REPLY_EXTRA ? "Now sending mail to " : "Now sending reply to " + replyTo + " to ") + sendTo); Intent recoverIntent = new Intent(getApplicationContext(), Home_.class); recoverIntent.replaceExtras(intent.getExtras()); recoverIntent.setAction(ACTION_SENDMAIL); createNotification(NOTIFY_SENDMAIL, getString(R.string.mail_sendingmail), getString((replyTo == NO_REPLY_EXTRA ? R.string.mail_sendingto : R.string.mail_replyingto), sendTo), true, recoverIntent, sendTo, NO_BEER_EXTRA); CommandResult result; if (replyTo == NO_REPLY_EXTRA) result = new SendBeerMailCommand(user, sendTo, subject, body).execute(apiConnection); else result = new SendBeerReplyCommand(user, replyTo, recipient, body).execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_SENDMAIL); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Sending of mail to " + sendTo + " failed: " + e); createNotification(NOTIFY_SENDMAIL, getString(R.string.mail_sendingmail), getString(R.string.error_commandfailed), true, recoverIntent, sendTo, NO_BEER_EXTRA); } } // Upload photo of a beer if (intent.getAction().equals(ACTION_UPLOADBEERPHOTO)) { // Get photo URI and beer id and name File photo = (File) intent.getSerializableExtra(EXTRA_PHOTO); int beerId = intent.getIntExtra(EXTRA_BEERID, NO_BEER_EXTRA); String beerName = intent.getStringExtra(EXTRA_BEERNAME); if (beerName == null) { beerName = "beer with ID " + Integer.toString(beerId); } if (photo == null || photo.getPath() == null || !(new File(photo.getPath()).exists())) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "No photo URI provided or the photo URI does not point to an existing file; cancelling"); return; } // Synchronously upload the photo for the specified beer // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Uploading photo for " + beerName); Intent recoverIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(String.format(URI_BEER, Integer.toString(beerId)))); createNotification(NOTIFY_UPLOADPHOTO, getString(R.string.app_uploadingphoto), getString(R.string.app_photofor, beerName), true, recoverIntent, null, beerId); // Make sure the photo is no bigger than 50kB try { decodeFile(photo); } catch (IOException e1) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Resizing of photo + " + photo.toString() + " for " + beerName + " failed: " + e1); createNotification(NOTIFY_UPLOADPHOTO, getString(R.string.app_uploadingphoto), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_FAILURE); return; } // Start actual upload of the now-resized file CommandResult result = new UploadBeerPhotoCommand(user, beerId, photo).execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_UPLOADPHOTO); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_SUCCESS); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Uploading photo for " + beerName + " failed: " + e); createNotification(NOTIFY_UPLOADPHOTO, getString(R.string.app_uploadingphoto), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); // If requested, call back the messenger, i.e. the calling activity callbackMessenger(intent, RESULT_FAILURE); } } // Try to add a UPC code to some selected beer if (intent.getAction().equals(ACTION_ADDUPCCODE)) { // Get beer and upc code int beerId = intent.getIntExtra(EXTRA_BEERID, -1); String beerName = intent.getStringExtra(EXTRA_BEERNAME); String upcCode = intent.getStringExtra(EXTRA_UPCCODE); if (beerId <= 0 || beerName == null || upcCode == null || upcCode.equals("")) { Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Missing extras in the ADD_UPCCODE intent; cancelling."); return; } // Synchronously call the add UPC code method // During the operation a notification will be shown Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Adding barcode " + upcCode + " to " + beerName); Intent recoverIntent = new Intent(getApplicationContext(), Home_.class); recoverIntent.replaceExtras(intent.getExtras()); recoverIntent.setAction(ACTION_ADDUPCCODE); createNotification(NOTIFY_ADDUPCCODE, getString(R.string.app_addingupccode), getString(R.string.app_addingcodefor, beerName), true, recoverIntent, null, beerId); CommandResult result = new AddUpcCodeCommand(user, beerId, upcCode).execute(apiConnection); if (result instanceof CommandSuccessResult) { notificationManager.cancel(NOTIFY_ADDUPCCODE); } else { String e = result instanceof CommandFailureResult ? ((CommandFailureResult) result).getException().toString() : "Unknown error"; Log.d(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Adding of barcode " + upcCode + " to " + beerName + " failed: " + e); createNotification(NOTIFY_ADDUPCCODE, getString(R.string.app_addingupccode), getString(R.string.error_commandfailed), true, recoverIntent, null, beerId); } } } private void decodeFile(File f) throws IOException { // See http://stackoverflow.com/a/3549021/243165 // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; FileInputStream fis = new FileInputStream(f); BitmapFactory.decodeStream(fis, null, o); fis.close(); int scale = 1; if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) { scale = (int) Math.pow(2, (int) Math .round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; fis = new FileInputStream(f); Bitmap b = BitmapFactory.decodeStream(fis, null, o2); fis.close(); // Write bitmap to the desired output file // See http://stackoverflow.com/a/673014/243165 FileOutputStream out = new FileOutputStream(f); b.compress(Bitmap.CompressFormat.JPEG, 80, out); out.close(); } private void callbackMessenger(Intent intent, int result) { if (intent.hasExtra(EXTRA_MESSENGER)) { // Prepare a message Messenger callback = intent.getParcelableExtra(EXTRA_MESSENGER); Message msg = Message.obtain(); msg.arg1 = result; try { // Send it back to the messenger, i.e. the activity callback.send(msg); } catch (RemoteException e) { Log.e(com.ratebeer.android.gui.components.helpers.Log.LOG_NAME, "Cannot call back to activity to deliver message '" + msg.toString() + "'"); } } } private void createNotification(int id, String line1, String line2, boolean autoCancel, Intent contentIntent, String username, int beerId) { // User/beer image to show? Bitmap avatar = null; try { if (username != null) avatar = BitmapFactory.decodeStream(apiConnection.getRaw(ImageUrls.getUserPhotoUrl(username))); if (beerId > 0) avatar = BitmapFactory.decodeStream(apiConnection.getRaw(ImageUrls.getBeerPhotoUrl(beerId))); } catch (Exception e) { // Could not load? Just don't show an image } // Set up notification with user/beer image and two lines of text (and optionally an intent) Builder builder = new NotificationCompat.Builder(getApplicationContext()); builder.setSmallIcon(R.drawable.ic_stat_notification); if (avatar != null) builder.setLargeIcon(avatar); builder.setTicker(line1); builder.setContentTitle(line1); builder.setContentText(line2); builder.setAutoCancel(autoCancel); builder.setContentIntent(PendingIntent.getActivity(this, 0, contentIntent, 0)); // Send notification Notification notification = builder.build(); notificationManager.notify(id, notification); } }