Android Open Source - HashQanda Main Activity






From Project

Back to project page HashQanda.

License

The source code is released under:

GNU General Public License

If you think the Android project HashQanda listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package au.com.infiniterecursion.hashqanda;
/*ww  w . j  a  v a 2  s  . co m*/
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Tweet;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;
import twitter4j.http.AccessToken;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/*
 * Main HashQanda Activity 
 * 
 * AUTHORS:
 * 
 * Andy Nicholson
 * 
 * 2011
 * Copyright Infinite Recursion Pty Ltd.
 * http://www.infiniterecursion.com.au
 */

public class MainActivity extends ListActivity {

  private static final String TAG = "hashqanda";
  private HQApp app;
  
  
  boolean autoRefreshPreference;
  String str_numberTweets;
  int numberTweets;
  SharedPreferences prefs;

  // UI threaded updater infrastructure
  private final ScheduledExecutorService scheduler = Executors
      .newScheduledThreadPool(1);

  ScheduledFuture<?> tweet_loader_handler;

  final Runnable tweet_loader = new Runnable() {
    public void run() {

      Log.d(TAG, " Auto loader starting ");

      tryToStartLoader();

    }
  };

  // Menu ids
  private static final int MENU_ITEM_1 = Menu.FIRST;
  private static final int MENU_ITEM_2 = MENU_ITEM_1 + 1;
  private static final int MENU_ITEM_3 = MENU_ITEM_2 + 1;
  private static final int MENU_ITEM_4 = MENU_ITEM_3 + 1;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    app = (HQApp) getApplication();

    Log.d(TAG,
        "onCreate , launching asynch loading if thread not running ? "
            + app.isThread_running());
    
