Twitter OAuth issue: error 401 - android

i am trying to get twitter work.
Error which i receive is:
Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match
I have already checked a lot of same issues here, on stackoverflow and here what i already tried:
1) checked consumer key (it is the same with that on dev.twitter.com)
2) added Callback URL for my app on dev.twitter.com
3) updated library to twitter-4j-core-3.0.5.jar
4) checked if time of my tablet is correct (set Eastern European Time)
Also i must say that some month ago Twitter in application worked properly. Then somehow it broke down.
Here is my code:
class GetOAuthVerifierTask extends AsyncTask<Void, Void, String> {
private Context context;
public GetOAuthVerifierTask(Context context) {
this.context = context;
dialog = ProgressDialog.show(TwitterActivity.this, getString(CANNOT_GET_REQUEST_TOKEN), null);
}
#Override
protected String doInBackground(Void... params) {
TwitterUtils twitterUtils = TwitterUtils.getInstance();
OAuthConsumer consumer = twitterUtils.createConsumer();
OAuthProvider provider = twitterUtils.createProvider();
try {
final String url = provider.retrieveRequestToken(consumer,
twitterUtils.getCallbackURL(context));
twitterUtils.setConsumerToken(context, consumer.getToken());
twitterUtils.setConsumerSekretToken(context, consumer.getTokenSecret());
return url;
} catch (Exception e) {
Logger.debug("Can not retrieve request token");
Logger.error(e.getMessage(), e);
return null;
}
}
#Override
protected void onPostExecute(String url) {
dialog.dismiss();
if (url != null){
// HERE IT WORKS CORRECT
web.loadUrl(url);
}
else{
Toast.makeText(TwitterActivity.this, getString(DOWNLOAD_WAIT_MESSAGE),
Toast.LENGTH_LONG).show();
}
}
}
class GetAccessTokenTask extends AsyncTask<Uri, Void, Boolean> {
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(TwitterActivity.this, getString(CANNOT_GET_REQUEST_TOKEN), null);
}
#Override
protected Boolean doInBackground(Uri... params) {
TwitterUtils twitterUtils = TwitterUtils.getInstance();
String oauthVerifier = params[0].getQueryParameter(OAuth.OAUTH_VERIFIER);
OAuthConsumer consumer = twitterUtils.createConsumer();
consumer.setTokenWithSecret(twitterUtils.getConsumerToken(TwitterActivity.this),
twitterUtils.getConsumerSekretToken(TwitterActivity.this));
OAuthProvider provider = twitterUtils.createProvider();
try {
provider.retrieveAccessToken(consumer, oauthVerifier);
twitterUtils.setAccessToken(TwitterActivity.this, consumer.getToken());
twitterUtils.setAccessTokenSecret(TwitterActivity.this, consumer.getTokenSecret());
} catch (Exception e) {
Logger.debug("Can not retrieve access token");
Logger.error(e.getMessage(), e);
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result) {
dialog.dismiss();
if (result) {
TwitterActivity.this.sendMessage();
TwitterActivity.this.finish();
} else {
// HERE I GET 401
Toast.makeText(TwitterActivity.this, getString(DOWNLOAD_WAIT_MESSAGE),
Toast.LENGTH_LONG).show();
}
}
}

Just found the solution:
i added line
provider.setOAuth10a(true); (for my OAuthProvider)
The explanation was found in source code:
// 1.0a expects the callback to be sent while getting the request token.
// 1.0 service providers would simply ignore this parameter.

In the last month, has been a change to the Twitter API. You can now only call it using HTTPS.
You should ensure that the URL you / your library is using starts with
https://api.twitter.com/1.1/
(Notice the extra s after the http.)
You may need to check with the maintainer of twitter4j.

Related

Best approach to make a login screen

