Importing gmail contacts using GoogleAuthUtil - android

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.

Related

Microsoft translator returns error

I am trying to build an app that translate the current city to english.
this is my code:
class translateAsync extends AsyncTask<Void, Integer, Boolean> {
#Override
protected Boolean doInBackground(Void... arg0) {
Translate.setClientId("xxx");
Translate.setClientSecret("yyy");
try {
translatedText = Translate.execute(location, Language.AUTO_DETECT, Language.ENGLISH);
} catch(Exception e) {
translatedText = e.getMessage();
}
return true;
}
}
this is my call to async task:
new translateAsync() {
protected void onPostExecute(Boolean result) {
if (translatedText.contains("Error")){
lblCbProfileLayoutCurrentCity.setText(translatedText);
} else {
lblCbProfileLayoutCurrentCity.setText(getResources().getString(R.string.user_profile_code_current_city)
+ translatedText);
}
Toast.makeText(UserProfileActivity.this, translatedText, Toast.LENGTH_SHORT).show();
}
}.execute();
I keep getting this error:
[microsoft-translator-api] Error retrieving translation: https://datamarket.access-control.windows.net/v2/qauth2-13
Please Help Me.
I found the answer.
I didn't register my app in the azure market correctly and because of it i got a wrong secret key.
if anyone needs help with registering correctly you can email me.

AsyncTask return a boolean while retrieving information from a Json

