Java tutorial
/* * Tweetings - Twitter client for Android * * Copyright (C) 2012-2013 RBD Solutions Limited <apps@tweetings.net> * Copyright (C) 2012 Mariotaku Lee <mariotaku.lee@gmail.com> * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package com.dwdesign.tweetings.service; import static com.dwdesign.tweetings.util.Utils.buildQueryUri; import static com.dwdesign.tweetings.util.Utils.getAccountUsername; import static com.dwdesign.tweetings.util.Utils.getActivatedAccountIds; import static com.dwdesign.tweetings.util.Utils.getAllStatusesIds; import static com.dwdesign.tweetings.util.Utils.getImagePathFromUri; import static com.dwdesign.tweetings.util.Utils.getImageUploadStatus; import static com.dwdesign.tweetings.util.Utils.getTwitterInstance; import static com.dwdesign.tweetings.util.Utils.hasActiveConnection; import static com.dwdesign.tweetings.util.Utils.isNullOrEmpty; import static com.dwdesign.tweetings.util.Utils.getNewestMessageIdsFromDatabase; import static com.dwdesign.tweetings.util.Utils.getNewestStatusIdsFromDatabase; import static com.dwdesign.tweetings.util.Utils.makeCachedUserContentValues; import static com.dwdesign.tweetings.util.Utils.makeDirectMessageContentValues; import static com.dwdesign.tweetings.util.Utils.makeStatusContentValues; import static com.dwdesign.tweetings.util.Utils.makeTrendsContentValues; import static com.dwdesign.tweetings.util.Utils.notifyForUpdatedUri; import static com.dwdesign.tweetings.util.Utils.parseInt; import static com.dwdesign.tweetings.util.Utils.parseString; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.lang.ref.WeakReference; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.TimeZone; import java.util.Timer; import java.util.TimerTask; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.dwdesign.tweetings.Constants; import com.dwdesign.tweetings.HttpClientFactory; import com.dwdesign.tweetings.ITweetingsService; import com.dwdesign.tweetings.R; import com.dwdesign.tweetings.activity.HomeActivity; import com.dwdesign.tweetings.app.TweetingsApplication; import com.dwdesign.tweetings.provider.TweetStore; import com.dwdesign.tweetings.provider.TweetStore.CachedTrends; import com.dwdesign.tweetings.provider.TweetStore.CachedUsers; import com.dwdesign.tweetings.provider.TweetStore.DirectMessages; import com.dwdesign.tweetings.provider.TweetStore.Drafts; import com.dwdesign.tweetings.provider.TweetStore.Mentions; import com.dwdesign.tweetings.provider.TweetStore.Statuses; import com.dwdesign.tweetings.util.AsyncTaskManager; import com.dwdesign.tweetings.util.ImageUploaderInterface; import com.dwdesign.tweetings.util.ListUtils; import com.dwdesign.tweetings.util.ManagedAsyncTask; import com.dwdesign.tweetings.util.TweetShortenerInterface; import com.dwdesign.tweetings.util.Utils; import twitter4j.DirectMessage; import twitter4j.GeoLocation; import twitter4j.Paging; import twitter4j.RateLimitStatus; import twitter4j.ResponseList; import twitter4j.Status; import twitter4j.StatusUpdate; import twitter4j.Trends; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.User; import twitter4j.UserList; import twitter4j.auth.AccessToken; import twitter4j.auth.Authorization; import twitter4j.auth.OAuthAuthorization; import twitter4j.internal.http.HttpClientWrapper; import twitter4j.internal.http.HttpParameter; import android.app.Activity; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.database.Cursor; import android.location.Location; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.SoundPool; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; import android.provider.Settings; import android.provider.Settings.Secure; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.RemoteViews; import android.widget.Toast; import com.twitter.Validator; public class TweetingsService extends Service implements Constants { private final ServiceStub mBinder = new ServiceStub(this); private AsyncTaskManager mAsyncTaskManager; private SharedPreferences mPreferences; private NotificationManager mNotificationManager; private AlarmManager mAlarmManager; private ContentResolver mResolver; private MediaPlayer mPlayer; private int activityCount = 1; private int mGetHomeTimelineTaskId, mGetMentionsTaskId; private int mStoreStatusesTaskId, mStoreMentionsTaskId; private int mGetReceivedDirectMessagesTaskId, mGetSentDirectMessagesTaskId; private int mStoreReceivedDirectMessagesTaskId, mStoreSentDirectMessagesTaskId; private int mGetLocalTrendsTaskId, mGetWeeklyTrendsTaskId, mGetDailyTrendsTaskId; private int mStoreLocalTrendsTaskId, mStoreWeeklyTrendsTaskId, mStoreDailyTrendsTaskId; private boolean mBatteryLow = false; private boolean mShouldShutdown = false; private int mNewMessagesCount, mNewMentionsCount, mNewStatusesCount; private PendingIntent mPendingRefreshHomeTimelineIntent, mPendingRefreshMentionsIntent, mPendingRefreshDirectMessagesIntent; private BroadcastReceiver mStateReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); if (BROADCAST_REFRESHSTATE_CHANGED.equals(action)) { if (!mAsyncTaskManager.hasActivatedTask() && mShouldShutdown) { stopSelf(); } } else if (Intent.ACTION_BATTERY_LOW.equals(action)) { mBatteryLow = true; } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) { mBatteryLow = false; } else if (BROADCAST_NOTIFICATION_CLEARED.equals(action)) { final Bundle extras = intent.getExtras(); if (extras != null && extras.containsKey(INTENT_KEY_NOTIFICATION_ID)) { clearNotification(extras.getInt(INTENT_KEY_NOTIFICATION_ID)); } } else if (hasActiveConnection(context) && !(mBatteryLow && mPreferences.getBoolean(PREFERENCE_KEY_STOP_AUTO_REFRESH_WHEN_BATTERY_LOW, true))) { if (BROADCAST_REFRESH_HOME_TIMELINE.equals(action)) { final long[] activated_ids = getActivatedAccountIds(context); if (mPreferences.getBoolean(PREFERENCE_KEY_REFRESH_ENABLE_HOME_TIMELINE, false)) { if (!isHomeTimelineRefreshing()) { getHomeTimeline(activated_ids, null, true); } } } else if (BROADCAST_REFRESH_MENTIONS.equals(action)) { final long[] activated_ids = getActivatedAccountIds(context); if (mPreferences.getBoolean(PREFERENCE_KEY_REFRESH_ENABLE_MENTIONS, false)) { if (!isMentionsRefreshing()) { getMentions(activated_ids, null, true); } } } else if (BROADCAST_REFRESH_DIRECT_MESSAGES.equals(action)) { final long[] activated_ids = getActivatedAccountIds(context); if (mPreferences.getBoolean(PREFERENCE_KEY_REFRESH_ENABLE_DIRECT_MESSAGES, false)) { if (!isReceivedDirectMessagesRefreshing()) { getReceivedDirectMessages(activated_ids, null, true); } } } } } }; public void cancelShutdown() { mShouldShutdown = false; } public int addUserListMember(final long account_id, final int list_id, final long user_id, final String screen_name) { final AddUserListMemberTask task = new AddUserListMemberTask(account_id, list_id, user_id, screen_name); return mAsyncTaskManager.add(task, true); } public void clearNotification(final int id) { switch (id) { case NOTIFICATION_ID_HOME_TIMELINE: { mNewStatusesCount = 0; break; } case NOTIFICATION_ID_MENTIONS: { mNewMentionsCount = 0; break; } case NOTIFICATION_ID_DIRECT_MESSAGES: { mNewMessagesCount = 0; break; } } mNotificationManager.cancel(id); } public int createBlock(final long account_id, final long user_id) { final CreateBlockTask task = new CreateBlockTask(account_id, user_id); return mAsyncTaskManager.add(task, true); } public int createFavorite(final long account_id, final long status_id) { final CreateFavoriteTask task = new CreateFavoriteTask(account_id, status_id); return mAsyncTaskManager.add(task, true); } public int createFriendship(final long account_id, final long user_id) { final CreateFriendshipTask task = new CreateFriendshipTask(account_id, user_id); return mAsyncTaskManager.add(task, true); } public int createMultiBlock(final long account_id, final long[] user_ids) { final CreateMultiBlockTask task = new CreateMultiBlockTask(account_id, user_ids); return mAsyncTaskManager.add(task, true); } public int createUserList(final long account_id, final String list_name, final boolean is_public, final String description) { final CreateUserListTask task = new CreateUserListTask(account_id, list_name, is_public, description); return mAsyncTaskManager.add(task, true); } public int createUserListSubscription(final long account_id, final int list_id) { final CreateUserListSubscriptionTask task = new CreateUserListSubscriptionTask(account_id, list_id); return mAsyncTaskManager.add(task, true); } public int deleteUserListMember(final long account_id, final int list_id, final long user_id) { final DeleteUserListMemberTask task = new DeleteUserListMemberTask(account_id, list_id, user_id); return mAsyncTaskManager.add(task, true); } public int destroyBlock(final long account_id, final long user_id) { final DestroyBlockTask task = new DestroyBlockTask(account_id, user_id); return mAsyncTaskManager.add(task, true); } public int destroyDirectMessage(final long account_id, final long message_id) { final DestroyDirectMessageTask task = new DestroyDirectMessageTask(account_id, message_id); return mAsyncTaskManager.add(task, true); } public int destroyFavorite(final long account_id, final long status_id) { final DestroyFavoriteTask task = new DestroyFavoriteTask(account_id, status_id); return mAsyncTaskManager.add(task, true); } public int destroyFriendship(long account_id, final long user_id) { final DestroyFriendshipTask task = new DestroyFriendshipTask(account_id, user_id); return mAsyncTaskManager.add(task, true); } public int destroyStatus(final long account_id, final long status_id) { final DestroyStatusTask task = new DestroyStatusTask(account_id, status_id); return mAsyncTaskManager.add(task, true); } public int destroySavedSearch(final long account_id, final int search_id) { final DestroySavedSearchTask task = new DestroySavedSearchTask(account_id, search_id); return mAsyncTaskManager.add(task, true); } public int createSavedSearch(final long account_id, final String query) { final CreateSavedSearchTask task = new CreateSavedSearchTask(account_id, query); return mAsyncTaskManager.add(task, true); } public int destroyUserList(final long account_id, final int list_id) { final DestroyUserListTask task = new DestroyUserListTask(account_id, list_id); return mAsyncTaskManager.add(task, true); } public int destroyUserListSubscription(final long account_id, final int list_id) { final DestroyUserListSubscriptionTask task = new DestroyUserListSubscriptionTask(account_id, list_id); return mAsyncTaskManager.add(task, true); } public int getDailyTrends(final long account_id) { mAsyncTaskManager.cancel(mGetDailyTrendsTaskId); final GetDailyTrendsTask task = new GetDailyTrendsTask(account_id); return mGetDailyTrendsTaskId = mAsyncTaskManager.add(task, true); } public int insertStreamToHomeTimeline(final long account_id, final Intent intent) { final String action = intent.getAction(); if (BROADCAST_STREAM_STATUS_RECEIVED.equals(action)) { twitter4j.Status status = (twitter4j.Status) intent.getExtras().get("status"); List<twitter4j.Status> statuses = new ArrayList<twitter4j.Status>(); statuses.add(status); ListResponse<twitter4j.Status> result = new ListResponse<twitter4j.Status>(account_id, 0, 0, statuses, null); List<ListResponse<twitter4j.Status>> result2 = new ArrayList<ListResponse<twitter4j.Status>>(); result2.add(result); try { return mAsyncTaskManager.add(new StoreHomeTimelineTask(result2, false, false), true); } catch (Exception e) { return -1; } } return -1; } public int insertStreamToMentions(final long account_id, final Intent intent) { final String action = intent.getAction(); if (BROADCAST_STREAM_STATUS_RECEIVED.equals(action)) { twitter4j.Status status = (twitter4j.Status) intent.getExtras().get("status"); List<twitter4j.Status> statuses = new ArrayList<twitter4j.Status>(); statuses.add(status); ListResponse<twitter4j.Status> result = new ListResponse<twitter4j.Status>(account_id, 0, 0, statuses, null); List<ListResponse<twitter4j.Status>> result2 = new ArrayList<ListResponse<twitter4j.Status>>(); result2.add(result); try { return mAsyncTaskManager.add(new StoreMentionsTask(result2, false, false), true); } catch (Exception e) { return -1; } } return -1; } public int insertStreamToInbox(final long account_id, final Intent intent) { final String action = intent.getAction(); if (BROADCAST_STREAM_STATUS_RECEIVED.equals(action)) { twitter4j.DirectMessage dm = (twitter4j.DirectMessage) intent.getExtras().get("status"); List<twitter4j.DirectMessage> statuses = new ArrayList<twitter4j.DirectMessage>(); statuses.add(dm); ListResponse<twitter4j.DirectMessage> result = new ListResponse<twitter4j.DirectMessage>(account_id, 0, 0, statuses, null); List<ListResponse<twitter4j.DirectMessage>> result2 = new ArrayList<ListResponse<twitter4j.DirectMessage>>(); result2.add(result); try { return mAsyncTaskManager.add(new StoreReceivedDirectMessagesTask(result2, false), true); } catch (Exception e) { return -1; } } return -1; } public int getHomeTimeline(final long[] account_ids, final long[] max_ids) { final boolean notification = mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_HOME_TIMELINE, false); return getHomeTimeline(account_ids, max_ids, notification); } public int getHomeTimelineWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { final boolean notification = mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_HOME_TIMELINE, false); return getHomeTimelineWithSinceId(account_ids, max_ids, since_ids, notification); } public int getLocalTrends(final long account_id, final int woeid) { mAsyncTaskManager.cancel(mGetLocalTrendsTaskId); final GetLocalTrendsTask task = new GetLocalTrendsTask(account_id, woeid); return mGetLocalTrendsTaskId = mAsyncTaskManager.add(task, true); } public String generateOAuthEchoHeader(final long account_id) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { Authorization authorization = twitter.getAuthorization(); if (!(authorization instanceof OAuthAuthorization)) { throw new IllegalArgumentException("OAuth authorization is required."); } OAuthAuthorization oauth = (OAuthAuthorization) authorization; List<HttpParameter> oauthSignatureParams = oauth.generateOAuthSignatureHttpParams("GET", TWITTER_VERIFY_CREDENTIALS_JSON); return "OAuth realm=\"http://api.twitter.com/\"," + OAuthAuthorization.encodeParameters(oauthSignatureParams, ",", true); } return null; } public int getMentions(final long[] account_ids, final long[] max_ids) { final boolean notification = mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_MENTIONS, false) && max_ids == null; return getMentions(account_ids, max_ids, notification); } public int getMentionsWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { final boolean notification = mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_MENTIONS, false) && max_ids == null; return getMentionsWithSinceId(account_ids, max_ids, since_ids, notification); } public int getReceivedDirectMessages(final long[] account_ids, final long[] max_ids) { final boolean notification = mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_DIRECT_MESSAGES, false) && max_ids == null; return getReceivedDirectMessages(account_ids, max_ids, notification); } public int getReceivedDirectMessagesWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { final boolean notification = mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_DIRECT_MESSAGES, false) && max_ids == null; return getReceivedDirectMessagesWithSinceId(account_ids, max_ids, since_ids, notification); } public int getSentDirectMessages(final long[] account_ids, final long[] max_ids) { mAsyncTaskManager.cancel(mGetSentDirectMessagesTaskId); final GetSentDirectMessagesTask task = new GetSentDirectMessagesTask(account_ids, max_ids, null); return mGetSentDirectMessagesTaskId = mAsyncTaskManager.add(task, true); } public int getSentDirectMessagesWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { mAsyncTaskManager.cancel(mGetSentDirectMessagesTaskId); final GetSentDirectMessagesTask task = new GetSentDirectMessagesTask(account_ids, max_ids, since_ids); return mGetSentDirectMessagesTaskId = mAsyncTaskManager.add(task, true); } public int getWeeklyTrends(final long account_id) { mAsyncTaskManager.cancel(mGetWeeklyTrendsTaskId); final GetWeeklyTrendsTask task = new GetWeeklyTrendsTask(account_id); return mGetWeeklyTrendsTaskId = mAsyncTaskManager.add(task, true); } public boolean hasActivatedTask() { return mAsyncTaskManager.hasActivatedTask(); } public boolean isDailyTrendsRefreshing() { return mAsyncTaskManager.isExcuting(mGetDailyTrendsTaskId) || mAsyncTaskManager.isExcuting(mStoreDailyTrendsTaskId); } public boolean isHomeTimelineRefreshing() { return mAsyncTaskManager.isExcuting(mGetHomeTimelineTaskId) || mAsyncTaskManager.isExcuting(mStoreStatusesTaskId); } public boolean isLocalTrendsRefreshing() { return mAsyncTaskManager.isExcuting(mGetLocalTrendsTaskId) || mAsyncTaskManager.isExcuting(mStoreLocalTrendsTaskId); } public boolean isMentionsRefreshing() { return mAsyncTaskManager.isExcuting(mGetMentionsTaskId) || mAsyncTaskManager.isExcuting(mStoreMentionsTaskId); } public boolean isReceivedDirectMessagesRefreshing() { return mAsyncTaskManager.isExcuting(mGetReceivedDirectMessagesTaskId) || mAsyncTaskManager.isExcuting(mStoreReceivedDirectMessagesTaskId); } public boolean isSentDirectMessagesRefreshing() { return mAsyncTaskManager.isExcuting(mGetSentDirectMessagesTaskId) || mAsyncTaskManager.isExcuting(mStoreSentDirectMessagesTaskId); } public boolean isWeeklyTrendsRefreshing() { return mAsyncTaskManager.isExcuting(mGetWeeklyTrendsTaskId) || mAsyncTaskManager.isExcuting(mStoreWeeklyTrendsTaskId); } @Override public IBinder onBind(final Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mAsyncTaskManager = ((TweetingsApplication) getApplication()).getAsyncTaskManager(); mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE); mResolver = getContentResolver(); mPendingRefreshHomeTimelineIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_HOME_TIMELINE), 0); mPendingRefreshMentionsIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_MENTIONS), 0); mPendingRefreshDirectMessagesIntent = PendingIntent.getBroadcast(this, 0, new Intent(BROADCAST_REFRESH_DIRECT_MESSAGES), 0); final IntentFilter filter = new IntentFilter(BROADCAST_REFRESHSTATE_CHANGED); filter.addAction(BROADCAST_NOTIFICATION_CLEARED); filter.addAction(BROADCAST_REFRESH_HOME_TIMELINE); filter.addAction(BROADCAST_REFRESH_MENTIONS); filter.addAction(BROADCAST_REFRESH_DIRECT_MESSAGES); filter.addAction(Intent.ACTION_BATTERY_LOW); filter.addAction(Intent.ACTION_BATTERY_OKAY); registerReceiver(mStateReceiver, filter); startAutoRefresh(); } @Override public void onDestroy() { unregisterReceiver(mStateReceiver); mNotificationManager.cancelAll(); if (mPreferences.getBoolean(PREFERENCE_KEY_AUTO_REFRESH, false)) { // Auto refresh enabled, so I will try to start service after it was // stopped. startService(new Intent(INTENT_ACTION_SERVICE)); } super.onDestroy(); } public void incrementActivityCount() { if (this.activityCount == 0) { final Intent intent = new Intent(BROADCAST_BACKGROUND_CHANGED); intent.putExtra(INTENT_KEY_BACKGROUND, false); sendBroadcast(intent); } this.activityCount++; } public void decrementActivityCount() { this.activityCount--; if (this.activityCount == 0) { final Intent intent = new Intent(BROADCAST_BACKGROUND_CHANGED); intent.putExtra(INTENT_KEY_BACKGROUND, true); sendBroadcast(intent); } } public int refreshAll() { final long[] account_ids = getActivatedAccountIds(this); final long[] since_ids = getNewestStatusIdsFromDatabase(this, Mentions.CONTENT_URI); getMentionsWithSinceId(account_ids, null, since_ids); final long[] since_idsDm = getNewestMessageIdsFromDatabase(this, DirectMessages.Inbox.CONTENT_URI); getReceivedDirectMessagesWithSinceId(account_ids, null, since_idsDm); getSentDirectMessagesWithSinceId(account_ids, null, since_idsDm); final long[] since_idsHome = getNewestStatusIdsFromDatabase(this, Statuses.CONTENT_URI); return getHomeTimelineWithSinceId(account_ids, null, since_idsHome); /*final long[] account_ids = getActivatedAccountIds(this); getMentions(account_ids, null); getReceivedDirectMessages(account_ids, null); getSentDirectMessages(account_ids, null); return getHomeTimeline(account_ids, null);*/ } public int reportMultiSpam(final long account_id, final long[] user_ids) { final ReportMultiSpamTask task = new ReportMultiSpamTask(account_id, user_ids); return mAsyncTaskManager.add(task, true); } public int reportSpam(final long account_id, final long user_id) { final ReportSpamTask task = new ReportSpamTask(account_id, user_id); return mAsyncTaskManager.add(task, true); } public int retweetStatus(final long account_id, final long status_id) { final RetweetStatusTask task = new RetweetStatusTask(account_id, status_id); return mAsyncTaskManager.add(task, true); } public int sendDirectMessage(final long account_id, final String screen_name, final long user_id, final String message) { final SendDirectMessageTask task = new SendDirectMessageTask(account_id, screen_name, user_id, message); return mAsyncTaskManager.add(task, true); } public void shutdownService() { // Auto refresh is enabled, so this service cannot be shut down. if (mPreferences.getBoolean(PREFERENCE_KEY_AUTO_REFRESH, false)) return; if (!mAsyncTaskManager.hasActivatedTask()) { stopSelf(); } else { mShouldShutdown = true; } } public boolean startAutoRefresh() { stopAutoRefresh(); if (mPreferences.getBoolean(PREFERENCE_KEY_AUTO_REFRESH, false)) { final long update_interval = parseInt(mPreferences.getString(PREFERENCE_KEY_REFRESH_INTERVAL, "30")) * 60 * 1000; if (update_interval <= 0) return false; mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + update_interval, update_interval, mPendingRefreshHomeTimelineIntent); mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + update_interval, update_interval, mPendingRefreshMentionsIntent); mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + update_interval, update_interval, mPendingRefreshDirectMessagesIntent); return true; } return false; } public void stopAutoRefresh() { mAlarmManager.cancel(mPendingRefreshHomeTimelineIntent); mAlarmManager.cancel(mPendingRefreshMentionsIntent); mAlarmManager.cancel(mPendingRefreshDirectMessagesIntent); } public boolean test() { try { return startService(new Intent(INTENT_ACTION_SERVICE)) != null; } catch (final Exception e) { return false; } } public int updateProfile(final long account_id, final String name, final String url, final String location, final String description) { final UpdateProfileTask task = new UpdateProfileTask(account_id, name, url, location, description); return mAsyncTaskManager.add(task, true); } public int updateProfileImage(final long account_id, final Uri image_uri, final boolean delete_image) { final UpdateProfileImageTask task = new UpdateProfileImageTask(account_id, image_uri, delete_image); return mAsyncTaskManager.add(task, true); } public int updateBannerImage(final long account_id, final Uri image_uri, final boolean delete_image) { final UpdateBannerImageTask task = new UpdateBannerImageTask(account_id, image_uri, delete_image); return mAsyncTaskManager.add(task, true); } public int updateStatus(final long[] account_ids, final String content, final Location location, final Uri image_uri, final long in_reply_to, final boolean is_possibly_sensitive, final boolean delete_image) { final UpdateStatusTask task = new UpdateStatusTask(account_ids, content, location, image_uri, in_reply_to, is_possibly_sensitive, delete_image); return mAsyncTaskManager.add(task, true); } public int scheduleStatus(final String schedule_date, final long[] account_ids, final String content, final Location location, final Uri image_uri, final long in_reply_to, final boolean delete_image) { final ScheduleStatusTask task = new ScheduleStatusTask(schedule_date, account_ids, content, location, image_uri, in_reply_to, delete_image); return mAsyncTaskManager.add(task, true); } public int bufferStatus(final long[] account_ids, final String content) { final BufferStatusTask task = new BufferStatusTask(account_ids, content); return mAsyncTaskManager.add(task, true); } public int updateUserListDetails(final long account_id, final int list_id, final boolean is_public, final String name, final String description) { final UpdateUserListProfileTask task = new UpdateUserListProfileTask(account_id, list_id, is_public, name, description); return mAsyncTaskManager.add(task, true); } private Notification buildNotification(final String title, final String message, final int icon, final Intent content_intent, final Intent delete_intent) { final NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setTicker(message); builder.setContentTitle(title); builder.setContentText(message); builder.setAutoCancel(true); builder.setWhen(System.currentTimeMillis()); builder.setSmallIcon(icon); if (delete_intent != null) { builder.setDeleteIntent( PendingIntent.getBroadcast(this, 0, delete_intent, PendingIntent.FLAG_UPDATE_CURRENT)); } if (content_intent != null) { builder.setContentIntent( PendingIntent.getActivity(this, 0, content_intent, PendingIntent.FLAG_UPDATE_CURRENT)); } int defaults = 0; final Calendar now = Calendar.getInstance(); if (mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_HAVE_SOUND, true) && !mPreferences.getBoolean("silent_notifications_at_" + now.get(Calendar.HOUR_OF_DAY), false)) { Uri soundUri = Uri.parse(mPreferences.getString(PREFERENCE_KEY_NOTIFICATION_RINGTONE, "android.resource://" + getPackageName() + "/" + R.raw.notify)); builder.setSound(soundUri, Notification.STREAM_DEFAULT); } if (mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_HAVE_VIBRATION, true) && !mPreferences.getBoolean("silent_notifications_at_" + now.get(Calendar.HOUR_OF_DAY), false)) { defaults |= Notification.DEFAULT_VIBRATE; } if (mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_HAVE_LIGHTS, true) && !mPreferences.getBoolean("silent_notifications_at_" + now.get(Calendar.HOUR_OF_DAY), false)) { final int color_def = getResources().getColor(R.color.holo_blue_dark); final int color = mPreferences.getInt(PREFERENCE_KEY_NOTIFICATION_LIGHT_COLOR, color_def); builder.setLights(color, 1000, 2000); } builder.setDefaults(defaults); return builder.getNotification(); } private int getHomeTimeline(final long[] account_ids, final long[] max_ids, final boolean is_auto_refresh) { mAsyncTaskManager.cancel(mGetHomeTimelineTaskId); final GetHomeTimelineTask task = new GetHomeTimelineTask(account_ids, max_ids, null, is_auto_refresh); return mGetHomeTimelineTaskId = mAsyncTaskManager.add(task, true); } private int getHomeTimelineWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids, final boolean is_auto_refresh) { mAsyncTaskManager.cancel(mGetHomeTimelineTaskId); final GetHomeTimelineTask task = new GetHomeTimelineTask(account_ids, max_ids, since_ids, is_auto_refresh); return mGetHomeTimelineTaskId = mAsyncTaskManager.add(task, true); } private int getMentions(final long[] account_ids, final long[] max_ids, final boolean is_auto_refresh) { mAsyncTaskManager.cancel(mGetMentionsTaskId); final GetMentionsTask task = new GetMentionsTask(account_ids, max_ids, null, is_auto_refresh); return mGetMentionsTaskId = mAsyncTaskManager.add(task, true); } private int getMentionsWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids, final boolean is_auto_refresh) { mAsyncTaskManager.cancel(mGetMentionsTaskId); final GetMentionsTask task = new GetMentionsTask(account_ids, max_ids, since_ids, is_auto_refresh); return mGetMentionsTaskId = mAsyncTaskManager.add(task, true); } private int getReceivedDirectMessages(final long[] account_ids, final long[] max_ids, final boolean is_auto_refresh) { mAsyncTaskManager.cancel(mGetReceivedDirectMessagesTaskId); final GetReceivedDirectMessagesTask task = new GetReceivedDirectMessagesTask(account_ids, max_ids, null, is_auto_refresh); return mGetReceivedDirectMessagesTaskId = mAsyncTaskManager.add(task, true); } private int getReceivedDirectMessagesWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids, final boolean is_auto_refresh) { mAsyncTaskManager.cancel(mGetReceivedDirectMessagesTaskId); final GetReceivedDirectMessagesTask task = new GetReceivedDirectMessagesTask(account_ids, max_ids, since_ids, is_auto_refresh); return mGetReceivedDirectMessagesTaskId = mAsyncTaskManager.add(task, true); } private void showErrorToast(final int action_res, final Exception e, final boolean long_message) { Utils.showErrorToast(this, getString(action_res), e, long_message); } class AddUserListMemberTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id, user_id; private final int list_id; private final String screen_name; public AddUserListMemberTask(final long account_id, final int list_id, final long user_id, final String screen_name) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.list_id = list_id; this.user_id = user_id; this.screen_name = screen_name; } @Override protected SingleResponse<UserList> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { if (user_id > 0) { final UserList list = twitter.addUserListMember(list_id, user_id); return new SingleResponse<UserList>(account_id, list, null); } else if (screen_name != null) { final User user = twitter.showUser(screen_name); if (user != null && user.getId() > 0) { final UserList list = twitter.addUserListMember(list_id, user.getId()); return new SingleResponse<UserList>(account_id, list, null); } } } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<UserList> result) { final boolean succeed = result != null && result.data != null && result.data.getId() > 0; if (succeed) { Toast.makeText(TweetingsService.this, R.string.add_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.add_member, result.exception, true); } final Intent intent = new Intent(BROADCAST_USER_LIST_MEMBER_DELETED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_LIST_ID, list_id); intent.putExtra(INTENT_KEY_SUCCEED, succeed); sendBroadcast(intent); super.onPostExecute(result); } } class CacheUsersTask extends ManagedAsyncTask<Void, Void, Void> { private final List<ListResponse<twitter4j.Status>> responses; public CacheUsersTask(final List<ListResponse<twitter4j.Status>> result) { super(TweetingsService.this, mAsyncTaskManager); responses = result; } @Override protected Void doInBackground(final Void... args) { for (final ListResponse<twitter4j.Status> response : responses) { final List<twitter4j.Status> statuses = response.list; if (statuses == null || statuses.size() <= 0) { continue; } final List<ContentValues> cached_users_list = new ArrayList<ContentValues>(); final List<Long> user_ids = new ArrayList<Long>(); for (final twitter4j.Status status : statuses) { if (status == null) { continue; } final User user = status.getUser(); final long user_id = user.getId(); if (!user_ids.contains(user_id)) { user_ids.add(user_id); cached_users_list.add(makeCachedUserContentValues(user)); } } mResolver.delete(CachedUsers.CONTENT_URI, CachedUsers.USER_ID + " IN (" + ListUtils.toString(user_ids, ',', true) + " )", null); mResolver.bulkInsert(CachedUsers.CONTENT_URI, cached_users_list.toArray(new ContentValues[cached_users_list.size()])); } return null; } } class CreateBlockTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private long account_id; private long user_id; public CreateBlockTask(final long account_id, final long user_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_id = user_id; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final User user = twitter.createBlock(user_id); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null && result.data.getId() > 0) { for (final Uri uri : Utils.STATUSES_URIS) { final String where = Statuses.ACCOUNT_ID + " = " + account_id + " AND " + Statuses.USER_ID + " = " + user_id; mResolver.delete(uri, where, null); } //I bet you don't want to see this user in your auto complete list. final String where = CachedUsers.USER_ID + " = " + user_id; mResolver.delete(CachedUsers.CONTENT_URI, where, null); Toast.makeText(TweetingsService.this, R.string.user_blocked, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.block, result.exception, true); } final Intent intent = new Intent(BROADCAST_BLOCKSTATE_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class CreateFavoriteTask extends ManagedAsyncTask<Void, Void, SingleResponse<twitter4j.Status>> { private long account_id; private long status_id; public CreateFavoriteTask(final long account_id, final long status_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.status_id = status_id; } @Override protected SingleResponse<twitter4j.Status> doInBackground(final Void... params) { if (account_id < 0) return new SingleResponse<twitter4j.Status>(account_id, null, null); final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final twitter4j.Status status = twitter.createFavorite(status_id); return new SingleResponse<twitter4j.Status>(account_id, status, null); } catch (final TwitterException e) { return new SingleResponse<twitter4j.Status>(account_id, null, e); } } return new SingleResponse<twitter4j.Status>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<twitter4j.Status> result) { if (result.data != null) { final long status_id = result.data.getId(); final ContentValues values = new ContentValues(); values.put(Statuses.IS_FAVORITE, 1); final StringBuilder where = new StringBuilder(); where.append(Statuses.ACCOUNT_ID + " = " + result.account_id); where.append(" AND "); where.append("("); where.append(Statuses.STATUS_ID + "=" + status_id); where.append(" OR "); where.append(Statuses.RETWEET_ID + "=" + status_id); where.append(")"); for (final Uri uri : TweetStore.STATUSES_URIS) { mResolver.update(uri, values, where.toString(), null); } final Intent intent = new Intent(BROADCAST_FAVORITE_CHANGED); intent.putExtra(INTENT_KEY_STATUS_ID, status_id); intent.putExtra(INTENT_KEY_FAVORITED, true); sendBroadcast(intent); Toast.makeText(TweetingsService.this, R.string.favorite_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.fav, result.exception, true); } super.onPostExecute(result); } } class CreateFriendshipTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private long account_id; private long user_id; public CreateFriendshipTask(final long account_id, final long user_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_id = user_id; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final User user = twitter.createFriendship(user_id); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null) { Toast.makeText(TweetingsService.this, R.string.follow_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.follow, result.exception, true); } final Intent intent = new Intent(BROADCAST_FRIENDSHIP_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class CreateMultiBlockTask extends ManagedAsyncTask<Void, Void, ListResponse<Long>> { private long account_id; private long[] user_ids; public CreateMultiBlockTask(final long account_id, final long[] user_ids) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_ids = user_ids; } @Override protected ListResponse<Long> doInBackground(final Void... params) { final List<Long> blocked_users = new ArrayList<Long>(); final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { for (final long user_id : user_ids) { try { final User user = twitter.createBlock(user_id); if (user == null || user.getId() <= 0) { continue; } blocked_users.add(user.getId()); } catch (final TwitterException e) { e.printStackTrace(); } } } return new ListResponse<Long>(account_id, -1, -1, blocked_users, null); } @Override protected void onPostExecute(final ListResponse<Long> result) { if (result != null) { final String user_ids = ListUtils.toString(result.list, ',', false); for (final Uri uri : Utils.STATUSES_URIS) { final String where = Statuses.ACCOUNT_ID + " = " + account_id + " AND " + Statuses.USER_ID + " IN (" + user_ids + ")"; mResolver.delete(uri, where, null); } //I bet you don't want to see these users in your auto complete list. final String where = CachedUsers.USER_ID + " IN (" + user_ids + ")"; mResolver.delete(CachedUsers.CONTENT_URI, where, null); Toast.makeText(TweetingsService.this, R.string.users_blocked, Toast.LENGTH_SHORT).show(); } final Intent intent = new Intent(BROADCAST_MULTI_BLOCKSTATE_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_ids); intent.putExtra(INTENT_KEY_SUCCEED, result != null); sendBroadcast(intent); super.onPostExecute(result); } } class CreateUserListSubscriptionTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id; private final int list_id; public CreateUserListSubscriptionTask(final long account_id, final int list_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.list_id = list_id; } @Override protected SingleResponse<UserList> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final UserList list = twitter.createUserListSubscription(list_id); return new SingleResponse<UserList>(account_id, list, null); } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<UserList> result) { final boolean succeed = result != null && result.data != null && result.data.getId() > 0; if (succeed) { Toast.makeText(TweetingsService.this, R.string.follow_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.block, result.exception, true); } final Intent intent = new Intent(BROADCAST_USER_LIST_SUBSCRIPTION_CHANGED); intent.putExtra(INTENT_KEY_LIST_ID, list_id); intent.putExtra(INTENT_KEY_SUCCEED, succeed); sendBroadcast(intent); super.onPostExecute(result); } } class CreateUserListTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id; private final String list_name, description; private final boolean is_public; public CreateUserListTask(final long account_id, final String list_name, final boolean is_public, final String description) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.list_name = list_name; this.description = description; this.is_public = is_public; } @Override protected SingleResponse<UserList> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { if (list_name != null) { final UserList list = twitter.createUserList(list_name, is_public, description); return new SingleResponse<UserList>(account_id, list, null); } } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<UserList> result) { final boolean succeed = result != null && result.data != null && result.data.getId() > 0; if (succeed) { Toast.makeText(TweetingsService.this, R.string.create_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.create, result.exception, true); } final Intent intent = new Intent(BROADCAST_USER_LIST_CREATED); intent.putExtra(INTENT_KEY_SUCCEED, succeed); sendBroadcast(intent); super.onPostExecute(result); } } class DeleteUserListMemberTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id, user_id; private final int list_id; public DeleteUserListMemberTask(final long account_id, final int list_id, final long user_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.list_id = list_id; this.user_id = user_id; } @Override protected SingleResponse<UserList> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final UserList list = twitter.deleteUserListMember(list_id, user_id); return new SingleResponse<UserList>(account_id, list, null); } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<UserList> result) { final boolean succeed = result != null && result.data != null && result.data.getId() > 0; if (succeed) { Toast.makeText(TweetingsService.this, R.string.delete_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.create, result.exception, true); } final Intent intent = new Intent(BROADCAST_USER_LIST_MEMBER_DELETED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_LIST_ID, list_id); intent.putExtra(INTENT_KEY_SUCCEED, succeed); sendBroadcast(intent); super.onPostExecute(result); } } class DestroyBlockTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private long account_id; private long user_id; public DestroyBlockTask(final long account_id, final long user_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_id = user_id; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final User user = twitter.destroyBlock(user_id); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null) { Toast.makeText(TweetingsService.this, R.string.user_unblocked, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.unblock, result.exception, true); } final Intent intent = new Intent(BROADCAST_BLOCKSTATE_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class DestroyDirectMessageTask extends ManagedAsyncTask<Void, Void, SingleResponse<DirectMessage>> { private final Twitter twitter; private final long message_id; private final long account_id; public DestroyDirectMessageTask(final long account_id, final long message_id) { super(TweetingsService.this, mAsyncTaskManager); twitter = getTwitterInstance(TweetingsService.this, account_id, false); this.account_id = account_id; this.message_id = message_id; } @Override protected SingleResponse<DirectMessage> doInBackground(final Void... args) { if (twitter == null) return new SingleResponse<DirectMessage>(account_id, null, null); try { return new SingleResponse<DirectMessage>(account_id, twitter.destroyDirectMessage(message_id), null); } catch (final TwitterException e) { return new SingleResponse<DirectMessage>(account_id, null, e); } } @Override protected void onPostExecute(final SingleResponse<DirectMessage> result) { super.onPostExecute(result); if (result == null) return; if (result.data != null && result.data.getId() > 0) { Toast.makeText(TweetingsService.this, R.string.delete_success, Toast.LENGTH_SHORT).show(); final String where = DirectMessages.MESSAGE_ID + " = " + message_id; mResolver.delete(DirectMessages.Inbox.CONTENT_URI, where, null); mResolver.delete(DirectMessages.Outbox.CONTENT_URI, where, null); } else { showErrorToast(R.string.delete, result.exception, true); } } } class DestroyFavoriteTask extends ManagedAsyncTask<Void, Void, SingleResponse<twitter4j.Status>> { private long account_id; private long status_id; public DestroyFavoriteTask(final long account_id, final long status_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.status_id = status_id; } @Override protected SingleResponse<twitter4j.Status> doInBackground(final Void... params) { if (account_id < 0) { new SingleResponse<twitter4j.Status>(account_id, null, null); } final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final twitter4j.Status status = twitter.destroyFavorite(status_id); return new SingleResponse<twitter4j.Status>(account_id, status, null); } catch (final TwitterException e) { return new SingleResponse<twitter4j.Status>(account_id, null, e); } } return new SingleResponse<twitter4j.Status>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<twitter4j.Status> result) { if (result.data != null) { final long status_id = result.data.getId(); final ContentValues values = new ContentValues(); values.put(Statuses.IS_FAVORITE, 0); final StringBuilder where = new StringBuilder(); where.append(Statuses.ACCOUNT_ID + " = " + result.account_id); where.append(" AND "); where.append("("); where.append(Statuses.STATUS_ID + "=" + status_id); where.append(" OR "); where.append(Statuses.RETWEET_ID + "=" + status_id); where.append(")"); for (final Uri uri : TweetStore.STATUSES_URIS) { mResolver.update(uri, values, where.toString(), null); } final Intent intent = new Intent(BROADCAST_FAVORITE_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, account_id); intent.putExtra(INTENT_KEY_STATUS_ID, status_id); intent.putExtra(INTENT_KEY_FAVORITED, false); sendBroadcast(intent); Toast.makeText(TweetingsService.this, R.string.unfavorite_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.unfav, result.exception, true); } super.onPostExecute(result); } } class DestroyFriendshipTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private long account_id; private long user_id; public DestroyFriendshipTask(final long account_id, final long user_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_id = user_id; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final User user = twitter.destroyFriendship(user_id); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null) { Toast.makeText(TweetingsService.this, R.string.unfollow_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.unfollow, result.exception, true); } final Intent intent = new Intent(BROADCAST_FRIENDSHIP_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class DestroyStatusTask extends ManagedAsyncTask<Void, Void, SingleResponse<twitter4j.Status>> { private long account_id; private long status_id; public DestroyStatusTask(final long account_id, final long status_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.status_id = status_id; } @Override protected SingleResponse<twitter4j.Status> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final twitter4j.Status status = twitter.destroyStatus(status_id); return new SingleResponse<twitter4j.Status>(account_id, status, null); } catch (final TwitterException e) { return new SingleResponse<twitter4j.Status>(account_id, null, e); } } return new SingleResponse<twitter4j.Status>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<twitter4j.Status> result) { final Intent intent = new Intent(BROADCAST_STATUS_DESTROYED); if (result != null && result.data != null && result.data.getId() > 0) { final long status_id = result.data.getId(); final StringBuilder where = new StringBuilder(); where.append(Statuses.STATUS_ID + " = " + status_id); where.append(" OR " + Statuses.RETWEET_ID + " = " + status_id); for (final Uri uri : TweetStore.STATUSES_URIS) { mResolver.delete(uri, where.toString(), null); } intent.putExtra(INTENT_KEY_STATUS_ID, status_id); intent.putExtra(INTENT_KEY_SUCCEED, true); Toast.makeText(TweetingsService.this, R.string.delete_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.delete, result.exception, true); } sendBroadcast(intent); super.onPostExecute(result); } } class DestroySavedSearchTask extends ManagedAsyncTask<Void, Void, SingleResponse<twitter4j.SavedSearch>> { private long account_id; private int search_id; public DestroySavedSearchTask(final long account_id, final int search_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.search_id = search_id; } @Override protected SingleResponse<twitter4j.SavedSearch> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final twitter4j.SavedSearch status = twitter.destroySavedSearch(search_id); return new SingleResponse<twitter4j.SavedSearch>(account_id, status, null); } catch (final TwitterException e) { return new SingleResponse<twitter4j.SavedSearch>(account_id, null, e); } } return new SingleResponse<twitter4j.SavedSearch>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<twitter4j.SavedSearch> result) { final Intent intent = new Intent(BROADCAST_SEARCH_CHANGED); if (result != null && result.data != null && result.data.getId() > 0) { Toast.makeText(TweetingsService.this, R.string.delete_search_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.delete, result.exception, true); } sendBroadcast(intent); super.onPostExecute(result); } } class CreateSavedSearchTask extends ManagedAsyncTask<Void, Void, SingleResponse<twitter4j.SavedSearch>> { private long account_id; private String query; public CreateSavedSearchTask(final long account_id, final String query) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.query = query; } @Override protected SingleResponse<twitter4j.SavedSearch> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final twitter4j.SavedSearch status = twitter.createSavedSearch(query); return new SingleResponse<twitter4j.SavedSearch>(account_id, status, null); } catch (final TwitterException e) { return new SingleResponse<twitter4j.SavedSearch>(account_id, null, e); } } return new SingleResponse<twitter4j.SavedSearch>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<twitter4j.SavedSearch> result) { final Intent intent = new Intent(BROADCAST_SEARCH_CHANGED); if (result != null && result.data != null && result.data.getId() > 0) { Toast.makeText(TweetingsService.this, R.string.create_search_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.save, result.exception, true); } sendBroadcast(intent); super.onPostExecute(result); } } class DestroyUserListSubscriptionTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id; private final int list_id; public DestroyUserListSubscriptionTask(final long account_id, final int list_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.list_id = list_id; } @Override protected SingleResponse<UserList> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final UserList list = twitter.destroyUserListSubscription(list_id); return new SingleResponse<UserList>(account_id, list, null); } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<UserList> result) { final boolean succeed = result != null && result.data != null && result.data.getId() > 0; if (succeed) { Toast.makeText(TweetingsService.this, R.string.unfollow_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.delete, result.exception, true); } final Intent intent = new Intent(BROADCAST_USER_LIST_SUBSCRIPTION_CHANGED); intent.putExtra(INTENT_KEY_LIST_ID, list_id); intent.putExtra(INTENT_KEY_SUCCEED, succeed); sendBroadcast(intent); super.onPostExecute(result); } } class DestroyUserListTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id; private final int list_id; public DestroyUserListTask(final long account_id, final int list_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.list_id = list_id; } @Override protected SingleResponse<UserList> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { if (list_id > 0) { final UserList list = twitter.destroyUserList(list_id); return new SingleResponse<UserList>(account_id, list, null); } } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<UserList> result) { final boolean succeed = result != null && result.data != null && result.data.getId() > 0; if (succeed) { Toast.makeText(TweetingsService.this, R.string.delete_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.delete, result.exception, true); } final Intent intent = new Intent(BROADCAST_USER_LIST_DELETED); intent.putExtra(INTENT_KEY_SUCCEED, succeed); intent.putExtra(INTENT_KEY_LIST_ID, list_id); sendBroadcast(intent); super.onPostExecute(result); } } class GetDailyTrendsTask extends GetTrendsTask { public GetDailyTrendsTask(final long account_id) { super(account_id); } @Override public ResponseList<Trends> getTrends(final Twitter twitter) throws TwitterException { if (twitter == null) return null; return twitter.getDailyTrends(); } @Override protected void onPostExecute(final ListResponse<Trends> result) { mStoreDailyTrendsTaskId = mAsyncTaskManager.add(new StoreDailyTrendsTask(result), true); super.onPostExecute(result); } } abstract class GetDirectMessagesTask extends ManagedAsyncTask<Void, Void, List<ListResponse<DirectMessage>>> { private final long[] account_ids, max_ids, since_ids; public GetDirectMessagesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids) { super(TweetingsService.this, mAsyncTaskManager); this.account_ids = account_ids; this.max_ids = max_ids; this.since_ids = since_ids; } public abstract ResponseList<DirectMessage> getDirectMessages(final Twitter twitter, final Paging paging) throws TwitterException; @Override protected List<ListResponse<DirectMessage>> doInBackground(final Void... params) { final List<ListResponse<DirectMessage>> result = new ArrayList<ListResponse<DirectMessage>>(); if (account_ids == null) return result; final boolean max_ids_valid = max_ids != null && max_ids.length == account_ids.length; final boolean since_ids_valid = since_ids != null && since_ids.length == account_ids.length; int idx = 0; final int load_item_limit = mPreferences.getInt(PREFERENCE_KEY_LOAD_ITEM_LIMIT, PREFERENCE_DEFAULT_LOAD_ITEM_LIMIT); for (final long account_id : account_ids) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, true); if (twitter != null) { try { final Paging paging = new Paging(); paging.setCount(load_item_limit); long max_id = -1; if (max_ids_valid && max_ids[idx] > 0) { max_id = max_ids[idx]; paging.setMaxId(max_id); } long since_id = -1; if (since_ids_valid && since_ids[idx] > 0) { since_id = since_ids[idx]; paging.setSinceId(since_id); } final ResponseList<DirectMessage> statuses = getDirectMessages(twitter, paging); if (statuses != null) { result.add( new ListResponse<DirectMessage>(account_id, max_id, since_id, statuses, null)); } } catch (final TwitterException e) { e.printStackTrace(); } } idx++; } return result; } } class GetHomeTimelineTask extends GetStatusesTask { private final boolean is_auto_refresh; public GetHomeTimelineTask(final long[] account_ids, final long[] max_ids, final long[] since_ids, final boolean is_auto_refresh) { super(Statuses.CONTENT_URI, account_ids, max_ids, since_ids); this.is_auto_refresh = is_auto_refresh; } @Override public ResponseList<twitter4j.Status> getStatuses(final Twitter twitter, final Paging paging) throws TwitterException { if (mPreferences.getBoolean(PREFERENCE_KEY_API_V1, true) == true) { return twitter.getHomeTimelinev1(paging); } return twitter.getHomeTimeline(paging); } @Override public Twitter getTwitter(final long account_id) { return getTwitterInstance(TweetingsService.this, account_id, true, true, true); } @Override protected void onPostExecute(final List<ListResponse<twitter4j.Status>> responses) { super.onPostExecute(responses); mStoreStatusesTaskId = mAsyncTaskManager .add(new StoreHomeTimelineTask(responses, is_auto_refresh, shouldSetMinId()), true); mGetHomeTimelineTaskId = -1; } @Override protected void onPreExecute() { mAlarmManager.cancel(mPendingRefreshHomeTimelineIntent); if (mPreferences.getBoolean(PREFERENCE_KEY_AUTO_REFRESH, false)) { final long update_interval = parseInt(mPreferences.getString(PREFERENCE_KEY_REFRESH_INTERVAL, "30")) * 60 * 1000; if (update_interval > 0) { mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + update_interval, update_interval, mPendingRefreshHomeTimelineIntent); } } super.onPreExecute(); } } class GetLocalTrendsTask extends GetTrendsTask { private final int woeid; public GetLocalTrendsTask(final long account_id, final int woeid) { super(account_id); this.woeid = woeid; } @Override public List<Trends> getTrends(final Twitter twitter) throws TwitterException { final ArrayList<Trends> trends_list = new ArrayList<Trends>(); if (twitter != null) { trends_list.add(twitter.getLocationTrends(woeid)); } return trends_list; } @Override protected void onPostExecute(final ListResponse<Trends> result) { mStoreLocalTrendsTaskId = mAsyncTaskManager.add(new StoreLocalTrendsTask(result), true); super.onPostExecute(result); } } class GetMentionsTask extends GetStatusesTask { private final boolean is_auto_refresh; public GetMentionsTask(final long[] account_ids, final long[] max_ids, final long[] since_ids, final boolean is_auto_refresh) { super(Mentions.CONTENT_URI, account_ids, max_ids, since_ids); this.is_auto_refresh = is_auto_refresh; } @Override public ResponseList<twitter4j.Status> getStatuses(final Twitter twitter, final Paging paging) throws TwitterException { if (mPreferences.getBoolean(PREFERENCE_KEY_API_V1, true) == true) { return twitter.getMentionsv1(paging); } return twitter.getMentions(paging); } @Override public Twitter getTwitter(final long account_id) { return getTwitterInstance(TweetingsService.this, account_id, true, false, true); } @Override protected void onPostExecute(final List<ListResponse<twitter4j.Status>> responses) { super.onPostExecute(responses); mStoreMentionsTaskId = mAsyncTaskManager .add(new StoreMentionsTask(responses, is_auto_refresh, shouldSetMinId()), true); mGetMentionsTaskId = -1; } @Override protected void onPreExecute() { mAlarmManager.cancel(mPendingRefreshMentionsIntent); if (mPreferences.getBoolean(PREFERENCE_KEY_AUTO_REFRESH, false)) { final long update_interval = parseInt(mPreferences.getString(PREFERENCE_KEY_REFRESH_INTERVAL, "30")) * 60 * 1000; if (update_interval > 0) { mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + update_interval, update_interval, mPendingRefreshMentionsIntent); } } super.onPreExecute(); } } class GetReceivedDirectMessagesTask extends GetDirectMessagesTask { private final boolean is_auto_refresh; public GetReceivedDirectMessagesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids, final boolean is_auto_refresh) { super(account_ids, max_ids, since_ids); this.is_auto_refresh = is_auto_refresh; } @Override public ResponseList<DirectMessage> getDirectMessages(final Twitter twitter, final Paging paging) throws TwitterException { if (mPreferences.getBoolean(PREFERENCE_KEY_API_V1, true) == true) { return twitter.getDirectMessagesv1(paging); } return twitter.getDirectMessages(paging); } @Override protected void onPreExecute() { mAlarmManager.cancel(mPendingRefreshDirectMessagesIntent); if (mPreferences.getBoolean(PREFERENCE_KEY_AUTO_REFRESH, false)) { final long update_interval = parseInt(mPreferences.getString(PREFERENCE_KEY_REFRESH_INTERVAL, "30")) * 60 * 1000; if (update_interval > 0) { mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + update_interval, update_interval, mPendingRefreshDirectMessagesIntent); } } super.onPreExecute(); } @Override protected void onPostExecute(final List<ListResponse<DirectMessage>> responses) { super.onPostExecute(responses); mStoreReceivedDirectMessagesTaskId = mAsyncTaskManager .add(new StoreReceivedDirectMessagesTask(responses, is_auto_refresh), true); mGetReceivedDirectMessagesTaskId = -1; } } class GetSentDirectMessagesTask extends GetDirectMessagesTask { public GetSentDirectMessagesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids) { super(account_ids, max_ids, since_ids); } @Override public ResponseList<DirectMessage> getDirectMessages(final Twitter twitter, final Paging paging) throws TwitterException { if (mPreferences.getBoolean(PREFERENCE_KEY_API_V1, true) == true) { return twitter.getSentDirectMessagesv1(paging); } return twitter.getSentDirectMessages(paging); } @Override protected void onPostExecute(final List<ListResponse<DirectMessage>> responses) { super.onPostExecute(responses); mStoreSentDirectMessagesTaskId = mAsyncTaskManager.add(new StoreSentDirectMessagesTask(responses), true); mGetSentDirectMessagesTaskId = -1; } } abstract class GetStatusesTask extends ManagedAsyncTask<Void, Void, List<ListResponse<twitter4j.Status>>> { private final long[] account_ids, max_ids, since_ids; private boolean should_set_min_id, should_set_since_id; public GetStatusesTask(final Uri uri, final long[] account_ids, final long[] max_ids, final long[] since_ids) { super(TweetingsService.this, mAsyncTaskManager); this.account_ids = account_ids; this.max_ids = max_ids; this.since_ids = since_ids; } public abstract ResponseList<twitter4j.Status> getStatuses(final Twitter twitter, final Paging paging) throws TwitterException; public abstract Twitter getTwitter(final long account_id); public boolean shouldSetMinId() { return should_set_min_id; } public boolean shouldSetSinceId() { return should_set_since_id; } @Override protected void onPostExecute(final List<ListResponse<twitter4j.Status>> result) { super.onPostExecute(result); for (final ListResponse<twitter4j.Status> response : result) { if (response.list == null) { showErrorToast(R.string.refresh, response.exception, true); } } } @Override protected List<ListResponse<twitter4j.Status>> doInBackground(final Void... params) { final List<ListResponse<twitter4j.Status>> result = new ArrayList<ListResponse<twitter4j.Status>>(); if (account_ids == null) return result; final boolean max_ids_valid = max_ids != null && max_ids.length == account_ids.length; should_set_min_id = !max_ids_valid; final boolean since_ids_valid = since_ids != null && since_ids.length == account_ids.length; should_set_since_id = !since_ids_valid; int idx = 0; final int load_item_limit = mPreferences.getInt(PREFERENCE_KEY_LOAD_ITEM_LIMIT, PREFERENCE_DEFAULT_LOAD_ITEM_LIMIT); for (final long account_id : account_ids) { final Twitter twitter = getTwitter(account_id); if (twitter != null) { try { final Paging paging = new Paging(); paging.setCount(load_item_limit); long max_id = -1; if (max_ids_valid && max_ids[idx] > 0) { max_id = max_ids[idx]; paging.setMaxId(max_id); } long since_id = -1; if (since_ids_valid && since_ids[idx] > 0) { since_id = since_ids[idx]; paging.setSinceId(since_id); } final ResponseList<twitter4j.Status> statuses = getStatuses(twitter, paging); if (statuses != null) { result.add(new ListResponse<twitter4j.Status>(account_id, max_id, since_id, statuses, null)); } } catch (final TwitterException e) { e.printStackTrace(); result.add(new ListResponse<twitter4j.Status>(account_id, -1, -1, null, e)); } } idx++; } return result; } } abstract class GetTrendsTask extends ManagedAsyncTask<Void, Void, ListResponse<Trends>> { private final long account_id; public GetTrendsTask(final long account_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; } public abstract List<Trends> getTrends(final Twitter twitter) throws TwitterException; @Override protected ListResponse<Trends> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { return new ListResponse<Trends>(account_id, -1, -1, getTrends(twitter), null); } catch (final TwitterException e) { e.printStackTrace(); } } return new ListResponse<Trends>(account_id, -1, -1, null, null); } } class GetWeeklyTrendsTask extends GetTrendsTask { public GetWeeklyTrendsTask(final long account_id) { super(account_id); } @Override public ResponseList<Trends> getTrends(final Twitter twitter) throws TwitterException { if (twitter == null) return null; return twitter.getWeeklyTrends(); } @Override protected void onPostExecute(final ListResponse<Trends> result) { mStoreWeeklyTrendsTaskId = mAsyncTaskManager.add(new StoreWeeklyTrendsTask(result), true); super.onPostExecute(result); } } public static final class ListResponse<Data> { public final long account_id, max_id, since_id; public final List<Data> list; public final TwitterException exception; public ListResponse(final long account_id, final long max_id, final long since_id, final List<Data> responselist, TwitterException exception) { this.account_id = account_id; this.max_id = max_id; this.since_id = since_id; this.list = responselist; this.exception = exception; } } class ReportMultiSpamTask extends ManagedAsyncTask<Void, Void, ListResponse<Long>> { private long account_id; private long[] user_ids; public ReportMultiSpamTask(final long account_id, final long[] user_ids) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_ids = user_ids; } @Override protected ListResponse<Long> doInBackground(final Void... params) { final List<Long> reported_users = new ArrayList<Long>(); final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { for (final long user_id : user_ids) { try { final User user = twitter.reportSpam(user_id); if (user == null || user.getId() <= 0) { continue; } reported_users.add(user.getId()); } catch (final TwitterException e) { e.printStackTrace(); } } } return new ListResponse<Long>(account_id, -1, -1, reported_users, null); } @Override protected void onPostExecute(final ListResponse<Long> result) { if (result != null) { final String user_id_where = ListUtils.toString(result.list, ',', false); for (final Uri uri : Utils.STATUSES_URIS) { final String where = Statuses.ACCOUNT_ID + " = " + account_id + " AND " + Statuses.USER_ID + " IN (" + user_id_where + ")"; mResolver.delete(uri, where, null); } Toast.makeText(TweetingsService.this, R.string.reported_users_for_spam, Toast.LENGTH_SHORT).show(); } final Intent intent = new Intent(BROADCAST_MULTI_BLOCKSTATE_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_ids); intent.putExtra(INTENT_KEY_SUCCEED, result != null); sendBroadcast(intent); super.onPostExecute(result); } } class ReportSpamTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private long account_id; private long user_id; public ReportSpamTask(final long account_id, final long user_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.user_id = user_id; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final User user = twitter.reportSpam(user_id); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null && result.data.getId() > 0) { for (final Uri uri : Utils.STATUSES_URIS) { final String where = Statuses.ACCOUNT_ID + " = " + account_id + " AND " + Statuses.USER_ID + " = " + user_id; mResolver.delete(uri, where, null); } Toast.makeText(TweetingsService.this, R.string.reported_user_for_spam, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.refresh, result.exception, true); } final Intent intent = new Intent(BROADCAST_BLOCKSTATE_CHANGED); intent.putExtra(INTENT_KEY_USER_ID, user_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class RetweetStatusTask extends ManagedAsyncTask<Void, Void, SingleResponse<twitter4j.Status>> { private long account_id; private long status_id; private final AudioManager audioManager = (AudioManager) getSystemService(Activity.AUDIO_SERVICE); public RetweetStatusTask(final long account_id, final long status_id) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.status_id = status_id; } @Override protected SingleResponse<twitter4j.Status> doInBackground(final Void... params) { if (account_id < 0) return new SingleResponse<twitter4j.Status>(account_id, null, null); final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final twitter4j.Status status = twitter.retweetStatus(status_id); return new SingleResponse<twitter4j.Status>(account_id, status, null); } catch (final TwitterException e) { return new SingleResponse<twitter4j.Status>(account_id, null, e); } } return new SingleResponse<twitter4j.Status>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<twitter4j.Status> result) { if (result.data != null && result.data.getId() > 0) { Toast.makeText(TweetingsService.this, R.string.retweet_success, Toast.LENGTH_SHORT).show(); boolean isMuted = false; switch (audioManager.getRingerMode()) { case AudioManager.RINGER_MODE_NORMAL: isMuted = false; break; case AudioManager.RINGER_MODE_SILENT: isMuted = true; break; case AudioManager.RINGER_MODE_VIBRATE: isMuted = true; break; } if (mPreferences.getBoolean(PREFERENCE_KEY_SOUND_SEND, true)) { if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); } mPlayer.release(); } mPlayer = MediaPlayer.create(TweetingsService.this, R.raw.whoosh); if (isMuted == true) { mPlayer.setVolume(0, 0); } mPlayer.start(); } final Intent intent = new Intent(BROADCAST_RETWEET_CHANGED); intent.putExtra(INTENT_KEY_STATUS_ID, status_id); intent.putExtra(INTENT_KEY_RETWEETED, true); sendBroadcast(intent); } else { showErrorToast(R.string.retweet, result.exception, true); } super.onPostExecute(result); } } class SendDirectMessageTask extends ManagedAsyncTask<Void, Void, SingleResponse<DirectMessage>> { private final Twitter twitter; private final long user_id; private final String screen_name; private final String message; private final long account_id; private final AudioManager audioManager = (AudioManager) getSystemService(Activity.AUDIO_SERVICE); public SendDirectMessageTask(final long account_id, final String screen_name, final long user_id, final String message) { super(TweetingsService.this, mAsyncTaskManager); twitter = getTwitterInstance(TweetingsService.this, account_id, true); this.account_id = account_id; this.user_id = user_id; this.screen_name = screen_name; this.message = message; } @Override protected SingleResponse<DirectMessage> doInBackground(final Void... args) { if (twitter == null) return new SingleResponse<DirectMessage>(account_id, null, null); try { if (user_id > 0) return new SingleResponse<DirectMessage>(account_id, twitter.sendDirectMessage(user_id, message), null); else if (screen_name != null) return new SingleResponse<DirectMessage>(account_id, twitter.sendDirectMessage(screen_name, message), null); } catch (final TwitterException e) { return new SingleResponse<DirectMessage>(account_id, null, e); } return new SingleResponse<DirectMessage>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<DirectMessage> result) { super.onPostExecute(result); if (result == null) return; if (result.data != null && result.data.getId() > 0) { final Uri.Builder builder = DirectMessages.Outbox.CONTENT_URI.buildUpon(); builder.appendQueryParameter(QUERY_PARAM_NOTIFY, String.valueOf(true)); final ContentValues values = makeDirectMessageContentValues(result.data, account_id); getContentResolver().insert(builder.build(), values); boolean isMuted = false; switch (audioManager.getRingerMode()) { case AudioManager.RINGER_MODE_NORMAL: isMuted = false; break; case AudioManager.RINGER_MODE_SILENT: isMuted = true; break; case AudioManager.RINGER_MODE_VIBRATE: isMuted = true; break; } if (mPreferences.getBoolean(PREFERENCE_KEY_SOUND_SEND, true)) { if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); } mPlayer.release(); } mPlayer = MediaPlayer.create(TweetingsService.this, R.raw.whoosh); if (isMuted == true) { mPlayer.setVolume(0, 0); } mPlayer.start(); } Toast.makeText(TweetingsService.this, R.string.send_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.update, result.exception, true); } } } /* * By making this a static class with a WeakReference to the Service, we * ensure that the Service can be GCd even when the system process still has * a remote reference to the stub. */ static final class ServiceStub extends ITweetingsService.Stub { public void cancelShutdown() { mService.get().cancelShutdown(); } final WeakReference<TweetingsService> mService; public ServiceStub(TweetingsService service) { mService = new WeakReference<TweetingsService>(service); } @Override public int addUserListMember(final long account_id, final int list_id, final long user_id, final String screen_name) { return mService.get().addUserListMember(account_id, list_id, user_id, screen_name); } @Override public void clearNotification(final int id) { mService.get().clearNotification(id); } @Override public int createBlock(final long account_id, final long user_id) { return mService.get().createBlock(account_id, user_id); } @Override public int insertStreamToHomeTimeline(final long account_id, final Intent intent) { return mService.get().insertStreamToHomeTimeline(account_id, intent); } @Override public int insertStreamToMentions(final long account_id, final Intent intent) { return mService.get().insertStreamToMentions(account_id, intent); } @Override public int insertStreamToInbox(final long account_id, final Intent intent) { return mService.get().insertStreamToInbox(account_id, intent); } @Override public int createFavorite(final long account_id, final long status_id) { return mService.get().createFavorite(account_id, status_id); } @Override public int createFriendship(final long account_id, final long user_id) { return mService.get().createFriendship(account_id, user_id); } @Override public String generateOAuthEchoHeader(final long account_id) { return mService.get().generateOAuthEchoHeader(account_id); } @Override public int createMultiBlock(final long account_id, final long[] user_ids) { return mService.get().createMultiBlock(account_id, user_ids); } @Override public int createUserList(final long account_id, final String list_name, final boolean is_public, final String description) { return mService.get().createUserList(account_id, list_name, is_public, description); } @Override public int createUserListSubscription(final long account_id, final int list_id) { return mService.get().createUserListSubscription(account_id, list_id); } @Override public int deleteUserListMember(final long account_id, final int list_id, final long user_id) { return mService.get().deleteUserListMember(account_id, list_id, user_id); } @Override public int destroyBlock(final long account_id, final long user_id) { return mService.get().destroyBlock(account_id, user_id); } @Override public int destroyDirectMessage(final long account_id, final long message_id) { return mService.get().destroyDirectMessage(account_id, message_id); } @Override public int destroyFavorite(final long account_id, final long status_id) { return mService.get().destroyFavorite(account_id, status_id); } @Override public int destroyFriendship(final long account_id, final long user_id) { return mService.get().destroyFriendship(account_id, user_id); } @Override public int destroyStatus(final long account_id, final long status_id) { return mService.get().destroyStatus(account_id, status_id); } @Override public int destroySavedSearch(final long account_id, final int search_id) { return mService.get().destroySavedSearch(account_id, search_id); } @Override public int createSavedSearch(final long account_id, final String query) { return mService.get().createSavedSearch(account_id, query); } @Override public int destroyUserList(final long account_id, final int list_id) { return mService.get().destroyUserList(account_id, list_id); } @Override public int destroyUserListSubscription(final long account_id, final int list_id) { return mService.get().destroyUserListSubscription(account_id, list_id); } @Override public int getDailyTrends(final long account_id) { return mService.get().getDailyTrends(account_id); } @Override public int getHomeTimeline(final long[] account_ids, final long[] max_ids) { return mService.get().getHomeTimeline(account_ids, max_ids); } @Override public int getHomeTimelineWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { return mService.get().getHomeTimelineWithSinceId(account_ids, max_ids, since_ids); } @Override public int getLocalTrends(final long account_id, final int woeid) { return mService.get().getLocalTrends(account_id, woeid); } @Override public int getMentions(final long[] account_ids, final long[] max_ids) { return mService.get().getMentions(account_ids, max_ids); } @Override public int getMentionsWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { return mService.get().getMentionsWithSinceId(account_ids, max_ids, since_ids); } @Override public int getReceivedDirectMessages(final long[] account_ids, final long[] max_ids) { return mService.get().getReceivedDirectMessages(account_ids, max_ids); } @Override public int getReceivedDirectMessagesWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { return mService.get().getReceivedDirectMessagesWithSinceId(account_ids, max_ids, since_ids); } @Override public int getSentDirectMessages(final long[] account_ids, final long[] max_ids) { return mService.get().getSentDirectMessages(account_ids, max_ids); } @Override public int getSentDirectMessagesWithSinceId(final long[] account_ids, final long[] max_ids, final long[] since_ids) { return mService.get().getSentDirectMessagesWithSinceId(account_ids, max_ids, since_ids); } @Override public int getWeeklyTrends(final long account_id) { return mService.get().getWeeklyTrends(account_id); } @Override public boolean hasActivatedTask() { return mService.get().hasActivatedTask(); } @Override public boolean isDailyTrendsRefreshing() { return mService.get().isDailyTrendsRefreshing(); } @Override public boolean isHomeTimelineRefreshing() { return mService.get().isHomeTimelineRefreshing(); } @Override public boolean isLocalTrendsRefreshing() { return mService.get().isLocalTrendsRefreshing(); } @Override public boolean isMentionsRefreshing() { return mService.get().isMentionsRefreshing(); } @Override public boolean isReceivedDirectMessagesRefreshing() { return mService.get().isReceivedDirectMessagesRefreshing(); } @Override public boolean isSentDirectMessagesRefreshing() { return mService.get().isSentDirectMessagesRefreshing(); } @Override public boolean isWeeklyTrendsRefreshing() { return mService.get().isWeeklyTrendsRefreshing(); } @Override public int refreshAll() { return mService.get().refreshAll(); } @Override public void incrementActivityCount() { mService.get().incrementActivityCount(); } @Override public void decrementActivityCount() { mService.get().decrementActivityCount(); } @Override public int reportMultiSpam(final long account_id, final long[] user_ids) { return mService.get().reportMultiSpam(account_id, user_ids); } @Override public int reportSpam(final long account_id, final long user_id) { return mService.get().reportSpam(account_id, user_id); } @Override public int retweetStatus(final long account_id, final long status_id) { return mService.get().retweetStatus(account_id, status_id); } @Override public int sendDirectMessage(final long account_id, final String screen_name, final long user_id, final String message) { return mService.get().sendDirectMessage(account_id, screen_name, user_id, message); } @Override public void shutdownService() { mService.get().shutdownService(); } @Override public boolean startAutoRefresh() { return mService.get().startAutoRefresh(); } @Override public void stopAutoRefresh() { mService.get().stopAutoRefresh(); } @Override public boolean test() { return mService.get().test(); } @Override public int updateProfile(final long account_id, final String name, final String url, final String location, final String description) { return mService.get().updateProfile(account_id, name, url, location, description); } @Override public int updateProfileImage(final long account_id, final Uri image_uri, final boolean delete_image) { return mService.get().updateProfileImage(account_id, image_uri, delete_image); } @Override public int updateBannerImage(final long account_id, final Uri image_uri, final boolean delete_image) { return mService.get().updateBannerImage(account_id, image_uri, delete_image); } @Override public int updateStatus(final long[] account_ids, final String content, final Location location, final Uri image_uri, final long in_reply_to, final boolean is_possibly_sensitive, final boolean delete_image) { return mService.get().updateStatus(account_ids, content, location, image_uri, in_reply_to, is_possibly_sensitive, delete_image); } @Override public int scheduleStatus(final String schedule_date, final long[] account_ids, final String content, final Location location, final Uri image_uri, final long in_reply_to, final boolean delete_image) { return mService.get().scheduleStatus(schedule_date, account_ids, content, location, image_uri, in_reply_to, delete_image); } @Override public int bufferStatus(final long[] account_ids, final String content) { return mService.get().bufferStatus(account_ids, content); } @Override public int updateUserListDetails(final long account_id, final int list_id, final boolean is_public, final String name, final String description) { return mService.get().updateUserListDetails(account_id, list_id, is_public, name, description); } } static final class SingleResponse<Data> { public final Exception exception; public final Data data; public final long account_id; public SingleResponse(final long account_id, final Data data, final Exception exception) { this.exception = exception; this.data = data; this.account_id = account_id; } } class StoreDailyTrendsTask extends StoreTrendsTask { public StoreDailyTrendsTask(final ListResponse<Trends> result) { super(result, CachedTrends.Daily.CONTENT_URI); } } class StoreDirectMessagesTask extends ManagedAsyncTask<Void, Void, SingleResponse<Bundle>> { private final List<ListResponse<DirectMessage>> responses; private final Uri uri; public StoreDirectMessagesTask(final List<ListResponse<DirectMessage>> result, final Uri uri) { super(TweetingsService.this, mAsyncTaskManager); responses = result; this.uri = uri; } @Override protected SingleResponse<Bundle> doInBackground(final Void... args) { boolean succeed = false; final Uri query_uri = buildQueryUri(uri, false); int total_items_inserted = 0; for (final ListResponse<DirectMessage> response : responses) { final long account_id = response.account_id; final List<DirectMessage> messages = response.list; final Cursor cur = mResolver.query(uri, new String[0], DirectMessages.ACCOUNT_ID + " = " + account_id, null, null); boolean no_items_before = false; if (cur != null) { no_items_before = cur.getCount() <= 0; cur.close(); } if (messages != null) { final List<ContentValues> values_list = new ArrayList<ContentValues>(); final List<Long> message_ids = new ArrayList<Long>(); final long min_id = -1; for (final DirectMessage message : messages) { if (message == null || message.getId() <= 0) { continue; } message_ids.add(message.getId()); values_list.add(makeDirectMessageContentValues(message, account_id)); } int rows_deleted = -1; // Delete all rows conflicting before new data inserted. { final StringBuilder where = new StringBuilder(); where.append(DirectMessages.ACCOUNT_ID + " = " + account_id); where.append(" AND "); where.append(DirectMessages.MESSAGE_ID + " IN ( " + ListUtils.toString(message_ids, ',', true) + " ) "); rows_deleted = mResolver.delete(query_uri, where.toString(), null); } // Insert previously fetched items. mResolver.bulkInsert(query_uri, values_list.toArray(new ContentValues[values_list.size()])); // No row deleted, so I will insert a gap. final boolean insert_gap = rows_deleted == 1 && message_ids.contains(response.max_id) || rows_deleted == 0 && response.max_id == -1 && !no_items_before; if (insert_gap) { final ContentValues values = new ContentValues(); values.put(DirectMessages.IS_GAP, 1); final StringBuilder where = new StringBuilder(); where.append(DirectMessages.ACCOUNT_ID + "=" + account_id); where.append(" AND " + DirectMessages.MESSAGE_ID + "=" + min_id); mResolver.update(query_uri, values, where.toString(), null); } final int actual_items_inserted = values_list.size() - rows_deleted; if (actual_items_inserted > 0) { total_items_inserted += actual_items_inserted; } } succeed = true; } final Bundle bundle = new Bundle(); bundle.putBoolean(INTENT_KEY_SUCCEED, succeed); bundle.putInt(INTENT_KEY_ITEMS_INSERTED, total_items_inserted); return new SingleResponse<Bundle>(-1, bundle, null); } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { if (response != null && response.data != null && response.data.getBoolean(INTENT_KEY_SUCCEED)) { notifyForUpdatedUri(TweetingsService.this, uri); } super.onPostExecute(response); } } public class StoreHomeTimelineTask extends StoreStatusesTask { private final boolean is_auto_refresh; public StoreHomeTimelineTask(final List<ListResponse<twitter4j.Status>> result, final boolean is_auto_refresh, final boolean should_set_min_id) { super(result, Statuses.CONTENT_URI, should_set_min_id); this.is_auto_refresh = is_auto_refresh; } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { mStoreStatusesTaskId = -1; final boolean succeed = response != null && response.data != null && response.data.getBoolean(INTENT_KEY_SUCCEED); final Bundle extras = new Bundle(); extras.putBoolean(INTENT_KEY_SUCCEED, succeed); if (shouldSetMinId() && getTotalItemsInserted() > 0) { extras.putLong(INTENT_KEY_MIN_ID, response != null && response.data != null ? response.data.getLong(INTENT_KEY_MIN_ID, -1) : -1); } sendBroadcast(new Intent(BROADCAST_HOME_TIMELINE_REFRESHED).putExtras(extras)); final int items_inserted = response.data.getInt(INTENT_KEY_ITEMS_INSERTED); mNewStatusesCount += items_inserted; if (items_inserted > 0) { Intent intent = new Intent(BROADCAST_TABS_NEW_TWEETS); intent.putExtra(INTENT_KEY_UPDATE_TAB, TAB_HOME); sendBroadcast(intent); } if (succeed && is_auto_refresh && mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_HOME_TIMELINE, false)) { if (items_inserted > 0) { final String message = getResources().getQuantityString(R.plurals.Ntweets, mNewStatusesCount, mNewStatusesCount); final Intent delete_intent = new Intent(BROADCAST_NOTIFICATION_CLEARED); final Bundle delete_extras = new Bundle(); delete_extras.putInt(INTENT_KEY_NOTIFICATION_ID, NOTIFICATION_ID_HOME_TIMELINE); delete_intent.putExtras(delete_extras); final Intent content_intent = new Intent(TweetingsService.this, HomeActivity.class); content_intent.setAction(Intent.ACTION_MAIN); content_intent.addCategory(Intent.CATEGORY_LAUNCHER); final Bundle content_extras = new Bundle(); content_extras.putInt(INTENT_KEY_INITIAL_TAB, HomeActivity.TAB_POSITION_HOME); content_intent.putExtras(content_extras); if (mPreferences.getBoolean(PREFERENCE_KEY_LOCAL_NOTIFICATIONS, true)) { mNotificationManager.notify(NOTIFICATION_ID_HOME_TIMELINE, buildNotification(getString(R.string.new_notifications), message, R.drawable.ic_stat_tweet, content_intent, delete_intent)); } } } super.onPostExecute(response); } } class StoreLocalTrendsTask extends StoreTrendsTask { public StoreLocalTrendsTask(final ListResponse<Trends> result) { super(result, CachedTrends.Local.CONTENT_URI); } } class StoreMentionsTask extends StoreStatusesTask { private final boolean is_auto_refresh; public StoreMentionsTask(final List<ListResponse<twitter4j.Status>> result, final boolean is_auto_refresh, boolean should_set_min_id) { super(result, Mentions.CONTENT_URI, should_set_min_id); this.is_auto_refresh = is_auto_refresh; } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { mStoreMentionsTaskId = -1; final boolean succeed = response != null && response.data != null && response.data.getBoolean(INTENT_KEY_SUCCEED); final Bundle extras = new Bundle(); extras.putBoolean(INTENT_KEY_SUCCEED, succeed); if (shouldSetMinId() && getTotalItemsInserted() > 0) { extras.putLong(INTENT_KEY_MIN_ID, response != null && response.data != null ? response.data.getLong(INTENT_KEY_MIN_ID, -1) : -1); } sendBroadcast(new Intent(BROADCAST_MENTIONS_REFRESHED).putExtras(extras)); final int items_inserted = response.data.getInt(INTENT_KEY_ITEMS_INSERTED); if (items_inserted > 0) { Intent intent = new Intent(BROADCAST_TABS_NEW_TWEETS); intent.putExtra(INTENT_KEY_UPDATE_TAB, TAB_MENTIONS); sendBroadcast(intent); } if (succeed && is_auto_refresh && mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_MENTIONS, false)) { mNewMentionsCount += items_inserted; if (items_inserted > 0) { final Intent delete_intent = new Intent(BROADCAST_NOTIFICATION_CLEARED); final Bundle delete_extras = new Bundle(); delete_extras.putInt(INTENT_KEY_NOTIFICATION_ID, NOTIFICATION_ID_MENTIONS); delete_intent.putExtras(delete_extras); final Intent content_intent = new Intent(TweetingsService.this, HomeActivity.class); content_intent.setAction(Intent.ACTION_MAIN); content_intent.addCategory(Intent.CATEGORY_LAUNCHER); final Bundle content_extras = new Bundle(); content_extras.putInt(INTENT_KEY_INITIAL_TAB, HomeActivity.TAB_POSITION_MENTIONS); content_intent.putExtras(content_extras); final String title = getString(R.string.mentions); final String message = getResources().getQuantityString(R.plurals.Nmentions, mNewMentionsCount, mNewMentionsCount); final Notification notification = buildNotification(title, message, R.drawable.ic_stat_mention, content_intent, delete_intent); if (mPreferences.getBoolean(PREFERENCE_KEY_LOCAL_NOTIFICATIONS, true)) { mNotificationManager.notify(NOTIFICATION_ID_MENTIONS, notification); } } } super.onPostExecute(response); } } class StoreReceivedDirectMessagesTask extends StoreDirectMessagesTask { private final boolean is_auto_refresh; public StoreReceivedDirectMessagesTask(final List<ListResponse<DirectMessage>> result, final boolean is_auto_refresh) { super(result, DirectMessages.Inbox.CONTENT_URI); this.is_auto_refresh = is_auto_refresh; } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { mStoreReceivedDirectMessagesTaskId = -1; final boolean succeed = response != null && response.data != null && response.data.getBoolean(INTENT_KEY_SUCCEED); sendBroadcast( new Intent(BROADCAST_RECEIVED_DIRECT_MESSAGES_REFRESHED).putExtra(INTENT_KEY_SUCCEED, succeed)); if (succeed && is_auto_refresh && mPreferences.getBoolean(PREFERENCE_KEY_NOTIFICATION_ENABLE_DIRECT_MESSAGES, false)) { final int items_inserted = response.data.getInt(INTENT_KEY_ITEMS_INSERTED); mNewMessagesCount += items_inserted; if (items_inserted > 0) { final String message = getResources().getQuantityString(R.plurals.Ndirect_messages, mNewMessagesCount, mNewMessagesCount); final Intent delete_intent = new Intent(BROADCAST_NOTIFICATION_CLEARED); final Bundle delete_extras = new Bundle(); delete_extras.putInt(INTENT_KEY_NOTIFICATION_ID, NOTIFICATION_ID_DIRECT_MESSAGES); delete_intent.putExtras(delete_extras); final Intent content_intent = new Intent(TweetingsService.this, HomeActivity.class); content_intent.setAction(Intent.ACTION_MAIN); content_intent.addCategory(Intent.CATEGORY_LAUNCHER); final Bundle content_extras = new Bundle(); content_extras.putInt(INTENT_KEY_INITIAL_TAB, HomeActivity.TAB_POSITION_MESSAGES); content_intent.putExtras(content_extras); if (mPreferences.getBoolean(PREFERENCE_KEY_LOCAL_NOTIFICATIONS, true)) { mNotificationManager.notify(NOTIFICATION_ID_DIRECT_MESSAGES, buildNotification(getString(R.string.new_notifications), message, R.drawable.ic_stat_direct_message, content_intent, delete_intent)); } } } super.onPostExecute(response); } } class StoreSentDirectMessagesTask extends StoreDirectMessagesTask { public StoreSentDirectMessagesTask(final List<ListResponse<DirectMessage>> result) { super(result, DirectMessages.Outbox.CONTENT_URI); } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { mStoreSentDirectMessagesTaskId = -1; final boolean succeed = response != null && response.data != null && response.data.getBoolean(INTENT_KEY_SUCCEED); sendBroadcast( new Intent(BROADCAST_SENT_DIRECT_MESSAGES_REFRESHED).putExtra(INTENT_KEY_SUCCEED, succeed)); super.onPostExecute(response); } } abstract class StoreStatusesTask extends ManagedAsyncTask<Void, Void, SingleResponse<Bundle>> { private final List<ListResponse<twitter4j.Status>> responses; private final Uri uri; private final boolean should_set_min_id; int total_items_inserted = 0; public StoreStatusesTask(final List<ListResponse<twitter4j.Status>> result, final Uri uri, final boolean should_set_min_id) { super(TweetingsService.this, mAsyncTaskManager); responses = result; this.should_set_min_id = should_set_min_id; this.uri = uri; } public int getTotalItemsInserted() { return total_items_inserted; } public boolean shouldSetMinId() { return should_set_min_id; } @Override protected SingleResponse<Bundle> doInBackground(final Void... args) { boolean succeed = false; final Uri query_uri = buildQueryUri(uri, false); final ArrayList<Long> newly_inserted_ids = new ArrayList<Long>(); final long[] old_ids = getAllStatusesIds(TweetingsService.this, uri, mPreferences.getBoolean(PREFERENCE_KEY_ENABLE_FILTER, false)); for (final ListResponse<twitter4j.Status> response : responses) { final long account_id = response.account_id; final List<twitter4j.Status> statuses = response.list; if (statuses == null || statuses.size() <= 0) { continue; } final ArrayList<Long> ids_in_db = Utils.getStatusIdsInDatabase(TweetingsService.this, query_uri, account_id); final boolean no_items_before = ids_in_db.size() <= 0; final List<ContentValues> values_list = new ArrayList<ContentValues>(); final List<Long> status_ids = new ArrayList<Long>(), retweet_ids = new ArrayList<Long>(); long min_id = -1; for (final twitter4j.Status status : statuses) { if (status == null) { continue; } final long status_id = status.getId(); final long retweet_id = status.getRetweetedStatus() != null ? status.getRetweetedStatus().getId() : -1; status_ids.add(status_id); if ((retweet_id <= 0 || !retweet_ids.contains(retweet_id)) && !retweet_ids.contains(status_id)) { if (status_id < min_id || min_id == -1) { min_id = status_id; } if (retweet_id > 0) { retweet_ids.add(retweet_id); } values_list.add(makeStatusContentValues(status, account_id)); } } int rows_deleted = -1; // Delete all rows conflicting before new data inserted. { final ArrayList<Long> account_newly_inserted = new ArrayList<Long>(); account_newly_inserted.addAll(status_ids); account_newly_inserted.removeAll(ids_in_db); newly_inserted_ids.addAll(account_newly_inserted); final StringBuilder where = new StringBuilder(); final String ids_string = ListUtils.toString(status_ids, ',', true); where.append(Statuses.ACCOUNT_ID + " = " + account_id); where.append(" AND "); where.append("("); where.append(Statuses.STATUS_ID + " IN ( " + ids_string + " ) "); where.append(" OR "); where.append(Statuses.RETWEET_ID + " IN ( " + ids_string + " ) "); where.append(")"); rows_deleted = mResolver.delete(query_uri, where.toString(), null); } // Insert previously fetched items. mResolver.bulkInsert(query_uri, values_list.toArray(new ContentValues[values_list.size()])); final int actual_items_inserted = values_list.size() - rows_deleted; if (actual_items_inserted > 0) { total_items_inserted += actual_items_inserted; } int variance = 0; final int load_item_limit = mPreferences.getInt(PREFERENCE_KEY_LOAD_ITEM_LIMIT, PREFERENCE_DEFAULT_LOAD_ITEM_LIMIT); if (load_item_limit > 50) { variance = 5; } else if (load_item_limit > 100) { variance = 10; } boolean insert_gap = false; int tryCount = load_item_limit - variance; if (no_items_before) { insert_gap = false; } if (response.list.size() == 0) { insert_gap = false; } else if (load_item_limit == response.list.size()) { insert_gap = true; } else if (response.list.size() > tryCount) { insert_gap = true; } //final boolean insert_gap = rows_deleted == 1 && status_ids.contains(response.max_id) // || rows_deleted == 0 && response.max_id == -1 && !no_items_before; if (insert_gap) { final ContentValues values = new ContentValues(); values.put(Statuses.IS_GAP, 1); final StringBuilder where = new StringBuilder(); where.append(Statuses.ACCOUNT_ID + "=" + account_id); where.append(" AND " + Statuses.STATUS_ID + "=" + min_id); mResolver.update(query_uri, values, where.toString(), null); // Ignore gaps newly_inserted_ids.remove(min_id); } succeed = true; } final long[] new_ids = getAllStatusesIds(TweetingsService.this, uri, mPreferences.getBoolean(PREFERENCE_KEY_ENABLE_FILTER, false)); final Bundle bundle = new Bundle(); bundle.putBoolean(INTENT_KEY_SUCCEED, succeed); getAllStatusesIds(TweetingsService.this, uri, mPreferences.getBoolean(PREFERENCE_KEY_ENABLE_FILTER, false)); bundle.putInt(INTENT_KEY_ITEMS_INSERTED, new_ids.length - old_ids.length); if (should_set_min_id && total_items_inserted > 0) { bundle.putLong(INTENT_KEY_MIN_ID, ListUtils.min(newly_inserted_ids)); } return new SingleResponse<Bundle>(-1, bundle, null); } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { if (response.data.getBoolean(INTENT_KEY_SUCCEED)) { notifyForUpdatedUri(TweetingsService.this, uri); } super.onPostExecute(response); mAsyncTaskManager.add(new CacheUsersTask(responses), true); } } class StoreTrendsTask extends ManagedAsyncTask<Void, Void, SingleResponse<Bundle>> { private final ListResponse<Trends> response; private final Uri uri; public StoreTrendsTask(final ListResponse<Trends> result, Uri uri) { super(TweetingsService.this, mAsyncTaskManager); response = result; this.uri = uri; } @Override protected SingleResponse<Bundle> doInBackground(final Void... args) { final Bundle bundle = new Bundle(); if (response != null) { final Uri query_uri = buildQueryUri(uri, false); final List<Trends> messages = response.list; if (messages != null && messages.size() > 0) { final ContentValues[] values_array = makeTrendsContentValues(messages); mResolver.delete(query_uri, null, null); mResolver.bulkInsert(query_uri, values_array); bundle.putBoolean(INTENT_KEY_SUCCEED, true); } } return new SingleResponse<Bundle>(-1, bundle, null); } @Override protected void onPostExecute(final SingleResponse<Bundle> response) { final Intent intent = new Intent(BROADCAST_TRENDS_UPDATED); if (response != null && response.data != null && response.data.getBoolean(INTENT_KEY_SUCCEED)) { notifyForUpdatedUri(TweetingsService.this, uri); intent.putExtra(INTENT_KEY_SUCCEED, true); } super.onPostExecute(response); sendBroadcast(intent); } } class StoreWeeklyTrendsTask extends StoreTrendsTask { public StoreWeeklyTrendsTask(final ListResponse<Trends> result) { super(result, CachedTrends.Weekly.CONTENT_URI); } } class UpdateProfileImageTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private final long account_id; private final Uri image_uri; private final boolean delete_image; public UpdateProfileImageTask(final long account_id, final Uri image_uri, final boolean delete_image) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.image_uri = image_uri; this.delete_image = delete_image; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null && image_uri != null && "file".equals(image_uri.getScheme())) { try { final User user = twitter.updateProfileImage(new File(image_uri.getPath())); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null) { Toast.makeText(TweetingsService.this, R.string.profile_image_update_success, Toast.LENGTH_SHORT) .show(); if (delete_image) { new File(image_uri.getPath()).delete(); } } else { showErrorToast(R.string.update, result.exception, true); } final Intent intent = new Intent(BROADCAST_PROFILE_UPDATED); intent.putExtra(INTENT_KEY_USER_ID, account_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class UpdateBannerImageTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private final long account_id; private final Uri image_uri; private final boolean delete_image; public UpdateBannerImageTask(final long account_id, final Uri image_uri, final boolean delete_image) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.image_uri = image_uri; this.delete_image = delete_image; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null && image_uri != null && "file".equals(image_uri.getScheme())) { try { final User user = twitter.updateBannerImage(new File(image_uri.getPath())); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { //if (result != null && result.data != null) { Toast.makeText(TweetingsService.this, R.string.profile_banner_update_success, Toast.LENGTH_SHORT) .show(); if (delete_image) { new File(image_uri.getPath()).delete(); } //} else { //showErrorToast(R.string.update, result.exception, true); //} final Intent intent = new Intent(BROADCAST_PROFILE_UPDATED); intent.putExtra(INTENT_KEY_USER_ID, account_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class UpdateProfileTask extends ManagedAsyncTask<Void, Void, SingleResponse<User>> { private final long account_id; private final String name, url, location, description; public UpdateProfileTask(final long account_id, final String name, final String url, final String location, final String description) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.name = name; this.url = url; this.location = location; this.description = description; } @Override protected SingleResponse<User> doInBackground(final Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final User user = twitter.updateProfile(name, url, location, description); return new SingleResponse<User>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<User>(account_id, null, e); } } return new SingleResponse<User>(account_id, null, null); } @Override protected void onPostExecute(final SingleResponse<User> result) { if (result != null && result.data != null) { Toast.makeText(TweetingsService.this, R.string.profile_update_success, Toast.LENGTH_SHORT).show(); } else { showErrorToast(R.string.update, result.exception, true); } final Intent intent = new Intent(BROADCAST_PROFILE_UPDATED); intent.putExtra(INTENT_KEY_USER_ID, account_id); intent.putExtra(INTENT_KEY_SUCCEED, result != null && result.data != null); sendBroadcast(intent); super.onPostExecute(result); } } class ScheduleStatusTask extends ManagedAsyncTask<Void, Void, String> { private final Validator validator = new Validator(); private String schedule_date; private long[] account_ids; private String content; private Location location; private Uri image_uri; private long in_reply_to; private final AudioManager audioManager = (AudioManager) getSystemService(Activity.AUDIO_SERVICE); public ScheduleStatusTask(final String schedule_date, final long[] account_ids, final String content, final Location location, final Uri image_uri, final long in_reply_to, final boolean delete_image) { super(TweetingsService.this, mAsyncTaskManager); this.account_ids = account_ids != null ? account_ids : new long[0]; this.content = content; this.location = location; this.image_uri = image_uri; this.in_reply_to = in_reply_to; this.schedule_date = schedule_date; } @Override protected String doInBackground(final Void... params) { if (account_ids.length == 0) return null; final String unshortened_content = content; final String send_on_date = schedule_date; final StatusUpdate status = new StatusUpdate(unshortened_content); final String deviceId = Secure.getString(getContentResolver(), Secure.ANDROID_ID); if (location != null) { status.setLocation(new GeoLocation(location.getLatitude(), location.getLongitude())); } if (in_reply_to > 0) { status.setInReplyToStatusId(in_reply_to); } for (final long account_id : account_ids) { final String screen_name = getAccountUsername(TweetingsService.this, account_id); final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); AccessToken accessToken = null; try { accessToken = twitter.getOAuthAccessToken(); } catch (TwitterException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } HttpClient client = HttpClientFactory.getThreadSafeClient(); HttpPost post = new HttpPost(TWEETINGS_SCHEDULER_POST_URL); if (accessToken != null) { try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); // Get the deviceID nameValuePairs.add(new BasicNameValuePair("status", unshortened_content)); if (in_reply_to > 0) { nameValuePairs.add(new BasicNameValuePair("replyto", String.valueOf(in_reply_to))); } if (location != null) { nameValuePairs.add(new BasicNameValuePair("display_coordinates", "true")); nameValuePairs .add(new BasicNameValuePair("lat", String.valueOf(location.getLatitude()))); nameValuePairs .add(new BasicNameValuePair("long", String.valueOf(location.getLongitude()))); } nameValuePairs.add(new BasicNameValuePair("app", "android")); TimeZone tz = TimeZone.getDefault(); Date now = new Date(); int offsetFromUtc = tz.getOffset(now.getTime()); nameValuePairs.add(new BasicNameValuePair("time", send_on_date)); nameValuePairs.add(new BasicNameValuePair("tz", String.valueOf(offsetFromUtc))); nameValuePairs.add(new BasicNameValuePair("u", screen_name)); nameValuePairs.add(new BasicNameValuePair("did", deviceId)); nameValuePairs.add(new BasicNameValuePair("se", accessToken.getTokenSecret())); nameValuePairs.add(new BasicNameValuePair("tk", accessToken.getToken())); post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = client.execute(post); BufferedReader rd = new BufferedReader( new InputStreamReader(response.getEntity().getContent())); String line = ""; while ((line = rd.readLine()) != null) { return null; //Log.e("HttpResponse", line); } } catch (IOException e) { e.printStackTrace(); } } } return ""; } @Override protected void onPostExecute(final String result) { boolean isMuted = false; switch (audioManager.getRingerMode()) { case AudioManager.RINGER_MODE_NORMAL: isMuted = false; break; case AudioManager.RINGER_MODE_SILENT: isMuted = true; break; case AudioManager.RINGER_MODE_VIBRATE: isMuted = true; break; } if (mPreferences.getBoolean(PREFERENCE_KEY_SOUND_SEND, true)) { if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); } mPlayer.release(); } mPlayer = MediaPlayer.create(TweetingsService.this, R.raw.whoosh); if (isMuted == true) { mPlayer.setVolume(0, 0); } mPlayer.start(); } //if (result != null) { Toast.makeText(TweetingsService.this, R.string.schedule_success, Toast.LENGTH_SHORT).show(); //} //else { //Toast.makeText(TweetingsService.this, R.string.schedule_error, Toast.LENGTH_SHORT).show(); //} super.onPostExecute(result); } } class BufferStatusTask extends ManagedAsyncTask<Void, Void, String> { private final Validator validator = new Validator(); private long[] account_ids; private String content; private String buffer_access_token; private final AudioManager audioManager = (AudioManager) getSystemService(Activity.AUDIO_SERVICE); public BufferStatusTask(final long[] account_ids, final String content) { super(TweetingsService.this, mAsyncTaskManager); this.account_ids = account_ids != null ? account_ids : new long[0]; this.content = content; this.buffer_access_token = mPreferences.getString(PREFERENCE_KEY_BUFFERAPP_ACCESS_TOKEN, null); } @Override protected String doInBackground(final Void... params) { boolean oneOrMoreFailed = true; if (account_ids.length == 0) return null; if (buffer_access_token == null) return null; final String unshortened_content = content; final StatusUpdate status = new StatusUpdate(unshortened_content); String accountJson = null; HttpClient client = HttpClientFactory.getThreadSafeClient(); try { HttpResponse response = client.execute(new HttpGet( "https://api.bufferapp.com/1/profiles.json?access_token=" + buffer_access_token)); BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), "UTF-8")); String sResponse; StringBuilder s = new StringBuilder(); while ((sResponse = reader.readLine()) != null) { s = s.append(sResponse); } accountJson = s.toString(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } if (accountJson != null) { try { JSONArray jArray = new JSONArray(accountJson); for (int i = 0; i < jArray.length(); i++) { JSONObject jObject = jArray.getJSONObject(i); final String service = jObject.getString("service"); final String service_user = jObject.getString("service_username").toLowerCase(); final String profile_id = jObject.getString("id"); if (service != null && service.equals("twitter")) { for (final long account_id : account_ids) { final String screen_name = getAccountUsername(TweetingsService.this, account_id) .toLowerCase(); if (screen_name.equals(service_user)) { // We have a matching user! try { HttpPost post = new HttpPost( "https://api.bufferapp.com/1/updates/create.json"); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); nameValuePairs.add(new BasicNameValuePair("text", unshortened_content)); nameValuePairs .add(new BasicNameValuePair("access_token", buffer_access_token)); nameValuePairs.add(new BasicNameValuePair("profile_ids[]", profile_id)); post.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = client.execute(post); BufferedReader rd = new BufferedReader( new InputStreamReader(response.getEntity().getContent())); String line = ""; String outputContent = ""; while ((line = rd.readLine()) != null) { outputContent += line; //Log.e("HttpResponse", line); } if (!outputContent.equals("")) { JSONObject bufferResponse = new JSONObject(outputContent); boolean didSucceed = bufferResponse.getBoolean("success"); if (didSucceed == true) { oneOrMoreFailed = false; } else { oneOrMoreFailed = true; } } } catch (IOException e) { e.printStackTrace(); } } } } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { return null; } if (oneOrMoreFailed == false) { boolean isMuted = false; switch (audioManager.getRingerMode()) { case AudioManager.RINGER_MODE_NORMAL: isMuted = false; break; case AudioManager.RINGER_MODE_SILENT: isMuted = true; break; case AudioManager.RINGER_MODE_VIBRATE: isMuted = true; break; } if (mPreferences.getBoolean(PREFERENCE_KEY_SOUND_SEND, true)) { if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); } mPlayer.release(); } mPlayer = MediaPlayer.create(TweetingsService.this, R.raw.whoosh); if (isMuted == true) { mPlayer.setVolume(0, 0); } mPlayer.start(); } return ""; } return null; } @Override protected void onPostExecute(final String result) { if (result == null) { Toast.makeText(TweetingsService.this, R.string.buffer_failed, Toast.LENGTH_SHORT).show(); } else { boolean isMuted = false; switch (audioManager.getRingerMode()) { case AudioManager.RINGER_MODE_NORMAL: isMuted = false; break; case AudioManager.RINGER_MODE_SILENT: isMuted = true; break; case AudioManager.RINGER_MODE_VIBRATE: isMuted = true; break; } if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); } mPlayer.release(); } mPlayer = MediaPlayer.create(TweetingsService.this, R.raw.whoosh); if (isMuted == true) { mPlayer.setVolume(0, 0); } mPlayer.start(); Toast.makeText(TweetingsService.this, R.string.tweet_buffered, Toast.LENGTH_SHORT).show(); } super.onPostExecute(result); } } class UpdateStatusTask extends ManagedAsyncTask<Void, Void, List<SingleResponse<twitter4j.Status>>> { private final ImageUploaderInterface uploader; private final TweetShortenerInterface shortener; private final Validator validator = new Validator(); private long[] account_ids; private String content; private Location location; private Uri image_uri; private Timer uploadTimer; private long in_reply_to; private boolean use_uploader, use_shortener, delete_image, is_possibly_sensitive; private Notification notification; private NotificationManager notificationManager; private final AudioManager audioManager = (AudioManager) getSystemService(Activity.AUDIO_SERVICE); public UpdateStatusTask(final long[] account_ids, final String content, final Location location, final Uri image_uri, final long in_reply_to, final boolean is_possibly_sensitive, final boolean delete_image) { super(TweetingsService.this, mAsyncTaskManager); final String uploader_component = mPreferences.getString(PREFERENCE_KEY_IMAGE_UPLOADER, null); final String shortener_component = mPreferences.getString(PREFERENCE_KEY_TWEET_SHORTENER, null); use_uploader = !isNullOrEmpty(uploader_component); uploader = use_uploader ? ImageUploaderInterface.getInstance(getApplication(), uploader_component) : null; use_shortener = !isNullOrEmpty(shortener_component); shortener = use_shortener ? TweetShortenerInterface.getInstance(getApplication(), shortener_component) : null; this.account_ids = account_ids != null ? account_ids : new long[0]; this.content = content; this.location = location; this.image_uri = image_uri; this.in_reply_to = in_reply_to; this.delete_image = delete_image; this.is_possibly_sensitive = is_possibly_sensitive; } @Override protected List<SingleResponse<twitter4j.Status>> doInBackground(final Void... params) { final List<SingleResponse<twitter4j.Status>> result = new ArrayList<SingleResponse<twitter4j.Status>>(); if (account_ids.length == 0) return result; try { if (use_shortener && shortener == null) throw new TweetShortenerNotFoundException(); final String image_path = getImagePathFromUri(TweetingsService.this, image_uri); final File image_file = image_path != null ? new File(image_path) : null; if (uploader != null) { uploader.waitForService(); } final String unshortened_content = content; final StatusUpdate status = new StatusUpdate(unshortened_content); if (location != null) { status.setLocation(new GeoLocation(location.getLatitude(), location.getLongitude())); } if (in_reply_to > 0) { status.setInReplyToStatusId(in_reply_to); } if (!use_uploader && image_file != null && image_file.exists()) { status.setMedia(image_file); } status.setPossiblySensitive(is_possibly_sensitive); for (final long account_id : account_ids) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (!use_uploader && image_file != null && image_file.exists()) { /*CreateNotification(); uploadTimer = new Timer(); uploadTimer.schedule(new TimerTask() { @Override public void run() { UploadProgressMethod(twitter); } }, 0, 50);*/ } if (twitter != null) { try { result.add(new SingleResponse<twitter4j.Status>(account_id, twitter.updateStatus(status), null)); } catch (final TwitterException e) { e.printStackTrace(); result.add(new SingleResponse<twitter4j.Status>(account_id, null, e)); } } } } catch (final UpdateStatusException e) { for (final long account_id : account_ids) { result.add(new SingleResponse<twitter4j.Status>(account_id, null, e)); } } return result; } protected void CreateNotification() { // configure the notification Intent intent = new Intent(TweetingsService.this, HomeActivity.class); final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0); notification = new Notification(R.drawable.logo, getString(R.string.uploading_media), System.currentTimeMillis()); notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.upload_progress); notification.contentIntent = pendingIntent; notification.contentView.setImageViewResource(R.id.status_icon, R.drawable.logo); notification.contentView.setTextViewText(R.id.status_text, getString(R.string.uploading_media)); notification.contentView.setProgressBar(R.id.status_progress, 100, 0, false); notificationManager = (NotificationManager) getApplicationContext() .getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(NOTIFICATION_ID_UPLOAD_PROGRESS, notification); } protected void UploadProgressMethod(final Twitter twitter) { if (twitter.getHttpClientWrapper() != null) { HttpClientWrapper http = twitter.getHttpClientWrapper(); float progress = (float) http.getRequestStatus() / (float) http.getRequestLength(); float longPc = progress * 100; int percentage = Math.round(longPc); if (notification != null && notificationManager != null) { notification.contentView.setProgressBar(R.id.status_progress, 100, percentage, false); // inform the progress bar of updates in progress notificationManager.notify(NOTIFICATION_ID_UPLOAD_PROGRESS, notification); } } ; } @Override protected void onPostExecute(final List<SingleResponse<twitter4j.Status>> result) { /*if (uploadTimer != null) { uploadTimer.cancel(); } NotificationManager notificationManager = (NotificationManager) getApplicationContext() .getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancelAll();*/ boolean succeed = true; Exception exception = null; final List<Long> failed_account_ids = new ArrayList<Long>(); for (final SingleResponse<twitter4j.Status> response : result) { if (response.data == null) { succeed = false; failed_account_ids.add(response.account_id); if (exception == null) { exception = response.exception; } } } if (succeed) { boolean isMuted = false; switch (audioManager.getRingerMode()) { case AudioManager.RINGER_MODE_NORMAL: isMuted = false; break; case AudioManager.RINGER_MODE_SILENT: isMuted = true; break; case AudioManager.RINGER_MODE_VIBRATE: isMuted = true; break; } if (mPreferences.getBoolean(PREFERENCE_KEY_SOUND_SEND, true)) { if (mPlayer != null) { if (mPlayer.isPlaying()) { mPlayer.stop(); } mPlayer.release(); } mPlayer = MediaPlayer.create(TweetingsService.this, R.raw.whoosh); if (isMuted == true) { mPlayer.setVolume(0, 0); } mPlayer.start(); } Toast.makeText(TweetingsService.this, R.string.send_success, Toast.LENGTH_SHORT).show(); if (image_uri != null && delete_image) { final String path = getImagePathFromUri(TweetingsService.this, image_uri); if (path != null) { new File(path).delete(); } } } else { showErrorToast(R.string.send, exception, true); final ContentValues values = new ContentValues(); values.put(Drafts.ACCOUNT_IDS, ListUtils.toString(failed_account_ids, ';', false)); values.put(Drafts.IN_REPLY_TO_STATUS_ID, in_reply_to); values.put(Drafts.TEXT, content); if (mPreferences.getBoolean(PREFERENCE_KEY_AUTOMATIC_RETRY, false)) { values.put(Drafts.IS_QUEUED, true); } else { values.put(Drafts.IS_QUEUED, false); } if (image_uri != null) { values.put(Drafts.IS_IMAGE_ATTACHED, !delete_image); values.put(Drafts.IS_PHOTO_ATTACHED, delete_image); values.put(Drafts.IMAGE_URI, parseString(image_uri)); } mResolver.insert(Drafts.CONTENT_URI, values); final String title = getString(R.string.tweet_not_sent); final String message = getString(R.string.tweet_not_sent_summary); final Intent intent = new Intent(INTENT_ACTION_DRAFTS); final Notification notification = buildNotification(title, message, R.drawable.ic_stat_tweet, intent, null); mNotificationManager.notify(NOTIFICATION_ID_DRAFTS, notification); } super.onPostExecute(result); // Add sound in here if (mPreferences.getBoolean(PREFERENCE_KEY_REFRESH_AFTER_TWEET, true)) { final long[] activated_ids = getActivatedAccountIds(TweetingsService.this); getHomeTimeline(activated_ids, null); if (mPreferences.getBoolean(PREFERENCE_KEY_HOME_REFRESH_MENTIONS, false)) { getMentions(account_ids, null); } if (mPreferences.getBoolean(PREFERENCE_KEY_HOME_REFRESH_DIRECT_MESSAGES, false)) { getReceivedDirectMessages(account_ids, null); //getSentDirectMessages(account_ids, null); } } } class ImageUploaderNotFoundException extends UpdateStatusException { private static final long serialVersionUID = 1041685850011544106L; public ImageUploaderNotFoundException() { super(R.string.error_message_image_uploader_not_found); } } class ImageUploadException extends UpdateStatusException { private static final long serialVersionUID = 8596614696393917525L; public ImageUploadException() { super(R.string.error_message_image_upload_failed); } } class StatusTooLongException extends UpdateStatusException { private static final long serialVersionUID = -6469920130856384219L; public StatusTooLongException() { super(R.string.error_message_status_too_long); } } class TweetShortenerNotFoundException extends UpdateStatusException { private static final long serialVersionUID = -7262474256595304566L; public TweetShortenerNotFoundException() { super(R.string.error_message_tweet_shortener_not_found); } } class TweetShortenException extends UpdateStatusException { private static final long serialVersionUID = 3075877185536740034L; public TweetShortenException() { super(R.string.error_message_tweet_shorten_failed); } } class UpdateStatusException extends Exception { private static final long serialVersionUID = -1267218921727097910L; public UpdateStatusException(int message) { super(getString(message)); } } } class UpdateUserListProfileTask extends ManagedAsyncTask<Void, Void, SingleResponse<UserList>> { private final long account_id; private final int list_id; private final boolean is_public; private final String name, description; public UpdateUserListProfileTask(long account_id, int list_id, boolean is_public, String name, String description) { super(TweetingsService.this, mAsyncTaskManager); this.account_id = account_id; this.name = name; this.list_id = list_id; this.is_public = is_public; this.description = description; } @Override protected SingleResponse<UserList> doInBackground(Void... params) { final Twitter twitter = getTwitterInstance(TweetingsService.this, account_id, false); if (twitter != null) { try { final UserList user = twitter.updateUserList(list_id, name, is_public, description); return new SingleResponse<UserList>(account_id, user, null); } catch (final TwitterException e) { return new SingleResponse<UserList>(account_id, null, e); } } return new SingleResponse<UserList>(account_id, null, null); } @Override protected void onPostExecute(SingleResponse<UserList> result) { final Intent intent = new Intent(BROADCAST_USER_LIST_DETAILS_UPDATED); intent.putExtra(INTENT_KEY_LIST_ID, list_id); if (result != null && result.data != null && result.data.getId() > 0) { Toast.makeText(TweetingsService.this, R.string.profile_update_success, Toast.LENGTH_SHORT).show(); intent.putExtra(INTENT_KEY_SUCCEED, true); } else { showErrorToast(R.string.update, result.exception, true); } sendBroadcast(intent); super.onPostExecute(result); } } }