    app.setShowing_tweet_dialog(false);
  }

  public void onResume() {
    super.onResume();
    
    
    
    Log.d(TAG, " on Resume... running thread ? " + app.isThread_running());
    prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

    autoRefreshPreference = prefs.getBoolean("autoloadingPreference", true);
    str_numberTweets = prefs.getString("numberTweetsPreference", "30");
    numberTweets = Integer.valueOf(str_numberTweets).intValue();

    // set up adapter
    TweetAdapter adapter = new TweetAdapter(this, R.layout.tweet_row, app
        .getTweetList());
    setListAdapter(adapter);
    app.setListAdapter(adapter);

    tryToStartLoader();

    if (autoRefreshPreference) {
      Log.d(TAG, "Starting autorefresh scheduler");
      tweet_loader_handler = scheduler.scheduleAtFixedRate(tweet_loader,
          30, 60, TimeUnit.SECONDS);

    } else {
      tweet_loader_handler = null;
    }

  }

  private void tryToStartLoader() {
    
    //dont do it, if user in middle of tweeting.
    if (app.isShowing_tweet_dialog()) return;
    
    // If we are still running, show dialog again, or else launch threaded
    // loader
    if (app.isThread_running()) {

      ThreadedLoader loader = app.getLoader();
      if (loader != null) {

        loader.showDialog();

      } else {
        Log.e(TAG, "Loader is null, though thread is running ?!");
      }

    } else {

      ThreadedLoader loader = new ThreadedLoader();
      loader.start();
      app.setLoader(loader);

    }
  }

  public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, " on Destroy");
  }

  public void onPause() {
    super.onPause();
    Log.d(TAG, " on Pause. running thread ? " + app.isThread_running());

    if (app.isThread_running()) {

      ThreadedLoader loader = app.getLoader();
      if (loader != null) {

        loader.dismissDialog();

      } else {
        Log.e(TAG, "Loader is null, though thread is running ?!");
      }
    }

    // cancel the periodic loader.
    if (tweet_loader_handler != null)
      tweet_loader_handler.cancel(true);

  }

  public int getVersionCode() {
    int v = 0;
    try {
      v = getPackageManager().getPackageInfo(
          getApplicationInfo().packageName, 0).versionCode;
    } catch (NameNotFoundException e) {
      // Huh? Really?
    }
    return v;
  }

  public String getVersionName() {
    String name = null;
    try {
      name = getPackageManager().getPackageInfo(
          getApplicationInfo().packageName, 0).versionName;
    } catch (NameNotFoundException e) {
      // Huh? Really?
    }
    return name;
  }

  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);

    Log.i(TAG, "OnPrepareOptionsMenu called");

    menu.clear();

    addConstantMenuItems(menu);

    return true;
  }

  private void addConstantMenuItems(Menu menu) {
    // ALWAYS ON menu items.
    MenuItem menu_about = menu.add(0, MENU_ITEM_1, 0, R.string.about);
    menu_about.setIcon(R.drawable.wizard48);

    MenuItem menu_tweet = menu.add(0, MENU_ITEM_4, 0, R.string.tweet);
    menu_tweet.setIcon(R.drawable.sun48);

    MenuItem menu_prefs = menu.add(0, MENU_ITEM_2, 0, R.string.preferences);
    menu_prefs.setIcon(R.drawable.options);

    MenuItem menu_refresh = menu.add(0, MENU_ITEM_3, 0, R.string.refresh);
    menu_refresh.setIcon(R.drawable.business48);

  }

  @Override
  public boolean onOptionsItemSelected(MenuItem menuitem) {
    int menuNum = menuitem.getItemId();

    Log.d("MENU", "Option " + menuNum + " selected");

    switch (menuitem.getItemId()) {

    case MENU_ITEM_1:

      // ABOUT
      String mesg = getString(R.string.about_this);
      // find&replace VERSION
      mesg = mesg.replace("VERSION", "version " + getVersionName());

      final SpannableString s = new SpannableString(mesg);
      Linkify.addLinks(s, Linkify.ALL);

      // Licenses
      String mesg2 = getString(R.string.third_party_licenses);

      final SpannableString s2 = new SpannableString(mesg2);
      Linkify.addLinks(s2, Linkify.ALL);

      AlertDialog about = new AlertDialog.Builder(this).setMessage(s)
          .setPositiveButton(R.string.yes,
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,
                    int whichButton) {

                }
              }).setNegativeButton(R.string.licenses,
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,
                    int whichButton) {

                  AlertDialog licenses = new AlertDialog.Builder(
                      MainActivity.this)
                      .setMessage(s2)
                      .setPositiveButton(
                          R.string.yes,
                          new DialogInterface.OnClickListener() {
                            public void onClick(
                                DialogInterface dialog,
                                int whichButton) {

                            }
                          }).show();

                  // makes links work
                  ((TextView) licenses
                      .findViewById(android.R.id.message))
                      .setMovementMethod(LinkMovementMethod
                          .getInstance());

                }
              }).show();

      // makes links work
      ((TextView) about.findViewById(android.R.id.message))
          .setMovementMethod(LinkMovementMethod.getInstance());

      break;

    case MENU_ITEM_2:

      // Preferences
      Intent intent = new Intent().setClass(this,
          PreferencesActivity.class);
      this.startActivity(intent);

      break;

    case MENU_ITEM_3:

      // refresh
      tryToStartLoader();

      break;

    case MENU_ITEM_4:

      // tweeting

      String twitterToken,
      twitterTokenSecret;

      String[] toks = twitterTokens();
      twitterToken = toks[0];
      twitterTokenSecret = toks[1];

      if (twitterToken != null && twitterTokenSecret != null) {
        showTweetDialog();
      } else {

        // Need to authorise.

        Toast
            .makeText(
                MainActivity.this,
                R.string.you_need_to_authorise_this_application_with_twitter_first_,
                Toast.LENGTH_LONG).show();

        // Launch Authorisation first.
        Intent intent2 = new Intent().setClass(this,
            TwitterOAuthActivity.class);
        this.startActivity(intent2);
      }

      break;

    default:
      return super.onOptionsItemSelected(menuitem);
    }

    return true;
  }

  public class ThreadedLoader extends Thread {

    ProgressDialog pdialog;

    public void dismissDialog() {
      MainActivity.this.runOnUiThread(new Runnable() {

        public void run() {
          if (pdialog != null && pdialog.isShowing()) {
            pdialog.dismiss();
          }
          pdialog = null;
        }
      });

    }

    public void showDialog() {
      // Show dialog on MainActivity UI thread
      MainActivity.this.runOnUiThread(new Runnable() {

        public void run() {

          if (pdialog == null) {

            pdialog = ProgressDialog
                .show(
                    MainActivity.this,
                    "HashQanda",
                    "Loading conversation from twitter. Please wait...",
                    true);

          }
        }

      });
    }

    public void run() {

      // Tell app we are running
      app.setThread_running(true);

      showDialog();

      // do long running network ops
      final boolean loaded_ok = loadTweets();

      // Dismiss dialog on UI thread, and then either update adapter , or
      // show Toast
      dismissDialog();

      MainActivity.this.runOnUiThread(new Runnable() {

        public void run() {
          Log.d(TAG, " load Tweets success ? " + loaded_ok);

          if (loaded_ok) {
            app.getListAdapter().notifyDataSetChanged();
          } else {
            Toast.makeText(MainActivity.this,
                "Failed to connect to twitter. Sorry",
                Toast.LENGTH_LONG).show();
          }
        }

      });

      // Finally tell app we arent running anymore.
      app.setThread_running(false);

    }

  }

  public class CachedBitmapAndTweet {

    Bitmap bm;
    Tweet twt;

  }

  public boolean loadTweets() {

    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb.setDebugEnabled(true).setOAuthConsumerKey("Q2DfeCNOxprbDp66fWlw")
        .setOAuthConsumerSecret(
            "TgyJ26CKXz1SxGiEJx4HG9rytFsqiMZlEPeCO7S9g");

    Twitter twitter = new TwitterFactory(cb.build()).getInstance();
    // clear tweet list.
    MainActivity.this.runOnUiThread(new Runnable() {

      public void run() {
        // add to it , via the runOnUIThread
        app.getTweetList().clear();
      }

    });

    try {
      Log.d(TAG, " starting Tweets loading ");
      Query q = new Query("#qanda");

      q.setRpp(numberTweets);

      QueryResult result = twitter.search(q);
      List<Tweet> tweets = result.getTweets();
      for (Tweet tweet : tweets) {
        // Log.d(TAG, "@" + tweet.getFromUser() + " - " +
        // tweet.getText());
        // Log.d(TAG, " img url " + tweet.getProfileImageUrl());

        final CachedBitmapAndTweet cachedbmtwt = new CachedBitmapAndTweet();

        cachedbmtwt.twt = tweet;

        try {
          URL url = new URL(tweet.getProfileImageUrl());
          InputStream is = (InputStream) url.getContent();

          if (is != null) {
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            cachedbmtwt.bm = bitmap;
          } else {
            cachedbmtwt.bm = null;
          }

        } catch (MalformedURLException e) {
          e.printStackTrace();
          cachedbmtwt.bm = null;
        } catch (IOException e) {
          e.printStackTrace();
          cachedbmtwt.bm = null;
        } catch (NullPointerException npe) {
          npe.printStackTrace();
          cachedbmtwt.bm = null;
        }

        MainActivity.this.runOnUiThread(new Runnable() {

          public void run() {
            // add to it , via the runOnUIThread
            app.getTweetList().add(cachedbmtwt);
          }

        });

      }

      Log.d(TAG, " finished Tweets loading ");

      return true;

    } catch (TwitterException te) {
      te.printStackTrace();
      Log.d(TAG, "Failed to search tweets: " + te.getMessage());
      return false;
    }
  }

  public class TweetAdapter extends ArrayAdapter<CachedBitmapAndTweet> {
    private ArrayList<CachedBitmapAndTweet> items;
    private TweetViewHolder tweetHolder;

    private class TweetViewHolder {
      ImageView img;
      TextView msg;
    }

    public TweetAdapter(Context context, int tvResId,
        ArrayList<CachedBitmapAndTweet> items) {
      super(context, tvResId, items);
      this.items = items;
    }

    public View getView(int pos, View convertView, ViewGroup parent) {
      View v = convertView;

      if (v == null) {
        LayoutInflater vi = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.tweet_row, null);
        tweetHolder = new TweetViewHolder();
        tweetHolder.img = (ImageView) v.findViewById(R.id.imageView1);
        tweetHolder.msg = (TextView) v.findViewById(R.id.textView1);
        v.setTag(tweetHolder);
      } else {
        tweetHolder = (TweetViewHolder) v.getTag();
      }

      // check items hasnt been reset
      if (items == null || items.size() == 0) {
        return v;
      }

      CachedBitmapAndTweet bmtwt = items.get(pos);

      if (bmtwt != null) {
        String raw = bmtwt.twt.getFromUser() + " : "
            + bmtwt.twt.getText();

        final SpannableString text = new SpannableString(raw);
        Linkify.addLinks(text, Linkify.ALL);
        
        tweetHolder.msg.setText(text);
        tweetHolder.msg.setMovementMethod(LinkMovementMethod.getInstance());
        
        if (bmtwt.bm != null) {
          tweetHolder.img.setImageBitmap(bmtwt.bm);
        } else {
          tweetHolder.img.setImageBitmap(null);
        }
      }

      return v;
    }
  }

  private void showTweetDialog() {
    
    app.setShowing_tweet_dialog(true);
    
    // Launch Tweet Edit View
    LayoutInflater inflater = (LayoutInflater) getApplicationContext()
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    final View tweet_dialog_view = inflater.inflate(R.layout.tweet_dialog,
        null);

    final EditText tweet_edittext = (EditText) tweet_dialog_view
        .findViewById(R.id.EditTextTweet);

    final Dialog d = new Dialog(this);
    Window w = d.getWindow();
    w.setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
        WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
    d.setTitle(R.string.tweet_dialog_title);
    // the edit layout defined in an xml file (in res/layout)
    d.setContentView(tweet_dialog_view);
    // Cancel
    Button cbutton = (Button) d.findViewById(R.id.button2Cancel);
    cbutton.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        
        app.setShowing_tweet_dialog(false);
        d.dismiss();
      }
    });
    // Edit
    Button ebutton = (Button) d.findViewById(R.id.button1Edit);
    ebutton.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        // save title and description to DB.
        String tweet = tweet_edittext.getText().toString();

        int end = (tweet.length() > 133) ? 133 : tweet.length();
        String real_tweet = "#qanda " + tweet.substring(0, end);
        Log.d(TAG, "New tweet is " + tweet);
        Log.d(TAG, "real tweet is " + real_tweet);

        String twitterToken, twitterTokenSecret;
        String[] toks = twitterTokens();
        twitterToken = toks[0];
        twitterTokenSecret = toks[1];

        if (twitterToken != null && twitterTokenSecret != null) {

          // Ok, now we can tweet this URL
          AccessToken a = new AccessToken(twitterToken,
              twitterTokenSecret);
          Twitter twitter = new TwitterFactory().getInstance();
          twitter.setOAuthConsumer(TwitterOAuthActivity.consumerKey,
              TwitterOAuthActivity.consumerSecret);
          twitter.setOAuthAccessToken(a);

          try {
            twitter.updateStatus(real_tweet);
            runOnUiThread(new Runnable() {
              public void run() {
                Toast.makeText(MainActivity.this,
                    R.string.tweet_posted,
                    Toast.LENGTH_LONG).show();
              }
            });
          } catch (TwitterException e) {
            // 
            e.printStackTrace();
            Log.e(TAG, " twittering failed " + e.getMessage());
          }
        } else {

          runOnUiThread(new Runnable() {
            public void run() {
              Toast.makeText(MainActivity.this,
                  R.string.tweet_not_posted,
                  Toast.LENGTH_LONG).show();
            }
          });

        }
        
        app.setShowing_tweet_dialog(false);
        d.dismiss();
      }
    });
    d.show();
  }

  private String[] twitterTokens() {

    // Check there is a valid twitter OAuth tokens.
    String twitterToken = prefs.getString("twitterToken", null);
    String twitterTokenSecret = prefs.getString("twitterTokenSecret", null);

    return new String[] { twitterToken, twitterTokenSecret };

  }

}




Java Source Code List

au.com.infiniterecursion.hashqanda.HQApp.java
au.com.infiniterecursion.hashqanda.MainActivity.java
au.com.infiniterecursion.hashqanda.PreferencesActivity.java
au.com.infiniterecursion.hashqanda.TwitterOAuthActivity.java