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.fragment; import static com.dwdesign.tweetings.util.HtmlEscapeHelper.unescape; import static com.dwdesign.tweetings.util.Utils.clearUserColor; import static com.dwdesign.tweetings.util.Utils.findStatusInDatabases; import static com.dwdesign.tweetings.util.Utils.formatToLongTimeString; import static com.dwdesign.tweetings.util.Utils.getAccountColor; import static com.dwdesign.tweetings.util.Utils.getActivatedAccountIds; import static com.dwdesign.tweetings.util.Utils.getBiggerTwitterProfileImage; import static com.dwdesign.tweetings.util.Utils.getImagesInStatus; import static com.dwdesign.tweetings.util.Utils.getQuoteStatus; import static com.dwdesign.tweetings.util.Utils.getTwitterInstance; import static com.dwdesign.tweetings.util.Utils.getUserColor; import static com.dwdesign.tweetings.util.Utils.getUserTypeIconRes; import static com.dwdesign.tweetings.util.Utils.isMyActivatedAccount; import static com.dwdesign.tweetings.util.Utils.isMyRetweet; import static com.dwdesign.tweetings.util.Utils.isNullOrEmpty; import static com.dwdesign.tweetings.util.Utils.openConversation; import static com.dwdesign.tweetings.util.Utils.openUserProfile; import static com.dwdesign.tweetings.util.Utils.openUserRetweetedStatus; import static com.dwdesign.tweetings.util.Utils.openUserTimeline; import static com.dwdesign.tweetings.util.Utils.parseURL; import static com.dwdesign.tweetings.util.Utils.setMenuForStatus; import static com.dwdesign.tweetings.util.Utils.setUserColor; import static com.dwdesign.tweetings.util.Utils.showErrorToast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URLEncoder; import java.util.List; import java.util.Locale; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import com.dwdesign.menubar.MenuBar; import com.dwdesign.menubar.MenuBar.OnMenuItemClickListener; import com.dwdesign.tweetings.R; import com.dwdesign.tweetings.activity.ComposeActivity; import com.dwdesign.tweetings.app.TweetingsApplication; import com.dwdesign.tweetings.model.ImageSpec; import com.dwdesign.tweetings.model.Panes; import com.dwdesign.tweetings.model.ParcelableLocation; import com.dwdesign.tweetings.model.ParcelableStatus; import com.dwdesign.tweetings.provider.TweetStore.Accounts; import com.dwdesign.tweetings.provider.TweetStore.Filters; import com.dwdesign.tweetings.provider.TweetStore.Mentions; import com.dwdesign.tweetings.provider.TweetStore.Statuses; import com.dwdesign.tweetings.util.HtmlEscapeHelper; import com.dwdesign.tweetings.util.ImageLoaderWrapper; import com.dwdesign.tweetings.util.OnLinkClickHandler; import com.dwdesign.tweetings.util.ServiceInterface; import com.dwdesign.tweetings.util.TwidereLinkify; import twitter4j.Relationship; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.internal.org.json.JSONArray; import twitter4j.internal.org.json.JSONException; import twitter4j.internal.org.json.JSONObject; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; import android.graphics.drawable.Drawable; import android.location.Address; import android.location.Geocoder; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.text.Html; import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.view.Display; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.twitter.Extractor; public class StatusFragment extends BaseFragment implements OnClickListener, OnMenuItemClickListener, Panes.Right { private long mAccountId, mStatusId; private boolean mLoadMoreAutomatically; private boolean mFollowInfoDisplayed, mLocationInfoDisplayed; private ServiceInterface mService; private SharedPreferences mPreferences; private TextView mNameView, mScreenNameView, mTextView, mTimeAndSourceView, mInReplyToView, mLocationView, mRetweetedStatusView; private ImageView mProfileImageView; private Button mFollowButton; private View mStatusContent, mProfileView, mFollowIndicator, mImagesPreviewContainer, mContentScroller, mUserColorLabel; private MenuBar mMenuBar; private ProgressBar mStatusLoadProgress, mFollowInfoProgress; private FollowInfoTask mFollowInfoTask; private ImagesPreviewFragment mImagesPreviewFragment; private GetStatusTask mGetStatusTask; private LocationInfoTask mLocationInfoTask; private ParcelableStatus mStatus; private RelativeLayout mConversationView; private RelativeLayout mMarketView; private PlayStoreInfoTask mPlayInfoTask; private ImageLoaderWrapper mLazyImageLoader; private String mAppAwareUrl; private final BroadcastReceiver mStatusReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); if (BROADCAST_FRIENDSHIP_CHANGED.equals(action)) { if (mStatus != null && mStatus.user_id == intent.getLongExtra(INTENT_KEY_USER_ID, -1) && intent.getBooleanExtra(INTENT_KEY_SUCCEED, false)) { showFollowInfo(true); } } else if (BROADCAST_FAVORITE_CHANGED.equals(action)) { final long status_id = intent.getLongExtra(INTENT_KEY_STATUS_ID, -1); if (status_id > 0 && status_id == mStatusId) { getStatus(true); } } else if (BROADCAST_RETWEET_CHANGED.equals(action)) { final long status_id = intent.getLongExtra(INTENT_KEY_STATUS_ID, -1); if (status_id > 0 && status_id == mStatusId) { getStatus(true); } } else if (BROADCAST_TWITLONGER_EXPANDED.equals(action)) { final String expanded_status_text = intent.getStringExtra(INTENT_KEY_TWITLONGER_EXPANDED_TEXT); Spanned expanded_text = Html.fromHtml(expanded_status_text); mTextView.setText(expanded_text); final TwidereLinkify linkify = new TwidereLinkify(mTextView); linkify.setOnLinkClickListener( new OnLinkClickHandler(getActivity(), mAccountId, mStatus.is_possibly_sensitive)); linkify.addAllLinks(); final ContentResolver resolver = context.getContentResolver(); final ContentValues values = new ContentValues(); values.put(Statuses.TEXT, expanded_status_text); values.put(Statuses.TEXT_PLAIN, unescape(expanded_status_text)); int updated = resolver.update(Statuses.CONTENT_URI, values, Statuses.STATUS_ID + " = " + mStatus.status_id, null); if (updated > 0) { context.sendBroadcast(new Intent(BROADCAST_HOME_TIMELINE_DATABASE_UPDATED)); } values.clear(); values.put(Mentions.TEXT, expanded_status_text); values.put(Mentions.TEXT_PLAIN, unescape(expanded_status_text)); updated = resolver.update(Mentions.CONTENT_URI, values, Mentions.STATUS_ID + " = " + mStatus.status_id, null); if (updated > 0) { context.sendBroadcast(new Intent(BROADCAST_MENTIONS_DATABASE_UPDATED)); } } } }; @SuppressWarnings("deprecation") public void displayStatus(final ParcelableStatus status) { mStatus = null; mImagesPreviewFragment.clear(); if (status == null || getActivity() == null) return; mStatus = status; final String buffer_authorised = mPreferences.getString(PREFERENCE_KEY_BUFFERAPP_ACCESS_TOKEN, null); mMenuBar.inflate(R.menu.menu_status); final MenuItem bufferView = mMenuBar.getMenu().findItem(MENU_ADD_TO_BUFFER); if (bufferView != null) { if (buffer_authorised != null && !buffer_authorised.equals("")) { bufferView.setVisible(true); } else { bufferView.setVisible(false); } } setMenuForStatus(getActivity(), mMenuBar.getMenu(), status); mMenuBar.show(); final boolean is_multiple_account_enabled = getActivatedAccountIds(getActivity()).length > 1; updateUserColor(); mContentScroller .setBackgroundResource(is_multiple_account_enabled ? R.drawable.ic_label_account_nopadding : 0); if (is_multiple_account_enabled) { final Drawable d = mContentScroller.getBackground(); if (d != null) { d.mutate().setColorFilter(getAccountColor(getActivity(), status.account_id), PorterDuff.Mode.MULTIPLY); mContentScroller.invalidate(); } } mNameView.setText(status.name); mScreenNameView.setText("@" + status.screen_name); mScreenNameView.setCompoundDrawablesWithIntrinsicBounds( getUserTypeIconRes(status.is_verified, status.is_protected), 0, 0, 0); mTextView.setText(status.text); final TwidereLinkify linkify = new TwidereLinkify(mTextView); linkify.setOnLinkClickListener(new OnLinkClickHandler(getActivity(), mAccountId)); linkify.addAllLinks(); final boolean is_reply = status.in_reply_to_status_id > 0; final String time = formatToLongTimeString(getActivity(), status.status_timestamp); final String strTime = "<a href=\"https://twitter.com/" + status.screen_name + "/status/" + String.valueOf(status.status_id) + "\">" + time + "</a>"; final String source_html = status.source; if (!isNullOrEmpty(time) && !isNullOrEmpty(source_html)) { mTimeAndSourceView.setText(Html.fromHtml(getString(R.string.time_source, strTime, source_html))); } else if (isNullOrEmpty(time) && !isNullOrEmpty(source_html)) { mTimeAndSourceView.setText(Html.fromHtml(getString(R.string.source, source_html))); } else if (!isNullOrEmpty(time) && isNullOrEmpty(source_html)) { mTimeAndSourceView.setText(time); } mTimeAndSourceView.setMovementMethod(LinkMovementMethod.getInstance()); mInReplyToView.setVisibility(is_reply ? View.VISIBLE : View.GONE); mConversationView.setVisibility(is_reply ? View.VISIBLE : View.GONE); if (is_reply) { mInReplyToView.setText(getString(R.string.in_reply_to, status.in_reply_to_screen_name)); Display display = getActivity().getWindowManager().getDefaultDisplay(); int width = display.getWidth(); // deprecated int height = display.getHeight(); // deprecated int heightOfConversation = (height / 2) - 48 - 44; ViewGroup.LayoutParams params = mConversationView.getLayoutParams(); params.height = heightOfConversation; mConversationView.setLayoutParams(params); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction ft = null; ft = fragmentManager.beginTransaction(); final Fragment fragment = new ConversationFragment(); final Bundle args = new Bundle(); args.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); args.putLong(INTENT_KEY_STATUS_ID, status.in_reply_to_status_id); fragment.setArguments(args); ft.replace(R.id.conversation, fragment, getString(R.string.view_conversation)); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit(); } if (status.play_package != null) { mMarketView.setVisibility(View.VISIBLE); mPlayInfoTask = new PlayStoreInfoTask(); mPlayInfoTask.execute(); } else { mMarketView.setVisibility(View.GONE); } final boolean hires_profile_image = getResources().getBoolean(R.bool.hires_profile_image); final String preview_image = hires_profile_image ? getBiggerTwitterProfileImage(status.profile_image_url_string) : status.profile_image_url_string; mLazyImageLoader.displayProfileImage(mProfileImageView, preview_image); final List<ImageSpec> images = getImagesInStatus(status.text_html); mImagesPreviewContainer.setVisibility(images.size() > 0 ? View.VISIBLE : View.GONE); mImagesPreviewFragment.addAll(images); mImagesPreviewFragment.update(); if (mLoadMoreAutomatically == true) { mImagesPreviewFragment.show(); } mRetweetedStatusView.setVisibility(status.is_protected ? View.GONE : View.VISIBLE); if (status.retweet_id > 0) { final boolean display_name = mPreferences.getBoolean(PREFERENCE_KEY_DISPLAY_NAME, false); final String retweeted_by = display_name ? status.retweeted_by_name : status.retweeted_by_screen_name; mRetweetedStatusView.setText(status.retweet_count > 1 ? getString(R.string.retweeted_by_with_count, retweeted_by, status.retweet_count - 1) : getString(R.string.retweeted_by, retweeted_by)); mRetweetedStatusView.setVisibility(View.VISIBLE); } else { mRetweetedStatusView.setVisibility(View.GONE); mRetweetedStatusView.setText(R.string.users_retweeted_this); } mLocationView.setVisibility(ParcelableLocation.isValidLocation(status.location) ? View.VISIBLE : View.GONE); if (mLoadMoreAutomatically) { showFollowInfo(true); showLocationInfo(true); } else { mFollowIndicator.setVisibility(View.GONE); } } @Override public void onActivityCreated(final Bundle savedInstanceState) { mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); final TweetingsApplication application = getApplication(); mService = application.getServiceInterface(); mLazyImageLoader = application.getImageLoaderWrapper(); mImagesPreviewFragment = (ImagesPreviewFragment) Fragment.instantiate(getActivity(), ImagesPreviewFragment.class.getName()); super.onActivityCreated(savedInstanceState); setRetainInstance(true); mLoadMoreAutomatically = mPreferences.getBoolean(PREFERENCE_KEY_LOAD_MORE_AUTOMATICALLY, true); final Bundle bundle = getArguments(); if (bundle != null) { mAccountId = bundle.getLong(INTENT_KEY_ACCOUNT_ID); mStatusId = bundle.getLong(INTENT_KEY_STATUS_ID); bundle.setClassLoader(ParcelableStatus.class.getClassLoader()); mStatus = bundle.getParcelable(INTENT_KEY_STATUS); mImagesPreviewFragment.setStatus(mStatus); } mInReplyToView.setOnClickListener(this); mFollowButton.setOnClickListener(this); mProfileView.setOnClickListener(this); mLocationView.setOnClickListener(this); mRetweetedStatusView.setOnClickListener(this); mMenuBar.setOnMenuItemClickListener(this); final FragmentManager fm = getFragmentManager(); final FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.images_preview, mImagesPreviewFragment); ft.commit(); //if (mStatus != null) { //displayStatus(mStatus); //} else { //getStatus(false); //} } @Override public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { if (intent == null || mStatus == null) return; switch (requestCode) { case REQUEST_SET_COLOR: { if (resultCode == Activity.RESULT_OK) if (intent != null && intent.getExtras() != null) { final int color = intent.getIntExtra(Accounts.USER_COLOR, Color.TRANSPARENT); setUserColor(getActivity(), mStatus.user_id, color); updateUserColor(); } break; } } } @Override public void onClick(final View view) { if (mStatus == null) return; switch (view.getId()) { case R.id.profile: { openUserProfile(getActivity(), mStatus.account_id, mStatus.user_id, null); break; } case R.id.follow: { mService.createFriendship(mAccountId, mStatus.user_id); break; } case R.id.in_reply_to: { openConversation(getActivity(), mStatus.account_id, mStatus.status_id); break; } case R.id.location_view: { if (mStatus.location == null) return; final ParcelableLocation location = mStatus.location; if (location == null || !location.isValid()) return; final Uri.Builder builder = new Uri.Builder(); builder.scheme(SCHEME_TWEETINGS); builder.authority(AUTHORITY_MAP); builder.appendQueryParameter(QUERY_PARAM_LAT, String.valueOf(location.latitude)); builder.appendQueryParameter(QUERY_PARAM_LNG, String.valueOf(location.longitude)); startActivity(new Intent(Intent.ACTION_VIEW, builder.build())); break; } case R.id.retweet_view: { openUserRetweetedStatus(getActivity(), mStatus.account_id, mStatus.retweet_id > 0 ? mStatus.retweet_id : mStatus.status_id); break; } } } @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.view_status, container, false); mStatusContent = view.findViewById(R.id.content); mStatusLoadProgress = (ProgressBar) view.findViewById(R.id.status_load_progress); mUserColorLabel = view.findViewById(R.id.user_color_label); mContentScroller = view.findViewById(R.id.content_scroller); mImagesPreviewContainer = view.findViewById(R.id.images_preview); mLocationView = (TextView) view.findViewById(R.id.location_view); mRetweetedStatusView = (TextView) view.findViewById(R.id.retweet_view); mNameView = (TextView) view.findViewById(R.id.name); mScreenNameView = (TextView) view.findViewById(R.id.screen_name); mTextView = (TextView) view.findViewById(R.id.text); mProfileImageView = (ImageView) view.findViewById(R.id.profile_image); mTimeAndSourceView = (TextView) view.findViewById(R.id.time_source); mInReplyToView = (TextView) view.findViewById(R.id.in_reply_to); mFollowButton = (Button) view.findViewById(R.id.follow); mFollowIndicator = view.findViewById(R.id.follow_indicator); mFollowInfoProgress = (ProgressBar) view.findViewById(R.id.follow_info_progress); mProfileView = view.findViewById(R.id.profile); mMenuBar = (MenuBar) view.findViewById(R.id.menu_bar); mConversationView = (RelativeLayout) view.findViewById(R.id.conversation); mMarketView = (RelativeLayout) view.findViewById(R.id.market); return view; } @Override public void onDestroyView() { mStatus = null; mAccountId = -1; mStatusId = -1; if (mGetStatusTask != null) { mGetStatusTask.cancel(true); } if (mFollowInfoTask != null) { mFollowInfoTask.cancel(true); } if (mLocationInfoTask != null) { mLocationInfoTask.cancel(true); } if (mPlayInfoTask != null) { mPlayInfoTask.cancel(true); } super.onDestroyView(); } @SuppressLint({ "NewApi", "NewApi", "NewApi" }) @Override public boolean onMenuItemClick(final MenuItem item) { if (mStatus == null) return false; final String text_plain = mStatus.text_plain; final String screen_name = mStatus.screen_name; final String name = mStatus.name; switch (item.getItemId()) { case MENU_SHARE: { final Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, "@" + mStatus.screen_name + ": " + text_plain); startActivity(Intent.createChooser(intent, getString(R.string.share))); break; } case MENU_RETWEET: { if (isMyRetweet(mStatus)) { mService.destroyStatus(mAccountId, mStatus.retweet_id); } else { final long id_to_retweet = mStatus.is_retweet && mStatus.retweet_id > 0 ? mStatus.retweet_id : mStatus.status_id; mService.retweetStatus(mAccountId, id_to_retweet); } break; } case MENU_TRANSLATE: { translate(mStatus); break; } case MENU_QUOTE_REPLY: { final Intent intent = new Intent(INTENT_ACTION_COMPOSE); final Bundle bundle = new Bundle(); bundle.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); bundle.putLong(INTENT_KEY_IN_REPLY_TO_ID, mStatusId); bundle.putString(INTENT_KEY_IN_REPLY_TO_SCREEN_NAME, screen_name); bundle.putString(INTENT_KEY_IN_REPLY_TO_NAME, name); bundle.putBoolean(INTENT_KEY_IS_QUOTE, true); bundle.putString(INTENT_KEY_TEXT, getQuoteStatus(getActivity(), screen_name, text_plain)); intent.putExtras(bundle); startActivity(intent); break; } case MENU_QUOTE: { final Intent intent = new Intent(INTENT_ACTION_COMPOSE); final Bundle bundle = new Bundle(); bundle.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); bundle.putBoolean(INTENT_KEY_IS_QUOTE, true); bundle.putString(INTENT_KEY_TEXT, getQuoteStatus(getActivity(), screen_name, text_plain)); intent.putExtras(bundle); startActivity(intent); break; } case MENU_ADD_TO_BUFFER: { final Intent intent = new Intent(INTENT_ACTION_COMPOSE); final Bundle bundle = new Bundle(); bundle.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); bundle.putBoolean(INTENT_KEY_IS_BUFFER, true); bundle.putString(INTENT_KEY_TEXT, getQuoteStatus(getActivity(), screen_name, text_plain)); intent.putExtras(bundle); startActivity(intent); break; } case MENU_REPLY: { final Intent intent = new Intent(INTENT_ACTION_COMPOSE); final Bundle bundle = new Bundle(); final List<String> mentions = new Extractor().extractMentionedScreennames(text_plain); mentions.remove(screen_name); mentions.add(0, screen_name); bundle.putStringArray(INTENT_KEY_MENTIONS, mentions.toArray(new String[mentions.size()])); bundle.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); bundle.putLong(INTENT_KEY_IN_REPLY_TO_ID, mStatusId); bundle.putString(INTENT_KEY_IN_REPLY_TO_TWEET, text_plain); bundle.putString(INTENT_KEY_IN_REPLY_TO_SCREEN_NAME, screen_name); bundle.putString(INTENT_KEY_IN_REPLY_TO_NAME, name); intent.putExtras(bundle); startActivity(intent); break; } case MENU_FAV: { if (mStatus.is_favorite) { mService.destroyFavorite(mAccountId, mStatusId); } else { mService.createFavorite(mAccountId, mStatusId); } break; } case MENU_COPY_CLIPBOARD: { final String textToCopy = "@" + mStatus.screen_name + ": " + mStatus.text_plain; int sdk = android.os.Build.VERSION.SDK_INT; if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) { android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService( Context.CLIPBOARD_SERVICE); clipboard.setText(textToCopy); } else { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService( Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("Status", textToCopy); clipboard.setPrimaryClip(clip); } Toast.makeText(getActivity(), R.string.text_copied, Toast.LENGTH_SHORT).show(); break; } case MENU_DELETE: { mService.destroyStatus(mAccountId, mStatusId); break; } case MENU_EXTENSIONS: { final Intent intent = new Intent(INTENT_ACTION_EXTENSION_OPEN_STATUS); final Bundle extras = new Bundle(); extras.putParcelable(INTENT_KEY_STATUS, mStatus); intent.putExtras(extras); startActivity(Intent.createChooser(intent, getString(R.string.open_with_extensions))); break; } case MENU_MUTE_SOURCE: { final String source = HtmlEscapeHelper.unescape(mStatus.source); if (source == null) return false; final Uri uri = Filters.Sources.CONTENT_URI; final ContentValues values = new ContentValues(); final SharedPreferences.Editor editor = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).edit(); final ContentResolver resolver = getContentResolver(); values.put(Filters.TEXT, source); resolver.delete(uri, Filters.TEXT + " = '" + source + "'", null); resolver.insert(uri, values); editor.putBoolean(PREFERENCE_KEY_ENABLE_FILTER, true).commit(); Toast.makeText(getActivity(), getString(R.string.source_muted, source), Toast.LENGTH_SHORT).show(); break; } case MENU_SET_COLOR: { final Intent intent = new Intent(INTENT_ACTION_SET_COLOR); startActivityForResult(intent, REQUEST_SET_COLOR); break; } case MENU_CLEAR_COLOR: { clearUserColor(getActivity(), mStatus.user_id); updateUserColor(); break; } case MENU_RECENT_TWEETS: { openUserTimeline(getActivity(), mAccountId, mStatus.user_id, mStatus.screen_name); break; } case MENU_FIND_RETWEETS: { openUserRetweetedStatus(getActivity(), mStatus.account_id, mStatus.retweet_id > 0 ? mStatus.retweet_id : mStatus.status_id); break; } default: return false; } return super.onOptionsItemSelected(item); } @Override public void onStart() { super.onStart(); final IntentFilter filter = new IntentFilter(); filter.addAction(BROADCAST_FRIENDSHIP_CHANGED); filter.addAction(BROADCAST_FAVORITE_CHANGED); filter.addAction(BROADCAST_RETWEET_CHANGED); filter.addAction(BROADCAST_TWITLONGER_EXPANDED); registerReceiver(mStatusReceiver, filter); if (mStatus != null) { displayStatus(mStatus); } else { getStatus(false); } updateUserColor(); } @Override public void onStop() { unregisterReceiver(mStatusReceiver); super.onStop(); } protected void translate(final ParcelableStatus status) { ThreadPolicy tp = ThreadPolicy.LAX; StrictMode.setThreadPolicy(tp); String language = Locale.getDefault().getLanguage(); String url = "http://api.microsofttranslator.com/v2/Http.svc/Translate?contentType=" + URLEncoder.encode("text/plain") + "&appId=" + BING_TRANSLATE_API_KEY + "&from=&to=" + language + "&text="; url = url + URLEncoder.encode(status.text_plain); try { HttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(new HttpGet(url)); 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); } String finalString = s.toString(); finalString = finalString .replace("<string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">", ""); finalString = finalString.replace("</string>", ""); AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); builder.setTitle(getString(R.string.translate)); builder.setMessage(finalString); builder.setCancelable(true); builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); alert.show(); //Toast.makeText(getActivity(), finalString, Toast.LENGTH_LONG).show(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void getStatus(final boolean omit_intent_extra) { if (mGetStatusTask != null) { mGetStatusTask.cancel(true); } mGetStatusTask = new GetStatusTask(omit_intent_extra); mGetStatusTask.execute(); } private void showFollowInfo(final boolean force) { if (mFollowInfoDisplayed && !force) return; if (mFollowInfoTask != null) { mFollowInfoTask.cancel(true); } mFollowInfoTask = new FollowInfoTask(); mFollowInfoTask.execute(); } private void showLocationInfo(final boolean force) { if (mLocationInfoDisplayed && !force) return; if (mLocationInfoTask != null) { mLocationInfoTask.cancel(true); } mLocationInfoTask = new LocationInfoTask(); mLocationInfoTask.execute(); } private void updateUserColor() { if (mUserColorLabel != null && mStatus != null) { final Drawable d = mUserColorLabel.getBackground(); if (d != null) { d.mutate().setColorFilter(getUserColor(getActivity(), mStatus.user_id), Mode.MULTIPLY); mUserColorLabel.invalidate(); } } } class FollowInfoTask extends AsyncTask<Void, Void, Response<Boolean>> { @Override protected Response<Boolean> doInBackground(Void... params) { return isAllFollowing(); } @Override protected void onPostExecute(Response<Boolean> result) { if (getActivity() == null) return; if (result.exception == null) { mFollowIndicator.setVisibility(result.value == null || result.value ? View.GONE : View.VISIBLE); if (result.value != null) { mFollowButton.setVisibility(result.value ? View.GONE : View.VISIBLE); mFollowInfoDisplayed = true; } } mFollowInfoProgress.setVisibility(View.GONE); super.onPostExecute(result); mFollowInfoTask = null; } @Override protected void onPreExecute() { if (getActivity() == null) return; mFollowIndicator.setVisibility(View.VISIBLE); mFollowButton.setVisibility(View.GONE); mFollowInfoProgress.setVisibility(View.VISIBLE); super.onPreExecute(); } private Response<Boolean> isAllFollowing() { if (mStatus == null) return new Response<Boolean>(null, null); if (isMyActivatedAccount(getActivity(), mStatus.user_id)) return new Response<Boolean>(true, null); final Twitter twitter = getTwitterInstance(getActivity(), mStatus.account_id, false); if (twitter == null) return new Response<Boolean>(null, null); try { final Relationship result = twitter.showFriendship(mStatus.account_id, mStatus.user_id); if (!result.isSourceFollowingTarget()) return new Response<Boolean>(false, null); } catch (final TwitterException e) { return new Response<Boolean>(null, e); } return new Response<Boolean>(null, null); } } class GetStatusTask extends AsyncTask<Void, Void, Response<ParcelableStatus>> { private final boolean omit_intent_extra; public GetStatusTask(boolean omit_intent_extra) { this.omit_intent_extra = omit_intent_extra; } @Override protected Response<ParcelableStatus> doInBackground(Void... params) { ParcelableStatus status = null; if (!omit_intent_extra) { status = getArguments().getParcelable(INTENT_KEY_STATUS); if (status != null) return new Response<ParcelableStatus>(status, null); } status = findStatusInDatabases(getActivity(), mAccountId, mStatusId); if (status != null) return new Response<ParcelableStatus>(status, null); final Twitter twitter = getTwitterInstance(getActivity(), mAccountId, false); try { return new Response<ParcelableStatus>( new ParcelableStatus(twitter.showStatus(mStatusId), mAccountId, false), null); } catch (final TwitterException e) { return new Response<ParcelableStatus>(null, e); } } @Override protected void onPostExecute(Response<ParcelableStatus> result) { if (getActivity() == null) return; if (result.value == null) { showErrorToast(getActivity(), null, result.exception, true); } else { displayStatus(result.value); mStatusLoadProgress.setVisibility(View.GONE); mStatusContent.setVisibility(View.VISIBLE); mStatusContent.setEnabled(true); } setProgressBarIndeterminateVisibility(false); super.onPostExecute(result); } @Override protected void onPreExecute() { if (getActivity() == null) return; mStatusLoadProgress.setVisibility(View.VISIBLE); mStatusContent.setVisibility(View.INVISIBLE); mStatusContent.setEnabled(false); setProgressBarIndeterminateVisibility(true); super.onPreExecute(); } } class LocationInfoTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... params) { if (getActivity() == null || mStatus == null) return null; final ParcelableLocation location = mStatus.location; if (location == null) return null; try { final Geocoder coder = new Geocoder(getActivity()); final List<Address> addresses = coder.getFromLocation(location.latitude, location.longitude, 1); if (addresses.size() == 1) { final Address address = addresses.get(0); final StringBuilder builder = new StringBuilder(); final int max_idx = address.getMaxAddressLineIndex(); for (int i = 0; i < max_idx; i++) { builder.append(address.getAddressLine(i)); if (i != max_idx - 1) { builder.append(", "); } } return builder.toString(); } } catch (final IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { if (result != null) { mLocationView.setText(result); mLocationInfoDisplayed = true; } else { mLocationView.setText(R.string.view_map); mLocationInfoDisplayed = false; } super.onPostExecute(result); } } class Response<T> { public final T value; public final TwitterException exception; public Response(T value, TwitterException exception) { this.value = value; this.exception = exception; } } private class PlayStoreInfoTask extends AsyncTask<Void, Void, String> { // can use UI thread here protected void onPreExecute() { } // automatically done on worker thread (separate from UI thread) protected String doInBackground(final Void... args) { Uri playUrl = Uri.parse(mStatus.play_package); String packageId = playUrl.getQueryParameter("id"); String finalUrl = "http://dev.appaware.com/1/app/show.json?p=" + packageId + "&client_token=" + APPAWARE_CLIENT_TOKEN; StringBuilder s = new StringBuilder(); try { HttpClient httpclient = new DefaultHttpClient(); HttpResponse response; response = httpclient.execute(new HttpGet(finalUrl)); BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), "UTF-8")); String sResponse; while ((sResponse = reader.readLine()) != null) { s = s.append(sResponse); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return s.toString(); } // can use UI thread here protected void onPostExecute(final String result) { try { JSONObject playObj = new JSONObject(result); mAppAwareUrl = playObj.getString("url"); String name = playObj.getString("name"); String icon = playObj.getString("icon"); JSONArray screenshots = playObj.getJSONArray("screenshots"); String screenshot = screenshots.getString(0); TextView playTitleView = (TextView) getView().findViewById(R.id.play_title); playTitleView.setText(name); ImageView playIconView = (ImageView) getView().findViewById(R.id.play_icon); mLazyImageLoader.displayPreviewImage(playIconView, icon); ImageView playSSView = (ImageView) getView().findViewById(R.id.play_screenshot); mLazyImageLoader.displayPreviewImage(playSSView, screenshot); ImageView playButtonView = (ImageView) getView().findViewById(R.id.play_button); playButtonView.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(mStatus.play_package)); startActivity(browserIntent); } }); TextView playAttributionView = (TextView) getView().findViewById(R.id.play_attribution); playAttributionView.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(mAppAwareUrl)); startActivity(browserIntent); } }); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }