Based on this I'm trying to auth with google. But a GoogleAuthException is thrown and the message is "BadUsername". This confuses me since I'm picking the email/username by the account picker. Anyone got a clue about what I'm doing wrong?
public class MainActivity extends Activity implements MainFragment.OnFragmentInteractionListener {
private static final String TAG = MainActivity.class.getSimpleName();
static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
String mEmail; // Received from newChooseAccountIntent(); passed to getToken()
private static final String SCOPE =
"oauth2:https://www.googleapis.com/auth/userinfo.profile";
#Override
protected void onCreate(Bundle savedInstanceState) {
...
pickUserAccount();
}
private void pickUserAccount() {
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
// Receiving a result from the AccountPicker
if (resultCode == RESULT_OK) {
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
// With the account name acquired, go get the auth token
Toast.makeText(this, mEmail, Toast.LENGTH_SHORT).show();
ConfirmEmailTask confirmEmailTask = new ConfirmEmailTask(this, SCOPE, mEmail);
confirmEmailTask.execute();
} else if (resultCode == RESULT_CANCELED) {
// The account picker dialog closed without selecting an account.
// Notify users that they must pick an account to proceed.
// Toast.makeText(this, R.string.pick_account, Toast.LENGTH_SHORT).show();
}
}
// Later, more code will go here to handle the result from some exceptions...
}
public class ConfirmEmailTask extends AsyncTask<Void, Void, String> {
Activity mActivity;
String mScope;
String mEmail;
ConfirmEmailTask(Activity activity, String name, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = name;
}
/**
* Executes the asynchronous job. This runs when you call execute()
* on the AsyncTask instance.
*/
#Override
protected String doInBackground(Void... params) {
try {
String token = fetchToken();
if (token != null) {
return token;
// Insert the good stuff here.
// Use the token to access the user's Google data.
// Toast.makeText(mActivity, token, Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
// The fetchToken() method handles Google-specific exceptions,
// so this indicates something went wrong at a higher level.
// TIP: Check for network connectivity before starting the AsyncTask.
}
return null;
}
/**
* Gets an authentication token from Google and handles any
* GoogleAuthException that may occur.
*/
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
Log.d(TAG, "error");
// GooglePlayServices.apk is either old, disabled, or not present
// so we need to show the user some UI in the activity to recover.
// mActivity.handleException(userRecoverableException);
} catch (GoogleAuthException fatalException) {
// Some other type of unrecoverable exception has occurred.
// Report and log the error as appropriate for your app.
Log.d(TAG, fatalException.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(mActivity, result, Toast.LENGTH_SHORT).show();
}
}
}
Below is the stacktrace.
W/System.err﹕ com.google.android.gms.auth.GoogleAuthException: BadUsername
W/System.err﹕ at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
W/System.err﹕ at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
W/System.err﹕ at dk.eterno.bloatwareremover.MainActivity$ConfirmEmailTask.fetchToken(MainActivity.java:138)
W/System.err﹕ at dk.eterno.bloatwareremover.MainActivity$ConfirmEmailTask.doInBackground(MainActivity.java:115)
W/System.err﹕ at dk.eterno.bloatwareremover.MainActivity$ConfirmEmailTask.doInBackground(MainActivity.java:97)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
Just for the record.
The problem here is that you are passing wrong the arguments in this:
ConfirmEmailTask confirmEmailTask = new ConfirmEmailTask(this, SCOPE, mEmail);
The class constructor is defined like
ConfirmEmailTask(Activity activity, String name, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = name;
}
So change the order of parameters in one of them.
Related
I'm developing an android application that makes use of Google Drive REST API. I just want to list all files in my drive. But when the method listDriveFiles() is called I get an error as java.lang.IllegalArgumentException: the name must not be empty: null.
I found similar problems asked here and most of them says to add the permission GET_ACCOUNT. I already did that but no luck. One answer points to check the value of getAccount() and when I did that I get the value as null.
Error:
java.lang.IllegalArgumentException: the name must not be empty: null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2358)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5388)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:655)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: the name must not be empty: null
at android.accounts.Account.<init>(Account.java:48)
at com.google.android.gms.auth.zzd.getToken(Unknown Source)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.datacubeinfo.drive2.MainActivity.listDriveFiles(MainActivity.java:68)
at com.datacubeinfo.drive2.MainActivity.onDriveClientReady(MainActivity.java:88)
at com.datacubeinfo.drive2.BaseGoogleDriveActivity.initializeDriveClient(BaseGoogleDriveActivity.java:149)
at com.datacubeinfo.drive2.BaseGoogleDriveActivity.signIn(BaseGoogleDriveActivity.java:82)
at com.datacubeinfo.drive2.BaseGoogleDriveActivity.onStart(BaseGoogleDriveActivity.java:43)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1174)
at android.app.Activity.performStart(Activity.java:5290)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5388)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:655)
at dalvik.system.NativeStart.main(Native Method)
MainActivity.java
public class MainActivity extends BaseGoogleDriveActivity {
private static final String APPLICATION_NAME = "Google Drive API";
/**
* Global instance of the HTTP transport.
*/
private static HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
/**
* Global instance of the JSON factory.
*/
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private Drive mDrive;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
signIn();
}
});
findViewById(R.id.listFile).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
try {
listDriveFiles();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
task.execute();
}
});
}
public void listDriveFiles() throws IOException {
// Print the names and IDs for up to 10 files.
FileList result = mDrive.files().list()
.setPageSize(10)
.setFields("nextPageToken, files(id, name)")
.execute();
List<File> files = result.getFiles();
if (files == null || files.isEmpty()) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
}
#Override
protected void onDriveClientReady(String displayName, String email, Uri avatar) {
// Build a new authorized API client service.
mDrive = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredential())
.setApplicationName(APPLICATION_NAME)
.build();
try {
listDriveFiles();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BaseGoogleDriveActivity.java
public abstract class BaseGoogleDriveActivity extends AppCompatActivity {
private static final String TAG = "BaseDriveActivity";
public static final Scope SCOPE_FILE = new Scope("https://www.googleapis.com/auth/drive.file");
public static final Scope SCOPE_APPFOLDER = new Scope("https://www.googleapis.com/auth/drive.appdata");
/**
* Request code for Google Sign-in
*/
protected static final int REQUEST_CODE_SIGN_IN = 1;
private String mToken;
private GoogleAccountCredential mCredential;
#Override
protected void onStart() {
super.onStart();
signIn();
}
/**
* Handles resolution callbacks.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SIGN_IN) {
if (resultCode != RESULT_OK) {
// Sign-in may fail or be cancelled by the user. For this sample, sign-in is
// required and is fatal. For apps where sign-in is optional, handle
// appropriately
Log.e(TAG, "Sign-in failed.");
return;
}
Task<GoogleSignInAccount> getAccountTask =
GoogleSignIn.getSignedInAccountFromIntent(data);
if (getAccountTask.isSuccessful()) {
initializeDriveClient(getAccountTask.getResult());
} else {
Log.e(TAG, "Sign-in failed.");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* Starts the sign-in process and initializes the Drive client.
*/
protected void signIn() {
Set<Scope> requiredScopes = new HashSet<>(2);
requiredScopes.add(SCOPE_FILE);
requiredScopes.add(SCOPE_APPFOLDER);
GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
initializeDriveClient(signInAccount);
} else {
GoogleSignInOptions signInOptions =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(SCOPE_FILE)
.requestScopes(SCOPE_APPFOLDER)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
}
protected boolean checkSignedIn(boolean initClient) {
Set<Scope> requiredScopes = new HashSet<>(2);
requiredScopes.add(SCOPE_FILE);
requiredScopes.add(SCOPE_APPFOLDER);
GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
if (initClient) {
initializeDriveClient(signInAccount);
}
return true;
} else {
return false;
}
}
protected void signOut() {
GoogleSignInOptions signInOptions =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(SCOPE_FILE)
.requestScopes(SCOPE_APPFOLDER)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
googleSignInClient.signOut();
}
/**
* Continues the sign-in process, initializing the Drive clients with the current
* user's account.
*/
private void initializeDriveClient(final GoogleSignInAccount signInAccount) {
mCredential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(SCOPE_FILE.getScopeUri()));
mCredential.setSelectedAccount(signInAccount.getAccount());
Log.e(TAG, ""+signInAccount.getAccount());
onDriveClientReady(signInAccount.getDisplayName(), signInAccount.getEmail(), signInAccount.getPhotoUrl());
}
public GoogleAccountCredential getCredential() {
return mCredential;
}
protected String getToken() {
return mToken;
}
/**
* Called after the user has signed in and the Drive client has been initialized.
*/
protected abstract void onDriveClientReady(final String displayName, final String email, final Uri avatar);
}
After some research I found what was missing. As I mentioned in the question the getAccount() always returned null value. So I checked the documentation of GoogleSignInAccount class.
You can check it here.
There it states that
getAccount() is a convenient wrapper for getEmail() which returns an
android.accounts.Account object
The getEmail() returns null if requestEmail() is not configured. If getEmail() is null, then is getAccount(). So I made changes in my code as below.
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(SCOPE_FILE)
.requestScopes(SCOPE_APPFOLDER)
.requestEmail()
.build();
Now it works perfect.
In my case (Google Drive REST API v3), ProGuard was the culprit, as the code was working fine in debug mode.
Just adding -keep class com.google.** { *;} to ProGuard rules got rid of the issue.
Good day everyone.
So, I have an AsyncTask that calculates a Gaussian Blur from an image. The original image data is retrieved from SQLite using Blob field, also the filtered image is stored in SQLite. Here's the code (setQuizData is the function that does this):
public class SaveFilterTask extends AsyncTask<Void, Void, Void>{
private Context mContext;
private Context mApplicationContext;
private Quiz mQuiz;
public SaveFilterTask(Context context, Quiz quiz, Context applicationContext) {
super();
this.mContext = context;
this.mApplicationContext = applicationContext;
this.mQuiz = quiz;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
setQuizData(mQuiz);
} catch (UnsupportedEncodingException e) {
cancel(true);
}
return null;
}
#Override
protected void onCancelled() {
Toast toast = Toast.makeText(mContext, R.string.error_loading_quiz, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
#Override
protected void onPreExecute() {
if(!((Activity)mContext).isFinishing()){
((MainActivity)mContext).showDialog();
}
}
protected void onPostExecute(Void args) {
if(!((Activity)mContext).isFinishing()){
((MainActivity)mContext).hideDialog();
}
Intent solveQuizIntent = new Intent(mContext, SolveQuizActivity.class);
solveQuizIntent.putExtra(
QuizConstants.KEY_PARCELABLE_FINISHED_QUIZ, mQuiz);
solveQuizIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(solveQuizIntent);
}
private void setQuizData(Quiz quiz) throws UnsupportedEncodingException {
if(quiz.getType().equals(QuizConstants.TYPE_PHOTO)){
QuizDataSource quizdatasource = new QuizDataSource(mApplicationContext);
quizdatasource.open();
String data = quizdatasource.getData(quiz.getId());
quizdatasource.close();
QuizDataSource quizdatasource2 = new QuizDataSource(mApplicationContext);
quizdatasource2.open();
String filterData = quizdatasource2.getDataFilter(quiz.getId());
quizdatasource2.close();
String filter = quiz.getFilter();
if(filter != null){
if(!filter.equals(QuizConstants.FILTER_DEFAULT)){
Bitmap original = decodeImage(data);
if(filterData == null){
data = FilterManager.applyFilter(original, quiz.getFilter());
Log.d("FilterManager","Data: "+ data);
Log.d("FilterManager","Id: "+ quiz.getId());
QuizDataSource quizdatasourceW = new QuizDataSource(mApplicationContext);
quizdatasourceW.open();
quizdatasourceW.setDataFilter(quiz.getId(), data);
quizdatasourceW.close();
}
}
}
}
}
private static Bitmap decodeImage(String data) {
byte[] b = Base64.decode(data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
}
This task is called from my Activity, like this:
SaveFilterTask sftask = new SaveFilterTask(this, quiz, getApplicationContext());
sftask.execute();
I don't know why sometimes (and randomly) I get this error:
0java.lang.RuntimeException: An error occured while executing doInBackground()
1at android.os.AsyncTask$3.done(AsyncTask.java:300)
2at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
3at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
4at java.util.concurrent.FutureTask.run(FutureTask.java:242)
5at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
6at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
7at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
8at java.lang.Thread.run(Thread.java:841)
9Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/Data.db
10at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
11at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1156)
12at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
13at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
14at QuizDataSource.getDataFilter(QuizDataSource.java:119)
15at SaveFilterTask.setQuizData(SaveFilterTask.java:82)
16at SaveFilterTask.doInBackground(SaveFilterTask.java:39)
17at SaveFilterTask.doInBackground(SaveFilterTask.java:1)
I tried in different ways, using a single connection, using one connection for the read operations and one for the write operation. But the bug persists...
Any ideas?
thanks.
First of all you shouldnt reinitialize QuazDataSource everytime.
Initialize it in the Construcotr and check it by using
if (quizdatasource == null) {
quizdatasource = CreateaQuizDataSourceHelper().open;
}
Then you should always make sure to close it, even when it fails.
Cursor cursor = null;
try {
if (quizdatasource == null) {
quizdatasource = CreateaQuizDataSourceHelper().open;
}
cursor= quizdatasource.rawQuery(...);
} catch (Exception e) { e.printStackTrace(); }
finally {
if (quizdatasource != null) { quizdatasource.close(); }
}
at least make sure that your cursors are closed aswell by putting the validating in the finally block.
if (cursor != null) { cursor.close; }
then you shouldnt get multiple instances.
You should also create a SINGLETON Instance of your database, to make sure it's accessed only onec.
The Helper itself may have such a open method to make sure it's using the same connection.
public SQLiteDatabase open() {
SQLiteDatabase sqLiteDatabase = null;
try {
try {
sqLiteDatabase = this.getDatabaseConnection();
} catch (SQLiteException e) {
e.printStackTrace();
DataBaseConnectionPool.DbHelper DbHelper = this.dbHelper;
if (DbHelper != null) {
return this.dbHelper.getReadableDatabase();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sqLiteDatabase;
}
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 8 years ago.
public class Foursquare {
private static final String LOGIN = "oauth";
public static final String API_END_POING_BASE_URL = "https://api.foursquare.com/v2/";
public static String REDIRECT_URI;
public static final String API_URL = "https://foursquare.com/oauth2/";
//public static final String CANCEL_URI = "";
public static final String TOKEN = "access_token";
public static final String EXPIRES = "expires_in";
public static final String SINGLE_SIGN_ON_DISABLED = "service_disabled";
public static String AUTHENTICATE_URL = "https://foursquare.com/oauth2/authenticate";// +
private String mClientId;
private String mClientSecret;
private String mAccessToken = null;
private DialogListener mAuthDialogListener;
public Foursquare(String clientId, String clientSecret, String redirectUrl) {
if (clientId == null || clientSecret == null) {
throw new IllegalArgumentException(
"You must specify your application ID when instantiating "
+ "a Foursquare object. See README for details.");
}
mClientId = clientId;
mClientSecret = clientSecret;
REDIRECT_URI = redirectUrl;
}
public void authorize(Activity activity, final DialogListener listener) {
mAuthDialogListener = listener;
startDialogAuth(activity);
}
public void startDialogAuth(Activity activity) {
CookieSyncManager.createInstance(activity);
Bundle params = new Bundle();
dialog(activity, LOGIN, params, new DialogListener() {
public void onComplete(Bundle values) {
// ensure any cookies set by the dialog are saved
CookieSyncManager.getInstance().sync();
String _token = values.getString(TOKEN);
setAccessToken(_token);
// setAccessExpiresIn(values.getString(EXPIRES));
if (isSessionValid()) {
Log.d("Foursquare-authorize",
"Login Success! access_token=" + getAccessToken());
mAuthDialogListener.onComplete(values);
} else {
mAuthDialogListener.onFoursquareError(new FoursquareError(
"Failed to receive access token."));
}
}
public void onError(DialogError error) {
Log.d("Foursquare-authorize", "Login failed: " + error);
mAuthDialogListener.onError(error);
}
public void onFoursquareError(FoursquareError error) {
Log.d("Foursquare-authorize", "Login failed: " + error);
mAuthDialogListener.onFoursquareError(error);
}
public void onCancel() {
Log.d("Foursquare-authorize", "Login canceled");
mAuthDialogListener.onCancel();
}
});
}
public void dialog(Context context, String action, Bundle parameters,
final DialogListener listener) {
String endpoint = "";
parameters.putString("client_id", mClientId);
parameters.putString("display", "touch");
if (action.equals(LOGIN)) {
endpoint = AUTHENTICATE_URL;
parameters.putString("client_secret", mClientSecret);
parameters.putString("response_type", "token");
parameters.putString("redirect_uri", REDIRECT_URI);
}
// if (isSessionValid()) {
// parameters.putString(TOKEN, getAccessToken());
// }
String url = endpoint + "?" + Util.encodeUrl(parameters);
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
Util.showAlert(context, "Error",
"Application requires permission to access the Internet");
} else {
new FoursquareDialog(context, url, listener).show();
}
}
public boolean isSessionValid() {
if (getAccessToken() != null) {
return true;
}
return false;
}
public void setAccessToken(String token) {
mAccessToken = token;
}
public String getAccessToken() {
return mAccessToken;
}
public String request(String graphPath) throws MalformedURLException,
IOException {
return request(graphPath, new Bundle(), "GET");
}
public String request(String graphPath, Bundle parameters)
throws MalformedURLException, IOException {
return request(graphPath, parameters, "GET");
}
public String request(String graphPath, Bundle params, String httpMethod)
throws FileNotFoundException, MalformedURLException, IOException {
params.putString("format", "json");
if (isSessionValid()) {
params.putString("oauth_token", getAccessToken());
}
String url = API_END_POING_BASE_URL + graphPath;
return Util.openUrl(url, httpMethod, params);
}
public static interface DialogListener {
/**
* Called when a dialog completes.
*
* Executed by the thread that initiated the dialog.
*
* #param values
* Key-value string pairs extracted from the response.
*/
public void onComplete(Bundle values);
/**
* Called when a Foursquare responds to a dialog with an error.
*
* Executed by the thread that initiated the dialog.
*
*/
public void onFoursquareError(FoursquareError e);
/**
* Called when a dialog has an error.
*
* Executed by the thread that initiated the dialog.
*
*/
public void onError(DialogError e);
/**
* Called when a dialog is canceled by the user.
*
* Executed by the thread that initiated the dialog.
*
*/
public void onCancel();
}
}
i am using foursqure functionality in my application in which user share any data so user can share on foursqure..,the problem is when i am using "StrictMode "functionality in my oncreate.,its not giving me error.,but when i am not using its giving me networkon minthread exception
i am getting this exception in foursqure.when dialog is loading??what i do plese help me thankyou...:)
here is my logcat
Networking operations tend to take some time. That's why on Android, it's forbidden to perform Networking Tasks on the UI (foreground) thread. The System throws a NetworkingOnMainThreadException if you try it.
You have to move your Networking code to a Background thread. The easiest way to do that is by using an AsyncTask.
Implement AsyncTask, read here
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.
Exception:
07-28 14:36:13.140: W/System.err(11382): com.google.android.gms.auth.GoogleAuthException: Unknown
07-28 14:36:13.140: W/System.err(11382): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-28 14:36:13.140: W/System.err(11382): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
07-28 14:36:13.148: E/AndroidRuntime(11382): FATAL EXCEPTION: main
My Sign Up code:
public class Signup extends Activity {
final private String CLIENT_ID = <android-client-id>;
final private List<String> SCOPES = Arrays.asList(new String[]{
"https://www.googleapis.com/auth/plus.login"
});
private String webId = <web-client-id>;
private GoogleAccountCredential mCredential;
private EditText mExchangeCodeEditText;
private EditText mIdTokenEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google);
//mExchangeCodeEditText = (EditText) findViewById(R.id.editTextExchangeCode);
// mIdTokenEditText = (EditText) findViewById(R.id.editTextIdToken);
// initiate a credential object with drive and plus.login scopes
// cross identity is only available for tokens retrieved with plus.login
mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(SCOPES.get(0)));
// user needs to select an account, start account picker
startActivityForResult(
mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
/**
* Handles the callbacks from result returning
* account picker and permission requester activities.
*/
#Override
protected void onActivityResult(
final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
// user has returned back from the account picker,
// initiate the rest of the flow with the account he/she has chosen.
case REQUEST_ACCOUNT_PICKER:
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
mCredential.setSelectedAccountName(accountName);
new RetrieveExchangeCodeAsyncTask().execute();
new RetrieveJwtAsyncTask().execute();
}
break;
// user has returned back from the permissions screen,
// if he/she has given enough permissions, retry the the request.
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
// replay the same operations
new RetrieveExchangeCodeAsyncTask().execute();
new RetrieveJwtAsyncTask().execute();
}
break;
}
}
/**
* Retrieves the exchange code to be sent to the
* server-side component of the app.
*/
public class RetrieveExchangeCodeAsyncTask
extends AsyncTask<Void, Boolean, String> {
#Override
protected String doInBackground(Void... params) {
String scope = String.format("oauth2:server:client_id:%s:api_scope:%s",
CLIENT_ID, TextUtils.join(" ", SCOPES));
try {
GoogleAccountCredential.usingAudience(Signup.this, "server:client_id:" + webId);
return GoogleAuthUtil.getToken(
Signup.this, mCredential.getSelectedAccountName(), scope);
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (Exception e) {
e.printStackTrace(); // TODO: handle the exception
}
return null;
}
#Override
protected void onPostExecute(String code) {
// exchange code with server-side to retrieve an additional
// access token on the server-side.
// mExchangeCodeEditText.setText(code);
Log.d("code",code);
}
}
/**
* Retrieves a JWT to identify the user without the
* regular client-side authorization flow. The jwt payload needs to be
* sent to the server-side component.
*/
public class RetrieveJwtAsyncTask
extends AsyncTask<Void, Boolean, String> {
#Override
protected String doInBackground(Void... params) {
String scope = "audience:server:client_id:" + CLIENT_ID;
try {
return GoogleAuthUtil.getToken(
Signup.this, mCredential.getSelectedAccountName(), scope);
} catch(UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (Exception e) {
e.printStackTrace(); // TODO: handle the exception
}
return null;
}
#Override
protected void onPostExecute(String idToken) {
// exchange encrypted idToken with server-side to identify the user
// mIdTokenEditText.setText(idToken);
Log.d("idtoken",idToken);
}
}
private static final int REQUEST_ACCOUNT_PICKER = 100;
private static final int REQUEST_AUTHORIZATION = 200;
}
I'm completely clueless what's happening here. Help?
I had similar problem. In my case the problem was in missed application name in google console.
Open console navigate to your project and choose "Consent screen". Fill in the "PRODUCT NAME" field and save.
Similar to CheatEx, I had to select my email address from the "Consent Screen" page and save.