I'm new to android development (and java in general). I'm building an application that requires a user to signup by logging-in to their twitter account from where their basic information is imported and saved. The information required would be birthday, name (full names), username, location, sex, etc.
I'm using twitter4j to accomplish this. I've tried looking at the twitter4j documentation but being an android newbie (and java in general), the documentation is a little bit hard to understand so I seem to be unable to get it to do something other than set a status update.
This is the code in my activity:
package cc.co.localsquare.app;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.exception.OAuthNotAuthorizedException;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
public class ConnectTwitterActivity extends BaseActivity {
public final static String CONSUMER_KEY = "valid key";
public final static String CONSUMER_SECRET = "valid secret";
public final static String CALLBACK_URL = "localsquare://ConnectTwitterActivity2";
private CommonsHttpOAuthConsumer commonHttpOAuthConsumer;
private OAuthProvider authProvider;
private Twitter twitter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.connect_twitter);
commonHttpOAuthConsumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
authProvider = new DefaultOAuthProvider("http://twitter.com/oauth/request_token",
"http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
try {
String oAuthURL = authProvider.retrieveRequestToken(commonHttpOAuthConsumer, CALLBACK_URL);
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(oAuthURL)));
} catch (OAuthMessageSignerException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (OAuthCommunicationException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Uri uri = intent.getData();
if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
String verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
try {
authProvider.retrieveAccessToken(commonHttpOAuthConsumer, verifier);
AccessToken accessToken = new AccessToken(commonHttpOAuthConsumer.getToken(),
commonHttpOAuthConsumer.getTokenSecret());
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
twitter.setOAuthAccessToken(accessToken);
// Alternate way:
// twitter = new TwitterFactory().getOAuthAuthorizedInstance(CONSUMER_KEY, CONSUMER_SECRET,
// new AccessToken(commonHttpOAuthConsumer.getToken(), commonHttpOAuthConsumer.getTokenSecret()));
// Tweet message to be updated.
String tweet = "Hi there, This was sent from my application - OAuth, Twitter";
twitter.updateStatus(tweet);
}
catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG);
}
}
}
}
How EXACTLY can I solve my problem?
If you have the screen name of the twitter user for whom you need to get the details, then you can use User user = twitter.showUser(screenName);.Now you can access the information about the user by using getter functions on the object user, e.g. user.getName(), user.getLocation() etc.
Remember to import the User class in Eclipse. Generally you can also do it by pressing Ctrl+Shift+O in Eclipse.
Get the twitter object from the session once the login in complete. That can be used in the following way to extract the name
Twitter twitter = (Twitter) request.getSession().getAttribute("twitter");
long userID = twitter.getId();
twitter4j.User newUser=twitter.showUser(twitter.getScreenName());
String name=newUser.getName();
You can explore several methods from User class to get different attributes of user like profile image, friendlistlength etc
#Vineet Bhatia
Use twitter.showUser() method to get user details. To get user's name do user.getName() Remember javadoc is your friend.
Related
i'm trying to connect to SQL Server Database from android studio
i'm using jtds and already import "jtds-1.3.1.jar" module to android studio
in the import part below line i got error
import net.sourceforge.jtds.jdbc.*;
and the error is:
"error: package net.sourceforge.jtds.jdbc does not exist"
. i don't know what i miss.
package com.example.mycar4;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.StrictMode;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import net.sourceforge.jtds.jdbc.*;
public class database extends AppCompatActivity {
// Declaring layout button, edit texts
Button login;
EditText username,password;
ProgressBar progressBar;
// End Declaring layout button, edit texts
// Declaring connection variables
Connection con;
String un,pass,db,ip;
String usernam,passwordd;
//End Declaring connection variables
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_database);
// Getting values from button, texts and progress bar
login = (Button) findViewById(R.id.btn_Login);
username = (EditText) findViewById(R.id.et_username);
password = (EditText) findViewById(R.id.et_password);
progressBar = (ProgressBar) findViewById(R.id.pbbar);
progressBar.setVisibility(View.GONE);
// End Getting values from button, texts and progress bar
// Declaring Server ip, username, database name and password
ip = "***";
db = "***";
un = "***";
pass = "***";
// Declaring Server ip, username, database name and password
// Setting up the function when button login is clicked
login.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
usernam = username.getText().toString();
passwordd = password.getText().toString();
CheckLogin checkLogin = new CheckLogin();// this is the Asynctask, which is used to process in background to reduce load on app process
checkLogin.execute("");
}
});
//End Setting up the function when button login is clicked
}
public class CheckLogin extends AsyncTask<String,String,String>
{
String z = "";
Boolean isSuccess = false;
#Override
protected void onPreExecute()
{
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(String r)
{
progressBar.setVisibility(View.GONE);
Toast.makeText(database.this, r, Toast.LENGTH_SHORT).show();
if(isSuccess)
{
Toast.makeText(database.this , "Login Successfull" , Toast.LENGTH_LONG).show();
//finish();
}
}
#Override
protected String doInBackground(String... params)
{
if(usernam.trim().equals("")|| passwordd.trim().equals(""))
z = "Please enter Username and Password";
else
{
try
{
con = connectionclass(un, pass, db, ip); // Connect to database
if (con == null)
{
z = "Check Your Internet Access!";
}
else
{
String query = "select * from login where username= '" + usernam.toString() + "' and password = '"+ passwordd.toString() +"' ";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
if(rs.next())
{
z = "Login successful";
isSuccess=true;
con.close();
}
else
{
z = "Invalid Credentials!";
isSuccess = false;
}
}
}
catch (Exception ex)
{
isSuccess = false;
z = ex.getMessage();
}
}
return z;
}
}
#SuppressLint("NewApi")
public Connection connectionclass(String user, String password, String database, String server)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Connection connection = null;
String ConnectionURL = null;
try
{
Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
ConnectionURL = "jdbc:jtds:sqlserver://sql5009.mywindowshosting.com;database=DB_A2C00B_login;user=DB_A2C00B_login_admin;password=login#123";
// ConnectionURL =
"jdbc:jtds:sqlserver://192.168.1.9;database=msss;instance=SQLEXPRESS;Network
Protocol=NamedPipes" ;
connection = DriverManager.getConnection(ConnectionURL);
}
catch (SQLException se)
{
Log.e("error here 1 : ", se.getMessage());
}
catch (ClassNotFoundException e)
{
Log.e("error here 2 : ", e.getMessage());
}
catch (Exception e)
{
Log.e("error here 3 : ", e.getMessage());
}
return connection;
}
}
To connect an Android App with a SQL server, you'll need to set up a web (Http) server in between the two. You can build this web server in any language you're familiar with be it java (J2EE) or php etc.
This web server will be hosted with your SQL server and will take Http requests from the Android app, process it, forward the request as queries to your SQL server and then return it back to your app as REST/JSON (the current format of sending data over the web) or SOAP/XML (the old way of sending data over the web).
App >> Web Server >> Database Server
The web server should be RESTful and the app can interact with it via Http requests via the library Retrofit2.
Here's some resources to get you started;
Retrofit by Square.
Retrofit Github repository.
Simple CRUD example with Java RESTful Web Service, a brief tutorial.
RESTful Web Services: A Tutorial Android + Java Web Services
if you are using android studio or eclipse you should put the jtds jar file in the correct location
it is in the libs (library) folder inside app n your project. Once you put it in the libs > right click then add library.
another note you should use 1.2.7 or lower which is much supported
i want to integration a twitter in my application,
this is my code:
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
// Constants
/**
* Register your here app https://dev.twitter.com/apps/new and get your
* consumer key and secret
* */
static String TWITTER_CONSUMER_KEY = "<my key>";
static String TWITTER_CONSUMER_SECRET = "<my secure key>";
// Preference Constants
static String PREFERENCE_NAME = "twitter_oauth";
static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
static final String PREF_KEY_OAUTH_SECRET = "oauth_token_secret";
static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLogedIn";
static final String TWITTER_CALLBACK_URL = "oauth://t4jsample";
// Twitter oauth urls
static final String URL_TWITTER_AUTH = "https://api.twitter.com/oauth/authenticate";
static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
static final String URL_TWITTER_OAUTH_TOKEN = "oauth_token";
// Login button
Button btnLoginTwitter;
// Update status button
Button btnUpdateStatus;
// Logout button
Button btnLogoutTwitter;
// EditText for update
EditText txtUpdate;
// lbl update
TextView lblUpdate;
TextView lblUserName;
// Progress dialog
ProgressDialog pDialog;
// Twitter
private static Twitter twitter;
private static RequestToken requestToken;
// Shared Preferences
private static SharedPreferences mSharedPreferences;
// Internet Connection detector
private ConnectionDetector cd;
// Alert Dialog Manager
AlertDialogManager alert = new AlertDialogManager();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(MainActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Check if twitter keys are set
if (TWITTER_CONSUMER_KEY.trim().length() == 0
|| TWITTER_CONSUMER_SECRET.trim().length() == 0) {
// Internet Connection is not present
alert.showAlertDialog(MainActivity.this, "Twitter oAuth tokens",
"Please set your twitter oauth tokens first!", false);
// stop executing code by return
return;
}
// All UI elements
btnLoginTwitter = (Button) findViewById(R.id.btnLoginTwitter);
btnUpdateStatus = (Button) findViewById(R.id.btnUpdateStatus);
btnLogoutTwitter = (Button) findViewById(R.id.btnLogoutTwitter);
txtUpdate = (EditText) findViewById(R.id.txtUpdateStatus);
lblUpdate = (TextView) findViewById(R.id.lblUpdate);
lblUserName = (TextView) findViewById(R.id.lblUserName);
// Shared Preferences
mSharedPreferences = getApplicationContext().getSharedPreferences(
"MyPref", 0);
/**
* Twitter login button click event will call loginToTwitter() function
* */
btnLoginTwitter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Call login twitter function
loginToTwitter();
}
});
/**
* This if conditions is tested once is redirected from twitter page.
* Parse the uri to get oAuth Verifier
* */
if (!isTwitterLoggedInAlready()) {
Uri uri = getIntent().getData();
if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {
// oAuth verifier
String verifier = uri
.getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
try {
Log.e("Twitter Login ... >", 0+"");
// Get the access token
AccessToken accessToken = twitter.getOAuthAccessToken(
requestToken, verifier);
Log.e("Twitter Login ... >", 1+"");
// Shared Preferences
Editor e = mSharedPreferences.edit();
Log.e("Twitter Login ... >", 2+"");
// After getting access token, access token secret
// store them in application preferences
e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
e.putString(PREF_KEY_OAUTH_SECRET,
accessToken.getTokenSecret());
// Store login status - true
e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
e.commit(); // save changes
Log.e("Twitter OAuth Token", "> " + accessToken.getToken());
// Hide login button
btnLoginTwitter.setVisibility(View.GONE);
// Show Update Twitter
lblUpdate.setVisibility(View.VISIBLE);
txtUpdate.setVisibility(View.VISIBLE);
btnUpdateStatus.setVisibility(View.VISIBLE);
btnLogoutTwitter.setVisibility(View.VISIBLE);
// Getting user details from twitter
// For now i am getting his name only
long userID = accessToken.getUserId();
Log.e("Twitter Login ... >", 3+"");
User user = twitter.showUser(userID);
String username = user.getName();
Log.e("Twitter Login ... >", 4+"");
// Displaying in xml ui
lblUserName.setText(Html.fromHtml("<b>Welcome " + username
+ "</b>"));
} catch (Exception e) {
// Check log for login errors
Log.e("Twitter Login Error", "> " + e.getMessage());
}
}
}
}
/**
* Function to login twitter
* */
private void loginToTwitter() {
new myConnection().execute(1);
}
/**
* Check user already logged in your application using twitter Login flag is
* fetched from Shared Preferences
* */
private boolean isTwitterLoggedInAlready() {
// return twitter login status from Shared Preferences
return mSharedPreferences.getBoolean(PREF_KEY_TWITTER_LOGIN, false);
}
class myConnection extends AsyncTask<Integer, Integer, Integer> {
#Override
protected Integer doInBackground(Integer... params) {
// Check if already logged in
if (!isTwitterLoggedInAlready()) {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
Configuration configuration = builder.build();
TwitterFactory factory = new TwitterFactory(configuration);
twitter = factory.getInstance();
try {
requestToken = twitter
.getOAuthRequestToken(TWITTER_CALLBACK_URL);
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(requestToken.getAuthenticationURL())));
} catch (TwitterException e) {
e.printStackTrace();
}
} else {
// user already logged into twitter
}
return 1;
}
}
}
The Log prints Twitter Login ... > 0 and then an exception happened , i catch and print this statment
Log.e("Twitter Login Error", "> " + e.getMessage());
the e.getMessage() is null
any help would be appreciated
Its all about the CallbackURL. You need to put some coding for handling the WebView. SO that after redirecting from the twitter.!! Check the code that i given below.!!
I set up Twitter user authentication as in the tutorial above such that the Activity doing the Twitter authentication has its content view changed to a WebView, the Activity is declared in the manifest file containing an intent-filter to catch the Twitter callback and, on callback, the response is processed and the Activity's content view is changed back to whatever it was.
I got it working but in doing so I found (what I think is) an easier way and such that the WebView doesn't ever kick off the phone's web browser app (thereby leaving your app, which you don't really want), as follows:
(1) Remove the Activity singleInstance and intent-filter declarations you added to the manifest file (in following the tutorial above). Don't need that anymore!
(2) Add a WebView to your Activity layout file and set its initial visibility to "gone" and its position, height, width etc however you want it. I set its properties so that it covers the whole screen when visible, as follows:
<WebView
android:id="#+id/myWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
(3) Get a handle to your WebView in your Activity and set its WebViewClient to pick up the Twitter callback (and not to kick off the web browser app at any time), as follows...
myWebView = (WebView)findViewById(R.id.myWebView);
myWebView.setWebViewClient(new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView webView, String url)
{
if (url != null
&& url.startsWith("myapptwittercallback:///myapp"))
handleTwitterCallback(url);
else
webView.loadUrl(url);
return true;
}
});
... Here you might also want to enable other settings of your WebView like saving form data and javascript execution (e.g. myWebView.getSettings().setJavaScriptEnabled(true);)
(4) Make your WebView visible and focused at the point you need to do Twitter authentication, as follows:
try
{
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(
myTwitterConsumerKey,
myTwitterConsumerSecret);
twitterRequestToken = twitter.getOAuthRequestToken(
"myapptwittercallback:///myapp");
myWebView.loadUrl(
twitterRequestToken.getAuthenticationURL());
myWebView.setVisibility(View.VISIBLE);
myWebView.requestFocus(View.FOCUS_DOWN);
}
catch (TwitterException ex)
{
Toast.makeText(
this,
"Login failed. Please try again.",
Toast.LENGTH_SHORT).show();
}
... Remember to clear your WebView's history (i.e. myWebView.clearHistory() and set its visibility to "gone" in your handleTwitterCallback(String) method.
(5) Lastly, override your Activity's onBackPressed() method so that your WebView handles presses of the back button if its visible, as follows...
#Override
public void onBackPressed()
{
if (myWebView.getVisibility() == View.VISIBLE)
{
if (myWebView.canGoBack())
{
myWebView.goBack();
return;
}
else
{
myWebView.setVisibility(View.GONE);
return;
}
}
super.onBackPressed();
}
That's it! You should now have Twitter integration in your app and the user should never leave your app in doing Twitter authentication.
I'm using an asyncTask in my app, but it's not calling the onPostExecute method. I read it dozen of times and couldn't find an error.
It flows like this:
MainActivity
--> user clicks on button
-->calls a class
-->call another class with a method that show some messages and then executes the AsyncTask.
This is the full class and the AsyncTask:
package com.vdlow.socialnotification.twitter;
import java.util.ArrayList;
import com.vdlow.socialnotification.R;
import oauth.signpost.OAuth;
import twitter4j.IDs;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
public class TwitterUtils {
static long userID;
static Context c;
static Boolean retornoSend;
public static boolean isAuthenticated(SharedPreferences prefs) {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
try {
twitter.getAccountSettings();
return true;
} catch (TwitterException e) {
return false;
}
}
public static void sendTweet(SharedPreferences prefs,String msg, Context cs) throws Exception {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
String values[] = {token, secret, msg};
TwitterUtils tu = new TwitterUtils();
TweetSender ts = tu.new TweetSender();
ts.execute(values);
Log.i("retornoSend", retornoSend.toString());
if(retornoSend){
Toast.makeText(cs, cs.getString(R.string.tweet_sent), Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(cs, cs.getString(R.string.fail_sending), Toast.LENGTH_LONG).show();
}
}
public static ArrayList<String> getUserId(final SharedPreferences prefs) throws Exception{
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
try {
userID = twitter.getId();
} catch (IllegalStateException e) {
Log.e("Error! Method: getUserId() Class: TwitterUtils", e.toString());
}
Log.i("USERID", String.valueOf(userID));
ArrayList<String> following = new ArrayList<String>();
long lCursor = -1;
try{
userID = twitter.getId();
IDs friendsIDs = twitter.getFriendsIDs(userID, lCursor);
do
{
for (long i : friendsIDs.getIDs())
{
following.add("#"+twitter.showUser(i).getScreenName());
}
}while(friendsIDs.hasNext());
}
catch(Exception e){
Log.e("Exception! Class TwitterUtils Method: getFriendsName()", e.toString()+"\n User ID "+String.valueOf(userID));
}
return following;
}
private class TweetSender extends AsyncTask<String, Void, Boolean>{
#Override
protected Boolean doInBackground(String... msg) {
Looper.prepare();
String token = msg[0];
String secret = msg[1];
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
try {
twitter.updateStatus(msg[2]);
} catch (TwitterException e) {
Log.e("Error sending tweet Class TwitterUtils Method sendTweet() AsyncTask TweetSender", e.toString());
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result){
Log.i("Post execute", "Runned");
retornoSend = result;
}
}
Any ideas why it's not working?
Your doInBackground is either never completing, or you cancel the request at some point:
from the developer docs (see bold text below): http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
Calling this method will result in onCancelled(Object) being invoked
on the UI thread after doInBackground(Object[]) returns. Calling
this method guarantees that onPostExecute(Object) is never invoked.
After invoking this method, you should check the value returned by
isCancelled() periodically from doInBackground(Object[]) to finish the
task as early as possible.
I am trying to make a class to handle all my interactions with Facebook. I am passing the the Login activity I created to the FacebookConnector object (the object in question) to store the credentials and etc. Please view the video to see what I am dealing with http://www.youtube.com/watch?v=OkHEy9Mh1hc. Below is the FacebookConnector class with the App Id edited out
package it.stick;
import java.io.IOException;
import java.net.MalformedURLException;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class FacebookConnector {
private static final String APP_ID ="************";
private static final String[] PERMISSIONS = new String[] {"user_likes","read_stream", "user_photos", "email","photo_upload", "offline_access", "publish_actions"};
private static final String TOKEN = "access_token";
private static final String EXPIRES = "expires_in";
private static final String KEY = "facebook-credentials";
private Facebook facebook;
private Activity activity;
/** Saves applications credentials */
public boolean saveCredentials(Facebook facebook){
Editor editor = activity.getSharedPreferences(KEY, Context.MODE_PRIVATE).edit();
editor.putString(TOKEN, facebook.getAccessToken());
editor.putLong(EXPIRES, facebook.getAccessExpires());
return editor.commit();
}
public boolean restoreCredentials(Facebook facebook){
SharedPreferences sharedPreferences = activity.getSharedPreferences(KEY, Context.MODE_PRIVATE);
facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
return facebook.isSessionValid();
}
public FacebookConnector(Activity activity){
facebook = new Facebook(APP_ID);
this.activity = activity;
}
// Creates new Facebook session and stores credentials
public void login(){
// 1.Restores previous credentials
//2.Creates and saves new session if previous session is not valid
restoreCredentials(facebook);
if(!facebook.isSessionValid()){
facebook.authorize(activity, PERMISSIONS, new LoginDialogListener());
}
}
public boolean isSessionValid() {
return facebook.isSessionValid();
}
public void logout(){
try {
facebook.logout(activity.getApplicationContext());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void postToWall(String message){
Bundle parameters = new Bundle();
parameters.putString("message", message);
parameters.putString("description", "topic share");
try{
facebook.request("me");
String response = facebook.request("me/feed", parameters, "POST");
Log.d("Tests", "got response: " + response);
if(response == null || response.equals("") || response.equals("false")){
showToast("Blank response from facebook.");
}
else{
showToast("Message posted to your facebook wall.");
}
}
catch(Exception e){
showToast("Failed to post to wall. We fucked up :(");
e.printStackTrace();
}
}
class LoginDialogListener implements DialogListener{
#Override
public void onComplete(Bundle values) {
saveCredentials(facebook);
postToWall("logged on to Stick.it");
}
#Override
public void onFacebookError(FacebookError e) {
showToast("Authentification with Facebook failed!");
}
#Override
public void onError(DialogError e) {
showToast("Authentification with Facebook failed!");
}
#Override
public void onCancel() {
showToast("Authentification with Facebook failed!");
}
}
public void showToast(String message){
Toast.makeText(activity.getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
Here is the log cat:
02-01 22:39:39.459: W/KeyCharacterMap(637): No keyboard for id 0
02-01 22:39:39.470: W/KeyCharacterMap(637): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
02-01 22:39:46.299: D/dalvikvm(637): GC_EXPLICIT freed 91K, 50% free 2744K/5447K, external 3745K/3903K, paused 1017ms
02-01 22:39:46.999: D/webviewglue(637): nativeDestroy view: 0x303080
02-01 22:39:48.239: D/dalvikvm(637): GC_EXTERNAL_ALLOC freed 54K, 51% free 2706K/5447K, external 3331K/3903K, paused 735ms
02-01 22:39:52.139: D/Facebook-WebView(637): Webview loading URL: https://m.facebook.com/dialog/oauth?display=touch&client_id=228461823905169&scope=user_likes%2Cread_stream%2Cuser_photos%2Cemail%2Cphoto_upload%2Coffline_access%2Cpublish_actions&type=user_agent&redirect_uri=fbconnect%3A%2F%2Fsuccess
02-01 22:40:12.209: D/Facebook-authorize(637): Login failed: com.facebook.android.DialogError: The connection to the server was unsuccessful.
02-01 22:40:12.279: D/Facebook-WebView(637): Webview loading URL: https://m.facebook.com/dialog/oauth?display=touch&client_id=228461823905169&scope=user_likes%2Cread_stream%2Cuser_photos%2Cemail%2Cphoto_upload%2Coffline_access%2Cpublish_actions&type=user_agent&redirect_uri=fbconnect%3A%2F%2Fsuccess
02-01 22:46:14.119: W/KeyCharacterMap(637): No keyboard for id 0
02-01 22:46:14.119: W/KeyCharacterMap(637): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
I have cleared the browser cache and the app data. I have checked the key hash and I have copied and pasted the App ID multiple times into the app.
Be sure, you have added your application's signature to application setting, as:
http://developers.facebook.com/docs/mobile/android/build/#sig
Without the onActivityResult() method in the Activity you are trying to login with, the login will Facebook, because the android sdk then invokes the authorizeCallback(requestCode, resultCode, data) method.
I'm writing an Android twitter app using twitter4j 2.2.4, and I'm having trouble getting past OAuth.
here's my code :
package info.mahmoudhossam.twitter;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.auth.AccessToken;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class TwitterActivity extends Activity {
private static int OAUTH_REQUEST = 1;
private static String consumerKey = "##########";
private static String consumerSecret = "################";
private Twitter twitter;
private AccessToken accessToken;
private TwitterBackend backend;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button loginButton = (Button) findViewById(R.id.button1);
registerForContextMenu(loginButton);
backend = new TwitterBackend();
twitter = backend.getTwitterInstance(consumerKey, consumerSecret);
}
public void onLogin(View view) {
Intent intent = new Intent("mahmoud.browser");
try {
Log.i("URL", backend.getRequestToken().getAuthenticationURL());
intent.putExtra("url", backend.getRequestToken().getAuthenticationURL());
} catch (TwitterException e) {
Log.e("Twitter", e.getMessage());
return;
}
startActivityForResult(intent, OAUTH_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OAUTH_REQUEST && resultCode == RESULT_OK) {
Uri url = Uri.parse(data.getExtras().getString("url"));
String verifier = url.getQueryParameter("oauth_verifier");
Log.i("Verifier", verifier);
try {
accessToken = backend.getAccessToken(verifier);
} catch (TwitterException e) {
Log.e("Twitter", "Exception occurred, quitting");
return;
}
twitter.setOAuthAccessToken(accessToken);
try {
if(twitter.verifyCredentials() != null){
Toast.makeText(getApplicationContext(), "Logged in!", Toast.LENGTH_SHORT);
}
} catch (TwitterException e) {
Log.e("Twitter", e.getMessage());
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this,
"Cannot connect to twitter, app not authorized",
Toast.LENGTH_SHORT).show();
}
}
}
And the TwitterBackend class :
package info.mahmoudhossam.twitter;
import java.util.List;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
public class TwitterBackend {
private static Twitter twitter;
public Twitter getTwitterInstance(String consumerKey,
String consumerSecret){
if(twitter == null){
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(consumerKey, consumerSecret);
}
return twitter;
}
public RequestToken getRequestToken()
throws TwitterException {
return twitter.getOAuthRequestToken();
}
public AccessToken getAccessToken(String verifier)
throws TwitterException{
return twitter.getOAuthAccessToken(getRequestToken(), verifier);
}
public List<Status> getTimeline() throws TwitterException{
return twitter.getHomeTimeline();
}
public void updateStatus(String status) throws TwitterException{
twitter.updateStatus(status);
}
}
I'm getting a 401 error from twitter saying that authentication credentials are missing or incorrect, and I'm sure I've entered the correct consumer key/secret.
Is there something wrong with the code itself?
I realize this is an old question, but I used your TwitterBackend class and I had the same issue. I resolved this by making one minor change (can't say why it works, yours should have been fine).
Change this
public AccessToken getAccessToken(String verifier) throws TwitterException{
return twitter.getOAuthAccessToken(getRequestToken(), verifier);
}
To this
public AccessToken getAccessToken(String verifier) throws TwitterException{
return twitter.getOAuthAccessToken(verifier);
}
I'm unable to explain why, but I just started going down each method listed at twitter4j for getOAuthAccessToken() and got one that works.
I hope this helps someone, but thank you for the nice base class to work with.
I don't think this is a problem with your code. This is a problem with the whole Twitter authorisation mechanism, it seems that if your are logged in from the Twitter App on your phone, into Twitter then the OAuth authorization gives you this error. I guess it takes the credentials used by the Twitter App and tries to acces the App using them, and that's why you get the "incorrect credentials" message.
You can try to logout from the Twitter App of your phone, and then try again with OAuth. It worked for me, but I still couldn't find how to solve the problem when you are logged into the Twitter App and you also try to log in from your app using OAuth.
In case someone gets stuck with this, I found a solution to my problem.
It was the emulator's clock being out of sync, starting emulators from snapshots used to mess up the clock.
So if you have this problem, check the emulator's time and date, and if it's out of sync, correct it.