Lowe Quality… only the best!
Ryan
This user hasn't shared any biographical information
Posts by Ryan
How to Post a Tweet to Twitter with the OAuth API
Sep 2nd
Recently, I released a few twitter wrapper apps. Apps that use twitter to do searches for specific #twitter tags. I found that while there was tons of information on the internet about how to do it, I still had quite a bit of trouble putting together all of the pieces for Twitter’s new OAuth Api. I found many great guides such as this post on how to make an android callback, or this guide on using the Signpost library. Through a bunch of trial and error, I was able to put together a working version that posts tweets to a twitter account. This is a code snippet from the Activity class for the submit tweet page. This Activity presents a user with a button to log into their twitter account. They are taken to the web browser where they give twitter their permission to use the app. At that point, they are brought back to this activity through the onNewIntent method. The necessary twitter account information is then stored in Android preferences objects for future use.
-
-
public class SubmitTwitter extends Activity implements OnClickListener {
-
-
public static final String PREFS_NAME = "AccountPrefs";
-
public static final String PREFS_TWITTER_ACCOUNT_NAME = "TwitterAccountName";
-
public static final String PREFS_TWITTER_USER_TOKEN = "TwitterUserToken";
-
public static final String PREFS_TWITTER_USER_SECRET = "TwitterUserSecret";
-
public static final String PREFS_TWITTER_USER_VERIFIER = "TwitterVerifier";
-
-
private CommonsHttpOAuthConsumer httpOauthConsumer;
-
private DefaultOAuthProvider httpOauthprovider;
-
-
public static final String consumerKey = "[TWITTER_CONSUMER_KEY]";
-
public static final String consumerSecret = "[TWITTER_CONSUMER_SECRET]";
-
-
public static final String CALLBACKURL = "fml://submitTwitter";
-
-
@Override
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
-
setContentView(R.layout.submit_tweet);
-
-
SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
-
-
if (settings.contains(PREFS_TWITTER_ACCOUNT_NAME) && null != settings.getString(PREFS_TWITTER_ACCOUNT_NAME, null)) {
-
twitterAccountName = settings.getString(PREFS_TWITTER_ACCOUNT_NAME, "");
-
((TextView)findViewById(R.id.currentUser)).setText(twitterAccountName);
-
}
-
-
Button signIn = (Button) findViewById(R.id.signIn);
-
signIn.setOnClickListener(this);
-
-
Button signOut = (Button) findViewById(R.id.signOut);
-
signOut.setOnClickListener(this);
-
-
Button submit = (Button) findViewById(R.id.submit);
-
submit.setOnClickListener(new OnClickListener() {
-
-
@Override
-
public void onClick(View v) {
-
EditText request = (EditText) findViewById(R.id.request);
-
String tweet = request.getText().toString();
-
-
if (!"".equals(tweet)) {
-
TwitterSearch.Post(getBaseContext(), tweet + " #fml");
-
request.setText("");
-
startActivity(new Intent(getBaseContext(), MainActivity.class));
-
-
} else {
-
Toast.makeText(getBaseContext(), "You must include a Message.", Toast.LENGTH_LONG).show();
-
}
-
-
}
-
});
-
}
-
-
@Override
-
protected void onNewIntent(Intent intent) {
-
super.onNewIntent(intent);
-
Uri uri = intent.getData();
-
// Check if you got NewIntent event due to Twitter Call back only
-
if (uri != null && uri.toString().startsWith(CALLBACKURL)) {
-
-
String verifier = uri
-
.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
-
-
try {
-
// this will populate token and token_secret in consumer
-
httpOauthprovider.retrieveAccessToken(httpOauthConsumer,
-
verifier);
-
-
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
-
String userToken = httpOauthConsumer.getToken();
-
String tokenSecret = httpOauthConsumer.getTokenSecret();
-
Editor editor = prefs.edit();
-
editor.putString(PREFS_TWITTER_USER_TOKEN, userToken);
-
editor.putString(PREFS_TWITTER_USER_SECRET, tokenSecret);
-
editor.putString(PREFS_TWITTER_USER_VERIFIER, verifier);
-
editor.commit();
-
} catch (Exception e) {
-
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
-
}
-
}
-
}
-
-
@Override
-
public void onClick(View v) {
-
try {
-
httpOauthConsumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
-
httpOauthprovider = new DefaultOAuthProvider("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
-
String authUrl = httpOauthprovider.retrieveRequestToken(httpOauthConsumer, CALLBACKURL);
-
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
-
} catch (Exception e) {
-
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
-
}
-
}
-
}
This is the static method call that does the post to Twitter. It uses Signpost to create a signed request.
-
public class TwitterSearch {
-
private static final String TWITTER_POST_STATUS_URI = "http://api.twitter.com/1/statuses/update.json";
-
-
public static void Post(Context context, String status) {
-
-
SharedPreferences prefs = context.getSharedPreferences(SubmitTwitter.PREFS_NAME, Activity.MODE_PRIVATE);
-
-
try {
-
HttpPost post = new HttpPost(TWITTER_POST_STATUS_URI);
-
final List nvps = new ArrayList();
-
nvps.add(new BasicNameValuePair("status", status));
-
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
-
// set this to avoid 417 error (Expectation Failed)
-
post.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
-
-
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(SubmitTwitter.consumerKey, SubmitTwitter.consumerSecret);
-
consumer.setTokenWithSecret(prefs.getString(SubmitTwitter.PREFS_TWITTER_USER_TOKEN, ""),
-
prefs.getString(SubmitTwitter.PREFS_TWITTER_USER_SECRET, ""));
-
-
consumer.sign(post);
-
HttpClient client = new DefaultHttpClient();
-
final HttpResponse response = client.execute(post);
-
-
} catch (Exception e) {
-
Log.e("TwitterSearch", e.getMessage());
-
}
-
-
}
-
}
Finally we register our callback in our AndroidManifest.xml
-
<intent-filter>
-
<data android:scheme="fml" android:host="submitTwitter" />
-
</intent-filter>
I wouldn’t do it justice to attempt to explain in detail what is going on here… instead I would recommend looking over the blogs I pointed out above. Feel free to email me with any questions you have. I certainly believe that since Android is an open platform, as developers we owe it to each other to help to make the best apps possible. Email me at ryan at lowequalityapps.com
Introducing Pray for Me!
Aug 23rd
Using Twitter, Pray for Me discovers prayer requests from around the world. Submit your own prayer request with your own Twitter account.
Perfect way to help others around the world with the power of prayer!
New Features coming soon!
- Search for Prayers by location
- Respond to prayer requests
- Many more
GPS Phone Silencer passes the 50 download mark
Jul 30th
GPS Phone Silencer just passed the 50 download mark. See for yourself why people are enjoying this cheaper alternative to Locale for simple Phone ringer settings.
Version 1.4 of GPS Phone Silencer Released
Jul 29th
GPS Phone Silencer v1.4 has been released. This new version allows you to set your ringer (On/Silent/Vibrate) depending on Wifi connections. Have a Wifi connection at work? Set your phone to automatically go on Vibrate when you are connected. Set your phone to be on ringer when you are disconnected from all Wifi networks (like in the car).
Download it now in the App Store.
Introducing GPS Phone Silencer
Jul 6th
Lowe Quality Apps presents the GPS Phone Silencer. Just released to the android market. Check out the details page and buy it on your handheld today!
Welcome to Lowe Quality Apps
Jun 26th
Welcome to the Lowe Quality Application website! Stay tuned for news and features on latest android applications. Buy them on your handheld today!