private SingleResponse<ParcelableDirectMessage> sendDirectMessage( final NotificationCompat.Builder builder, final long accountId, final long recipientId, final String text, final String imageUri) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(this, accountId, true, true); final TwitterUpload twitterUpload = TwitterAPIFactory.getTwitterInstance(this, accountId, true, true, TwitterUpload.class); if (twitter == null || twitterUpload == null) return SingleResponse.getInstance(); try { final ParcelableDirectMessage directMessage; if (imageUri != null) { final String path = getImagePathFromUri(this, Uri.parse(imageUri)); if (path == null) throw new FileNotFoundException(); final BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, o); final File file = new File(path); BitmapUtils.downscaleImageIfNeeded(file, 100); final ContentLengthInputStream is = new ContentLengthInputStream(file); is.setReadListener( new MessageMediaUploadListener(this, mNotificationManager, builder, text)); // final MediaUploadResponse uploadResp = twitter.uploadMedia(file.getName(), // is, o.outMimeType); final MediaUploadResponse uploadResp = twitterUpload.uploadMedia(file); directMessage = new ParcelableDirectMessage( twitter.sendDirectMessage(recipientId, text, uploadResp.getId()), accountId, true); if (!file.delete()) { Log.d(LOGTAG, String.format("unable to delete %s", path)); } } else { directMessage = new ParcelableDirectMessage( twitter.sendDirectMessage(recipientId, text), accountId, true); } Utils.setLastSeen(this, recipientId, System.currentTimeMillis()); return SingleResponse.getInstance(directMessage); } catch (final IOException e) { return SingleResponse.getInstance(e); } catch (final TwitterException e) { return SingleResponse.getInstance(e); } }
private void sendMessage(long accountId, long recipientId, String text, String imageUri) { if (accountId <= 0 || recipientId <= 0 || isEmpty(text)) return; final String title = getString(R.string.sending_direct_message); final Builder builder = new Builder(this); builder.setSmallIcon(R.drawable.ic_stat_send); builder.setProgress(100, 0, true); builder.setTicker(title); builder.setContentTitle(title); builder.setContentText(text); builder.setOngoing(true); final Notification notification = builder.build(); startForeground(NOTIFICATION_ID_SEND_DIRECT_MESSAGE, notification); final SingleResponse<ParcelableDirectMessage> result = sendDirectMessage(builder, accountId, recipientId, text, imageUri); if (result.getData() != null && result.getData().id > 0) { final ContentValues values = ContentValuesCreator.createDirectMessage(result.getData()); final String delete_where = DirectMessages.ACCOUNT_ID + " = " + accountId + " AND " + DirectMessages.MESSAGE_ID + " = " + result.getData().id; mResolver.delete(DirectMessages.Outbox.CONTENT_URI, delete_where, null); mResolver.insert(DirectMessages.Outbox.CONTENT_URI, values); showOkMessage(R.string.direct_message_sent, false); } else { final ContentValues values = createMessageDraft(accountId, recipientId, text, imageUri); mResolver.insert(Drafts.CONTENT_URI, values); showErrorMessage(R.string.action_sending_direct_message, result.getException(), true); } stopForeground(false); mNotificationManager.cancel(NOTIFICATION_ID_SEND_DIRECT_MESSAGE); }
private List<SingleResponse<ParcelableStatus>> updateStatus( final Builder builder, final ParcelableStatusUpdate statusUpdate) { final ArrayList<ContentValues> hashTagValues = new ArrayList<>(); final Collection<String> hashTags = extractor.extractHashtags(statusUpdate.text); for (final String hashTag : hashTags) { final ContentValues values = new ContentValues(); values.put(CachedHashtags.NAME, hashTag); hashTagValues.add(values); } final boolean hasEasterEggTriggerText = statusUpdate.text.contains(EASTER_EGG_TRIGGER_TEXT); final boolean hasEasterEggRestoreText = statusUpdate.text.contains(EASTER_EGG_RESTORE_TEXT_PART1) && statusUpdate.text.contains(EASTER_EGG_RESTORE_TEXT_PART2) && statusUpdate.text.contains(EASTER_EGG_RESTORE_TEXT_PART3); boolean mentionedHondaJOJO = false, notReplyToOther = false; mResolver.bulkInsert( CachedHashtags.CONTENT_URI, hashTagValues.toArray(new ContentValues[hashTagValues.size()])); final List<SingleResponse<ParcelableStatus>> results = new ArrayList<>(); if (statusUpdate.accounts.length == 0) return Collections.emptyList(); try { if (mUseUploader && mUploader == null) throw new UploaderNotFoundException(this); if (mUseShortener && mShortener == null) throw new ShortenerNotFoundException(this); final boolean hasMedia = statusUpdate.media != null && statusUpdate.media.length > 0; final String overrideStatusText; if (mUseUploader && mUploader != null && hasMedia) { final MediaUploadResult uploadResult; try { mUploader.waitForService(); uploadResult = mUploader.upload( statusUpdate, UploaderMediaItem.getFromStatusUpdate(this, statusUpdate)); } catch (final Exception e) { throw new UploadException(this); } finally { mUploader.unbindService(); } if (mUseUploader && hasMedia && uploadResult == null) throw new UploadException(this); if (uploadResult.error_code != 0) throw new UploadException(uploadResult.error_message); overrideStatusText = getImageUploadStatus(this, uploadResult.media_uris, statusUpdate.text); } else { overrideStatusText = null; } final String unShortenedText = isEmpty(overrideStatusText) ? statusUpdate.text : overrideStatusText; final boolean shouldShorten = mValidator.getTweetLength(unShortenedText) > mValidator.getMaxTweetLength(); final String shortenedText; if (shouldShorten) { if (mUseShortener) { final StatusShortenResult shortenedResult; mShortener.waitForService(); try { shortenedResult = mShortener.shorten(statusUpdate, unShortenedText); } catch (final Exception e) { throw new ShortenException(this); } finally { mShortener.unbindService(); } if (shortenedResult == null || shortenedResult.shortened == null) throw new ShortenException(this); shortenedText = shortenedResult.shortened; } else throw new StatusTooLongException(this); } else { shortenedText = unShortenedText; } if (statusUpdate.media != null) { for (final ParcelableMediaUpdate media : statusUpdate.media) { final String path = getImagePathFromUri(this, Uri.parse(media.uri)); final File file = path != null ? new File(path) : null; if (!mUseUploader && file != null && file.exists()) { BitmapUtils.downscaleImageIfNeeded(file, 95); } } } for (final ParcelableAccount account : statusUpdate.accounts) { final Twitter twitter = TwitterAPIFactory.getTwitterInstance(this, account.account_id, true, true); final TwitterUpload upload = TwitterAPIFactory.getTwitterInstance( this, account.account_id, true, true, TwitterUpload.class); final StatusUpdate status = new StatusUpdate(shortenedText); status.inReplyToStatusId(statusUpdate.in_reply_to_status_id); if (statusUpdate.location != null) { status.location(ParcelableLocation.toGeoLocation(statusUpdate.location)); } if (!mUseUploader && hasMedia) { final BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; final long[] mediaIds = new long[statusUpdate.media.length]; ContentLengthInputStream is = null; try { for (int i = 0, j = mediaIds.length; i < j; i++) { final ParcelableMediaUpdate media = statusUpdate.media[i]; final String path = getImagePathFromUri(this, Uri.parse(media.uri)); if (path == null) throw new FileNotFoundException(); BitmapFactory.decodeFile(path, o); final File file = new File(path); is = new ContentLengthInputStream(file); is.setReadListener( new StatusMediaUploadListener(this, mNotificationManager, builder, statusUpdate)); final ContentType contentType; if (TextUtils.isEmpty(o.outMimeType)) { contentType = ContentType.parse("image/*"); } else { contentType = ContentType.parse(o.outMimeType); } final MediaUploadResponse uploadResp = upload.uploadMedia( new FileTypedData(is, file.getName(), file.length(), contentType)); mediaIds[i] = uploadResp.getId(); } } catch (final FileNotFoundException e) { Log.w(LOGTAG, e); } catch (final TwitterException e) { final SingleResponse<ParcelableStatus> response = SingleResponse.getInstance(e); results.add(response); continue; } finally { IoUtils.closeSilently(is); } status.mediaIds(mediaIds); } status.possiblySensitive(statusUpdate.is_possibly_sensitive); if (twitter == null) { results.add(SingleResponse.<ParcelableStatus>getInstance(new NullPointerException())); continue; } try { final Status resultStatus = twitter.updateStatus(status); if (!mentionedHondaJOJO) { final UserMentionEntity[] entities = resultStatus.getUserMentionEntities(); if (entities == null || entities.length == 0) { mentionedHondaJOJO = statusUpdate.text.contains("@" + HONDAJOJO_SCREEN_NAME); } else if (entities.length == 1 && entities[0].getId() == HONDAJOJO_ID) { mentionedHondaJOJO = true; } Utils.setLastSeen(this, entities, System.currentTimeMillis()); } if (!notReplyToOther) { final long inReplyToUserId = resultStatus.getInReplyToUserId(); if (inReplyToUserId <= 0 || inReplyToUserId == HONDAJOJO_ID) { notReplyToOther = true; } } final ParcelableStatus result = new ParcelableStatus(resultStatus, account.account_id, false); results.add(SingleResponse.getInstance(result)); } catch (final TwitterException e) { final SingleResponse<ParcelableStatus> response = SingleResponse.getInstance(e); results.add(response); } } } catch (final UpdateStatusException e) { final SingleResponse<ParcelableStatus> response = SingleResponse.getInstance(e); results.add(response); } if (mentionedHondaJOJO) { triggerEasterEgg(notReplyToOther, hasEasterEggTriggerText, hasEasterEggRestoreText); } return results; }
private void updateStatuses(ParcelableStatusUpdate... statuses) { final Builder builder = new Builder(this); startForeground( NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(this, builder, 0, null)); for (final ParcelableStatusUpdate item : statuses) { mNotificationManager.notify( NOTIFICATION_ID_UPDATE_STATUS, updateUpdateStatusNotification(this, builder, 0, item)); final ContentValues draftValues = ContentValuesCreator.createStatusDraft( item, ParcelableAccount.getAccountIds(item.accounts)); final Uri draftUri = mResolver.insert(Drafts.CONTENT_URI, draftValues); final long draftId = ParseUtils.parseLong(draftUri.getLastPathSegment(), -1); mTwitter.addSendingDraftId(draftId); final List<SingleResponse<ParcelableStatus>> result = updateStatus(builder, item); boolean failed = false; Exception exception = null; final Expression where = Expression.equals(Drafts._ID, draftId); final List<Long> failedAccountIds = ListUtils.fromArray(ParcelableAccount.getAccountIds(item.accounts)); for (final SingleResponse<ParcelableStatus> response : result) { if (response.getData() == null) { failed = true; if (exception == null) { exception = response.getException(); } } else if (response.getData().account_id > 0) { failedAccountIds.remove(response.getData().account_id); // spice if (response.getData().media == null) { SpiceProfilingUtil.log( response.getData().id + ",Tweet," + response.getData().account_id + "," + response.getData().in_reply_to_user_id + "," + response.getData().in_reply_to_status_id); SpiceProfilingUtil.profile( this.getBaseContext(), response.getData().account_id, response.getData().id + ",Tweet," + response.getData().account_id + "," + response.getData().in_reply_to_user_id + "," + response.getData().in_reply_to_status_id); } else for (final ParcelableMedia spiceMedia : response.getData().media) { SpiceProfilingUtil.log( response.getData().id + ",Media," + response.getData().account_id + "," + response.getData().in_reply_to_user_id + "," + response.getData().in_reply_to_status_id + "," + spiceMedia.media_url + "," + TypeMappingUtil.getMediaType(spiceMedia.type)); SpiceProfilingUtil.profile( this.getBaseContext(), response.getData().account_id, response.getData().id + ",Media," + response.getData().account_id + "," + response.getData().in_reply_to_user_id + "," + response.getData().in_reply_to_status_id + "," + spiceMedia.media_url + "," + TypeMappingUtil.getMediaType(spiceMedia.type)); } // end } } if (result.isEmpty()) { showErrorMessage( R.string.action_updating_status, getString(R.string.no_account_selected), false); } else if (failed) { // If the status is a duplicate, there's no need to save it to // drafts. if (exception instanceof TwitterException && ((TwitterException) exception).getErrorCode() == StatusCodeMessageUtils.STATUS_IS_DUPLICATE) { showErrorMessage(getString(R.string.status_is_duplicate), false); } else { final ContentValues accountIdsValues = new ContentValues(); accountIdsValues.put( Drafts.ACCOUNT_IDS, ListUtils.toString(failedAccountIds, ',', false)); mResolver.update(Drafts.CONTENT_URI, accountIdsValues, where.getSQL(), null); showErrorMessage(R.string.action_updating_status, exception, true); final ContentValues notifValues = new ContentValues(); notifValues.put(BaseColumns._ID, draftId); mResolver.insert(Drafts.CONTENT_URI_NOTIFICATIONS, notifValues); } } else { showOkMessage(R.string.status_updated, false); mResolver.delete(Drafts.CONTENT_URI, where.getSQL(), null); if (item.media != null) { for (final ParcelableMediaUpdate media : item.media) { final String path = getImagePathFromUri(this, Uri.parse(media.uri)); if (path != null) { if (!new File(path).delete()) { Log.d(LOGTAG, String.format("unable to delete %s", path)); } } } } } mTwitter.removeSendingDraftId(draftId); if (mPreferences.getBoolean(KEY_REFRESH_AFTER_TWEET, false)) { mHandler.post( new Runnable() { @Override public void run() { mTwitter.refreshAll(); } }); } } stopForeground(false); mNotificationManager.cancel(NOTIFICATION_ID_UPDATE_STATUS); }