I am writing here because this is my last solution of understanding this type of programming.The problem is that I got stuck on what to use to handle the connection to a server and log-in. Should I use async task, handler or thread ? I didn't find a concrete answer stating which one to use, only found that async task is used to download images or other download stuffs.
Until now I have used a thread to connect to the server. The problem I encountered was when I catch the exception ( Putting invalid username/password ) and try to log-in again. ( I needed to "close" the last thread and start one again )
After this I started to use async task but I don't really understand how it should work and I am stuck on a toast of invalid username/password.
private class connectStorage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
api = DefaultClientFactory.create(host, getUser, getPassword);
if (api.getAuthToken().trim().length() > 3) {
//TO DO LAYOUT CHANGE;
}
} catch (StorageApiException e) {
e.printStackTrace();
Log.i("TEST", "" + e.getMessage());
}
return null;
}
Also, I am 100% sure that calling inflate in the doInBackground method won't work too ( there I wanted to change the activity ).
I am starting the async task on a button press.
When you are using asynctask
You have doInBackground and onPostExecute
So basically get a json or string or boolean as a result from doinbackground
and in onpostexecute check if the login in succesful or not if its succesful save the data from server and start an intent to go to another activity or toast the user that that user login details are wrong and try again.
So your asynctask can be an inner class of your activity class which is login and onClickSubmit button call the asynctask class and on post execute parse the json and according to the result decide what to do
Example:
public class SignInAsycTask extends AsyncTask<RequestParams, Void, String> {
#Override
protected String doInBackground(RequestParams... params) {
return new HttpManager().sendUserData(params[0]);
}
#Override
protected void onPostExecute(String result) {
String[] details = parseJsonObject(result);
if (details != null) {
user.setUser_id(Integer.valueOf(details[0]));
user.setName(details[1]);
if (details.length > 2) {
user.setProfilePic(details[2]);
}
setSharedPreferences();
startActivity(new Intent(Signin.this, MainActivity.class));
finish();
} else {
Toast.makeText(Signin.this, "please try again",
Toast.LENGTH_LONG).show();
}
}
}
public String[] parseJsonObject(String result) {
JSONObject obj = null;
try {
obj = new JSONObject(result);
if (obj.has("success")) {
if (obj.getInt("success") == 1) {
if (obj.has("user_pic")) {
return new String[] {
String.valueOf(obj.getInt("user_id")),
obj.getString("user_name"),
obj.getString("user_pic") };
} else {
return new String[] {
String.valueOf(obj.getInt("user_id")),
obj.getString("user_name"), };
}
} else {
return null;
}
} else {
return null;
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
here my RequestParams are just a object where I stored all the details like url parameters to send etc and the output of the doinbackground is a String and I am parsing it in my postexecute method

Android - Scope for access gmail with server

I want to connect with oAuth2 the IMAP of Google. But the App seems to be not really authorize.
I try using the scope oauth2:https://mail.google.com/ but the token returned is unusable by the server.
Then I want to set more datas on the scope Android say : "INVALID_SCOPE".
The scope is:
String scope = String.format("oauth2:server:%s:client_id:%s:api_scope:%s",
API_KEY, CLIENT_ID, "https://mail.google.com/");
With:
API KEY: the API KEY of the Server Application (not the web Application Client Api Key)
CLIENT_ID: The Client ID of the Service Account (not the web application)
The full Code is :
public static String getToken(final Context context, final Activity activity, final String accountName)
{
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>()
{
#Override
protected String doInBackground(Void... params)
{
String token = null;
try
{
String scope = String.format("oauth2:server:%s:client_id:%s:api_scope:%s", API_KEY, CLIENT_ID, "https://mail.google.com/");
Log.i("GooglePlusSignupTool", "scope : "+scope);
token = GoogleAuthUtil.getToken(context, accountName, scope);
}
catch (IOException transientEx)
{
// Network or server error, try later
Log.e("GoogleSignupTool", transientEx.toString());
}
catch (UserRecoverableAuthException e)
{
// Recover (with e.getIntent())
Log.e("GoogleSignupTool", e.toString());
Intent recover = e.getIntent();
context.startActivity(recover);//ForResult(recover, REQUEST_CODE_TOKEN_AUTH);
}
catch (GoogleAuthException authEx)
{
// The call is not ever expected to succeed
// assuming you have already verified that
// Google Play services is installed.
Log.e("GoogleSignupTool", authEx.toString());
}
return token;
}
#Override
protected void onPostExecute(String token)
{
Log.i("GoogleSignupTool", "Access token retrieved:" + token);
}
};
task.execute();
Log.i("GoogleSignupTool", "END");
return "";
}

Android Login with Azure Mobile Services

I am having trouble creating a login function with Android using Azure mobile services. When i attempt to login, using a user that I have previously created, It tells me that the password is incorrect, but when I login again using the same credentials straight afterwards it gives me access to the next activity.
This is the code in which I use to connect to my Azure mobile service
// Connect client to azure
try {
mClient = new MobileServiceClient(
"URL",
"App Key",
this
);
mUserTable = mClient.getTable(User.class);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This is the code in which executes when i attempt the login
public class UserLoginTask extends AsyncTask<Void, Void, Boolean>
{
#Override
protected Boolean doInBackground(Void... params)
{
mUserTable.where().field("email").eq(user.getEmail()).execute(new TableQueryCallback<User>()
{
public void onCompleted(List<User> result, int count, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
for (User u : result) {
if(user.getPassword().equals(u.getPassword()))
{
grantAccess = true;
}
else
{
grantAccess = false;
}
}
} else {
grantAccess= false;
}
}
});
return grantAccess;
}
#Override
protected void onPostExecute(final Boolean success)
{
mAuthTask = null;
showProgress(false);
if (success == true)
{
// Finish this activity
finish();
// Start the main activity
Intent i = new Intent(getApplicationContext(),
MainActivity.class);
startActivity(i);
}
else
{
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled()
{
mAuthTask = null;
showProgress(false);
}
}
}
The problem is with how you're calling your Mobile Service to read the user table. You don't need to wrap this in an AsyncTask. The Mobile Services SDK will do that for you by default. The onCompleted method you implement inside of your TableQueryCallback will be called when the results are returned from the server. What this means is that the callback will be called (most likely) after the onPostExecute method is called. Let me try to diagram the flow:
--Query users table
----Query task kicked off by SDK with callback
--Proceed with UserLoginTask
--Call onPostExecute of UserLoginTask
Then at some separate point when the server responds, your callback is called. To fix this, I would recommend getting rid of your async task. Put everything you have in onPostExecute into your callback method as, again, this will be called once you get a response from your Mobile Service.

OAuth token with Google Play Game Services

Is there a way to get the token that was used to log in the user with Google Play Game Services?
I'm looking for something like:
#Override
public void onSignInSucceeded() {
String email = getGamesClient().getCurrentAccountName();
String token = getGamesClient().getToken();
}
I need this to authenticate the user when they are contacting my own server.
This is how I managed to get the token:
#Override
public void onSignInSucceeded() {
String email = getGamesClient().getCurrentAccountName();
String scopes = getScopes();
new registerBackground(getApplicationContext()).execute(email, scopes);
}
private class registerBackground extends AsyncTask<String, Void, Void> {
Context context;
registerBackground (Context context) {
this.context = context;
}
#Override
protected Void doInBackground(String... params) {
try {
String oAuthToken = GoogleAuthUtil.getToken(context, params[0], params[1]);
...
catch (Exception e) {
e.printStackTrace();
}
}
...
}

Importing gmail contacts using GoogleAuthUtil

I'm trying to add import contacts from gmail account function in my android app. So the first problem is to get access token from gmail. I've found that there is GoogleAuthUtil class which can help me with it.
Here is my code:
private void importContactsFromGmail() {
showProgressDialog();
GetTokenTask getTokenTask = new GetTokenTask();
getTokenTask.execute();
String token = "";
try {
token = getTokenTask.get();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(token);
hideProgressDialog();
}
private class GetTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String token = "";
try {
token = GoogleAuthUtil.getToken(activity, <My_gmail_account>, "https://www.google.com/m8/feeds/");
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
}
Now after calling GoogleAuthUtil.getToken my app completely freezes(no errors in Logcat). I completely stuck and I need your help.
What is wrong with my code? Maybe I should import contacts in some other way?
Not sure if this is related but calling the .get() method on the main thread is not correct because is blocking method.
What if you use the AsyncTask in this way?
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetTokenTask().execute();
}
static class GetTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... unused) {
String token = "";
try {
token = GoogleAuthUtil.getToken(activity, <My_gmail_account>, "https://www.google.com/m8/feeds/");
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
#Override
protected void onPostExecute(String token) {
Toast.makeText(MainActivity.this, token, Toast.LENGTH_SHORT).show();
}
}
}
(I wrote without compiling it, maybe it needs to be adjusted)
On Android devices, Gmail contacts are synced locally onto the device and are available via a public Contacts Provider, therefore there's no reason you'd need to use the Google API to pull what is already available. There is a whole training series dedicated specifically to retrieving a list of contacts.
Note that the Contacts training series does assume you have knowledge of Content Providers already, so it may be helpful to read up on the basics of Content Providers as well.

Categories

Resources