I want to check if a user is registered or not in a database, and if it is get the information of the user.
Normally, when I retrieve the information from the server, I put in the Json a variable saying if the user exists or not. Then in onPostExecute(Void result) i treat the Json, so i don't need the AsyncTask to return any value.
Before I was calling the AsyncTask as follows:
task=new isCollectorRegistered();
task.execute();
But now i'm trying a different approach. I want my asynktask to just return a boolean where i called the AsyncTask.
the AsyncTask looks as follows:
public class isCollectorRegistered extends AsyncTask<Void, Void, Void> {
private static final String TAG_SUCCESS = "success";
int TAG_SUCCESS1;
private static final String TAG_COLLECTOR = "collector";
public String collector;
JSONArray USER = null;
JSONObject jObj = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// Checks on the server if collector is registered
try {
jObj = ServerUtilities.UserRegistered(context, collector);
return null;
} finally {
return null;
}
}
#Override
protected void onPostExecute(Void result) {
try {
String success = jObj.getString(TAG_SUCCESS);
Log.d(TAG_COLLECTOR, "Final Info: " + success);
//This if sees if user correct
if (Objects.equals(success, "1")){
//GOOD! THE COLLECTOR EXISTS!!
}
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG_COLLECTOR, "JSON parsing didn't work");
}
}
}
I have checked several posts, but I still havent found out the way to retrieve the boolean where I call the Asynktask, something like this :
task=new isCollectorRegistered();
task.execute();
boolean UserRegistered = task.result();
What would be the right approach? Any help would be appreciated
To use AsyncTask you must subclass it. AsyncTask uses generics and varargs. The parameters are the following AsyncTask <TypeOfVarArgParams , ProgressValue , ResultValue> .
An AsyncTask is started via the execute() method.
The execute() method calls the doInBackground() and the onPostExecute() method.
TypeOfVarArgParams is passed into the doInBackground() method as input, ProgressValue is used for progress information and ResultValue must be returned from doInBackground() method and is passed to onPostExecute() as a parameter.
In your case you are passing Void to your AsyncTask : isCollectorRegistered extends AsyncTask<Void, Void, Void> so you can't get your result from the thread.
please read this tutorial to a deep understand of the AsyncTask in Android
I think the following is exactly what you were looking for, Alvaro...NOTE: I tweaked your code to make it more sensible, but I tried to stick to as much of your original code as possible...
public class RegisterCollector extends AsyncTask<String, Void, Boolean> {
private static final String TAG_SUCCESS = "success";
private static final String TAG_COLLECTOR = "collector";
int TAG_SUCCESS1;
String[] strArray;
JSONArray USER = null;
JSONObject jObj = null;
public String collector;
private AppCompatActivity mAct; // Just incase you need an Activity Context inside your AsyncTask...
private ProgressDialog progDial;
// Pass data to the AsyncTask class via constructor -> HACK!!
// This is a HACK because you are apparently only suppose to pass data to AsyncTask via the 'execute()' method.
public RegisterCollector (AppCompatActivity mAct, String[] strArray) {
this.mAct = mAct;
this.strArray = strArray;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// AHAH!! - So we do need that Activity Context after all...*TISK* *TISK* # Google **sigh**.
progDial = ProgressDialog.show(mAct, "Please wait...", "Fetching the strawberries & cream", true, false);
}
#Override
protected Boolean doInBackground(String... params) {
// Checks on the server if collector is registered
try {
jObj = ServerUtilities.UserRegistered(context, collector);
return true; // return whatever Boolean you require here.
} finally {
return false; // return whatever Boolean you require here.
}
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progDial.dismiss();
try {
String success = jObj.getString(TAG_SUCCESS);
Log.d(TAG_COLLECTOR, "Final Info: " + success);
// This 'if' block checks if the user is correct...
if (Objects.equals(success, "1")){
//GOOD! THE COLLECTOR EXISTS!!
}
// You can then also use the Boolean result here if you need to...
if (result) {
// GOOD! THE COLLECTOR EXISTS!!
} else {
// Oh my --> We need to try again!! :(
}
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG_COLLECTOR, "JSON parsing didn't work");
Toast.makeText(mAct, "JSON parsing FAILED - Please try again.", Toast.LENGTH_LONG).show();
}
}
}
...then if you want to use the generated Boolean data outside the AsyncTask class try the following:.
RegisterCollector regisColctr = new RegisterCollector((AppCompatActivity) this, String[] myStrArry);
AsyncTask<String, Void, Boolean> exeRegisColctr = regisColctr.execute("");
Boolean isColctrRegistered = false;
try {
isColctrRegistered = exeRegisColctr.get(); // This is how you FINALLY 'get' the Boolean data outside the AsyncTask...-> VERY IMPORTANT!!
} catch (InterruptedException in) {
in.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
if (isColctrRegistered) {
// Do whatever tasks you need to do here based on the positive (i.e. 'true') AsyncTask Bool result...
} else {
// Do whatever tasks you need to do here based on the negative (i.e. 'false') AsyncTask Bool result...
}
There you go - I think this is what you were looking for (originally). I always use this approach whenever I need Async data externally, and it has yet to fail me....

How to implement ACRA with custom URL

I want to send the mail of Crash report in background but unable to send because it is using ACTION_SEND
I am using code: formKey = "", mailTo = "abc#gmail.com"
How can i make the url where the reports can be save to my own server, If any dummy url available to store or any open source database can be used. Please recommend.
Thanks
Use this custom class:
public class AcraCustomSender implements ReportSender {
Context activity;
#Override
public void send(Context context, CrashReportData errorContent) throws ReportSenderException {
activity=context;
String crashReport = "";
try {
JSONObject object = errorContent.toJSON();
Log.e("acra", object.toString());
crashReport = object.toString();
}catch (JSONReportBuilder.JSONReportException e) {
e.printStackTrace();
}
//the string crashreport contains your crash log. you can pass it to your own backend.
}
}
Create another class for your application:
public class YourApplication extends Application {
#Override
public void onCreate() {
try {
ACRA.init(this);
AcraCustomSender yourSender = new AcraCustomSender();
ACRA.getErrorReporter().setReportSender(yourSender);
super.onCreate();
}catch (Exception ex) {
ex.printStackTrace();
}
}
}
Now, whenever app crashes you can get it in AcraCustomSender class, and do whatever you want to do(like sending to your own DB)

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

Twitter OAuth issue: error 401

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.

Categories

Resources