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.
Related
I am a newbie in Android. I have a rest API I developed in Django which I want my Android app to interact with.
I am using Retrofit In Android Studio
To save a new user through the API I pass four fields (staff_id,email,password,password2) to my API.
It all works fine in Postman and returns the appropriate responses for both a success (HTTP 200) and bad request (HTTP 400)
This Is The Image of a 201 Response on The Android App Which is correct
However the HTTP 400 response in Android does not return a JSON. In Postman I get this for the HTTP 400
{
"error_message": "That email is already in use.",
"response": "Error"
}
But In Android I don’t get the Same JSON Response from the response.errorBody(). Instead I Get A HTML Response LIke This:
<DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0 transitional//EN>
<html>
<head>
<title>400</title>
<meta http-eqiv="Cache-Control"
content ="no-cache"/>
</head>
<body>
<p>
Bad Request
</p>
</body>
</html>
Here’s My Android Studio Code
Api.java:`
package nkemokongwu.com.ng.leave.activities.api;
import nkemokongwu.com.ng.leave.activities.models.NewStaff;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
public interface Api {
#FormUrlEncoded
#POST("authenticate/api/api_signup/")
Call<ResponseBody> signup(
#Field("staff_id") int staff_id,
#Field("email") String email,
#Field("password") String password,
#Field("password2") String password2
);
#FormUrlEncoded
#POST("authenticate/api/api_login")
Call<ResponseBody> userLogin(
#Field("email") String email,
#Field("password") String password
);
}
RetrofitClient.Java
package nkemokongwu.com.ng.leave.activities.api;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static final String BASE_URL = "http://nsitf.pythonanywhere.com/";
private static RetrofitClient mInstance;
private Retrofit retrofit;
private RetrofitClient() {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static synchronized RetrofitClient getInstance() {
if (mInstance == null) {
mInstance = new RetrofitClient();
}
return mInstance;
}
public Api getApi() {
return retrofit.create(Api.class);
}
}
SignUpActivity.java
package nkemokongwu.com.ng.leave.activities.authentication;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.util.Objects;
import nkemokongwu.com.ng.leave.R;
import nkemokongwu.com.ng.leave.activities.api.RetrofitClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class SignUpActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editTextstaff_id,editTextemail,editTextpassword,editTextpassword2;
private static final String TAG = "MyActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
editTextstaff_id = findViewById(R.id.editTextstaff_id);
editTextemail = findViewById(R.id.editTextemail);
editTextpassword = findViewById(R.id.editTextpassword);
editTextpassword2 = findViewById(R.id.editTextpassword2);
findViewById(R.id.text_already_have_account).setOnClickListener(this);
findViewById(R.id.buttonSignUp).setOnClickListener(this);
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void userSignUp() {
String temp = editTextstaff_id.getText().toString().trim();
int staff_id = 0;
if (!"".equals(temp)) {
staff_id = Integer.parseInt(temp);
} else {
editTextstaff_id.setError("Staff ID Is Required");
editTextstaff_id.requestFocus();
return;
}
String email = editTextemail.getText().toString().trim();
String password = editTextpassword.getText().toString().trim();
String password2 = editTextpassword2.getText().toString().trim();
if (email.isEmpty()) {
editTextemail.setError("Email is required");
editTextemail.requestFocus();
return;
}
if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
editTextemail.setError("Enter a valid email");
editTextemail.requestFocus();
return;
}
if (password.isEmpty()) {
editTextpassword.setError("Password required");
editTextpassword.requestFocus();
return;
}
if (password2.isEmpty()) {
editTextpassword2.setError("Confirmation Password Required");
editTextpassword2.requestFocus();
return;
}
if (!Objects.equals(password, password2)) {
editTextpassword.setError("Passwords Do Not Match");
editTextpassword.requestFocus();
return;
}
Call <ResponseBody> call =RetrofitClient
.getInstance()
.getApi()
.signup(staff_id,email,password,password2);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.code() == 201){
try {
Toast.makeText(SignUpActivity.this,response.body().string(),Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
} else if (response.code() == 400){
try {
Toast.makeText(SignUpActivity.this,response.errorBody().string(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(SignUpActivity.this,t.toString(),Toast.LENGTH_LONG).show();
}
});
//
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonSignUp:
userSignUp();
break;
case R.id.text_already_have_account:
startActivity(new Intent(this, LoginActivity.class));
break;
}
}
}
`
I have tried the following;
1. Annotated the Signup call with #Headers to specify Accept and Content-Type
2. Modified my Django API code to include content type as well.
None of which have helped. I have also scoured through Stack Overflow to find a solution and everything I’ve tried still did not work.
I would appreciate any help to point me in the right direction. Is it my android code or do I have to modify the Django Rest API? The latter is unlikely given that I get the correct response on Postman.
Thank you for any help you can offer.
I figured it out! For anyone who is facing this, the problem is with the API itself. In my Django Rest API Serializer, I had some of my responses like:
return Response(status=status.HTTP_400_BAD_REQUEST)
return Response(status=status.HTTP_401_UNAUTHORIZED)
Now this was the issue for Retrofit cos it changes the response from a successful response (code 200) to an error response which in turn returns an error when attempting to view the response.body() in retrofit. The response is only available in response.errorbody() which returns some strange okhttp stuff that dosen’t help at all!!
Instead what I should have done in my API was:
First define an empty list:
context={}
Then add the error values with
context['status'] = 'Error'
context['message'] = 'Invalid credentials'
context['code']=status.HTTP_401_UNAUTHORIZED
return Response(data=context)
This returns
Postman Image Of Response
Which is perfect and can be easily modelled into a Java Class or Pojo as you wish. As the API’s Actual response code is 200, the response.body() is available and won’t return an error.
That was the issue!
i am currently developping an application for my third year project, it's an android app (i used android studio) that will access a database that i created on my wamp server, the connection works perfectly from the application when i debug it on my android phone( i used in my code the "HttpURLConnection" with the url being my pc ip adress that i got from (cmd/ipconfig) ) .
The problem is that once i disconnect my phone from my pc and try to run the application from the phone, the connection with the database won't work, and also if i connect my pc to another modem, my pc ip changes, which is pretty much normal, but i don't think supposed to change the ip everytime the modem i connect to change ( although i'm not really sure, server connexions are clearly not something i'm an expert at ) , so i tried to use the ip of my pc on the internet that i got from "ipaddress.com" but it won't work, not even if i debug the application directly from android studio,
i don't have much time left to present the application , so i need a quick answer, thank you in advance
P.S : i guess i gotta mention that i need to acces the database to read AND write on it from the phone since it's an app that permits login/registration and will get the data that the user will enter and store it in the database .
I don't know wheter understanded, when you disconnect your phone from your pc, the app dead? or simplely it don't connect with db. Regard router, you need an account in "no-ip" and configure forguard's router on port 80 to redirect your computer's static IP. i need more details and information to help you. Regards
Try to connect the Phone and Mobile in same network.
your connection Url would be Like this 192.10.20.2 which is your ip or computer. as your get it form cmd using ipconfig command.
but whenever your networks changes your have to decompile to change the ip. or provide ip via textview.
take a Editview to take ip. and the concat it to your url. this will work. as it worked for me.
i'm working on an external server
The php code (for the connection to the db)
<?php
$db_name="pfe";
$mysql_username="root";
$mysql_password="";
$server_name="localhost";
$conn = mysqli_connect($server_name,$mysql_username,$mysql_password,$db_name);
?>
then i got another php file which handles the login part
<?php
require "connexion.php";
$user_email =$_POST["user-email"];
$user_pass =$_POST["password"];
$mysql_qry = "select id from donateur where email like '$user_email' and
password like '$user_pass'";
$result = mysqli_query($conn , $mysql_qry);
if(($row=mysqli_fetch_assoc($result))!=null){
$a = array('myarray' => array("donateur", $row["id"]));
echo json_encode($a);}
else {
$mysql_qry2 = "select id, username from association where email like
'$user_email' and password like '$user_pass'";
$result2 = mysqli_query($conn , $mysql_qry2);
if(($row=mysqli_fetch_assoc($result2))!=null) { $a = array('myarray' =>
array("association", $row["id"]));
echo json_encode($a);
}
else { echo "rien";}}
$conn->close();
the java code :
package applis.pfe;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static android.Manifest.permission.READ_CONTACTS;
public class LoginActivity extends AppCompatActivity implements
LoaderCallbacks<Cursor> {
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
DonateurDAO donateurdao= new DonateurDAO(this);
AssociationDAO associationdao=new AssociationDAO(this);
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
String ip="http://105.101.179.155/";
private UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
public static String qui;
public static int id;
public static String username;
SessionManager session;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
///////////////////// POUR AFFICHER LE MESSAGE DIINSCRIPTION REUSSIE /////////////////////////////////////
if(getIntent().getStringExtra("inscription")!=null &&
getIntent().getStringExtra("inscription").equals("oui"))
{ AlertDialog a= new AlertDialog.Builder(LoginActivity.this).create();
a.setTitle("Inscription réussie !");
a.setMessage("Votre inscription a été validé, veuillez vous connecter
pour pouvoir continuer");
a.show();}
session = new SessionManager(this);
// Set up the login form.
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
// populateAutoComplete();
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new
TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent
keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
ImageButton btn;
btn =(ImageButton)findViewById(R.id.InscriptionDonateurButton);
btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {Intent in= new
Intent(LoginActivity.this,InscriptionDonateurActivity.class);
startActivity(in);
}
});
ImageButton btn1;
btn1 =(ImageButton)findViewById(R.id.InscriptionAssociationButton);
btn1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {Intent in= new
Intent(LoginActivity.this,InscriptionAssociationActivity.class);
startActivity(in);
}
});
}
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!isEmailValid(email)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
}
private boolean isEmailValid(String email) {
//TODO: Replace this with your own logic
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
private boolean isPasswordValid(String password) {
//TODO: Replace this with your own logic
return password.length() > 4;
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(this,
// Retrieve data rows for the device user's 'profile' contact.
Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,
// Select only email addresses.
ContactsContract.Contacts.Data.MIMETYPE +
" = ?", new String[]{ContactsContract.CommonDataKinds.Email
.CONTENT_ITEM_TYPE},
// Show primary email addresses first. Note that there won't be
// a primary email address if the user hasn't specified one.
ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> emails = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
emails.add(cursor.getString(ProfileQuery.ADDRESS));
cursor.moveToNext();
}
addEmailsToAutoComplete(emails);
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
}
private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this,
android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
mEmailView.setAdapter(adapter);
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.Email.ADDRESS,
ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
};
int ADDRESS = 0;
int IS_PRIMARY = 1;
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, String> {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#Override
protected String doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
String login_url= ip.concat("login.php");
try {
URL url= new URL(login_url);
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
OutputStream outputStream= httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter= new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
String Post_data= URLEncoder.encode("user-email","UTF-8")+"="+URLEncoder.encode(mEmail,"UTF-8")+"&"
+URLEncoder.encode("password","UTF-8")+"="+URLEncoder.encode(mPassword,"UTF-8");
bufferedWriter.write(Post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream=httpURLConnection.getInputStream();
qui=null;
id=0;
BufferedReader bufferedReader= new BufferedReader(new InputStreamReader(inputStream,"iso-8859-1"));
String resultat="";
String ligne="";
while((ligne=bufferedReader.readLine())!=null)
resultat += ligne;
if (resultat.equals("rien")) return resultat; else {
JSONObject jsonObject = new JSONObject(resultat);
JSONArray json_data = jsonObject.getJSONArray("myarray");
qui=json_data.getString(0);
id=json_data.getInt(1);
username= json_data.getString(2);}
/* for(int i=0;i<json_data.length();i++)
{
k++;
qui= json_data.getString(1);
id= json_data.getInt(2);
//r.add(json_data.getString("categorie"));
}*/
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return resultat;
} catch (MalformedURLException e) {
e.printStackTrace();return e.toString();
} catch (IOException e) {
e.printStackTrace();return e.toString();
} catch (JSONException e) {
e.printStackTrace(); return e.toString();
}
}
/* for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}*/
// TODO: register the new account here.
#Override
protected void onPostExecute(String resultat) {
mAuthTask = null;
showProgress(false);
/////////////////////////////////////////////////////////////////////////////////
Intent i;
AlertDialog a;
if (resultat.equals("rien")){i= new Intent(LoginActivity.this,LoginActivity.class);
a= new AlertDialog.Builder(LoginActivity.this).create();
a.setTitle("Erreur");
a.setMessage(" Email et/ou mot de passe erroné(s)");
a.show();} else {
try {
session.createLoginSession(mEmail,username,qui,id);
session.checkLogin();
if (qui.equals("donateur")) {
i = new Intent(LoginActivity.this, Suite_Inscription_Donateur.class);
i.putExtra("id", id);
startActivity(i);
} else if (qui.equals("association")) {
session.createLoginSession(mEmail,username,qui,id);
i = new Intent(LoginActivity.this, Suite_Inscription_Association.class);
i.putExtra("id", id);
startActivity(i);
}
} catch (Exception e) {
e.printStackTrace();
a= new AlertDialog.Builder(LoginActivity.this).create();
a.setTitle("Erreur");
a.setMessage("Erreur :".concat(e.toString()));
a.show();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
}
I am quite new to android developing
I have written the following code to connect my android to a ftp server
package com.example.test1;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.apache.commons.net.ftp.*;
public class MainActivity extends Activity {
public FTPClient mFTPClient = null;
Button but;
public boolean ftpConnect(String host, String username, String password, int port) {
try {
mFTPClient = new FTPClient();
// connecting to the host
mFTPClient.connect(host, port);
// Now check the reply code, if positive mean connection success
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
// Login using username & password
boolean status = mFTPClient.login(username, password);
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
mFTPClient.enterLocalPassiveMode();
return status;
}
} catch(Exception e) {
CharSequence c = ""+e;
int d = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getApplicationContext(),c,d);
toast.show();
}
return false;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but=(Button)findViewById(R.id.button1);
but.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ftpConnect("127.0.0.1","userName","Password",21);
}
});
}
}
But this gives a networkOnMainThread Exception so after searching i found out i have to use AsyncTask but i have no idea how to implement it!
public void onClick(View v) {
new AsyncTask() {
publc Object doInBackground(Object...) {
try {
mFTPClient = new FTPClient();
// connecting to the host
mFTPClient.connect(host, port);
// Now check the reply code, if positive mean connection success
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
// Login using username & password
boolean status = mFTPClient.login(username, password);
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
mFTPClient.enterLocalPassiveMode();
return status;
}
} catch(Exception e) {
return e;
}
}
}
public void onPostExecute(Object res) {
if (res instanceof Exception) {
int d = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getApplicationContext(),""+res,d);
toast.show();
}
}
}.execute();
Another temporary 'workaround' is to set your android:targetSdkVersion="9" or below in AndroidManifest.xml, as this exception was introduced in API level 10.
Documentation on Android Developers is pretty rich on such an important topic. You'll get it through with that.
http://developer.android.com/reference/android/os/AsyncTask.html
You may want to refer the NetworkConnect sample from the Android SDK.
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 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.