Android: Add users to Parse via Facebook, using its `ParseFacebookUtils` - android

I have downloaded the sample from Parse.com for its login using facebook and adding uers to its data browser.
Its code is as follows:
IntegratingFacebookTutorialApplication class
public class IntegratingFacebookTutorialApplication extends Application {
static final String TAG = "MyApp";
#Override
public void onCreate() {
super.onCreate();
Parse.initialize(this, "Parse Application ID",
"Parse Client Key");
ParseFacebookUtils.initialize(getString(R.string.facebook_app_id));
}
Login class
import java.util.Arrays;
import java.util.List;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.parse.LogInCallback;
import com.parse.ParseException;
import com.parse.ParseFacebookUtils;
import com.parse.ParseUser;
public class LoginActivity extends Activity {
private Button loginButton;
private Dialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loginButton = (Button) findViewById(R.id.loginButton);
loginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onLoginButtonClicked();
}
});
// Check if there is a currently logged in user
// and they are linked to a Facebook account.
ParseUser currentUser = ParseUser.getCurrentUser();
if ((currentUser != null) && ParseFacebookUtils.isLinked(currentUser)) {
// Go to the user info activity
showUserDetailsActivity();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);
}
private void onLoginButtonClicked() {
LoginActivity.this.progressDialog = ProgressDialog.show(
LoginActivity.this, "", "Logging in...", true);
List<String> permissions = Arrays.asList("basic_info", "user_about_me",
"user_relationships", "user_birthday", "user_location");
ParseFacebookUtils.logIn(permissions, this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
LoginActivity.this.progressDialog.dismiss();
if (user == null)
{
Toast.makeText(getApplicationContext(), "Uh oh. The user cancelled the Facebook login.",
Toast.LENGTH_SHORT).show();
} else if (user.isNew()) {
Toast.makeText(getApplicationContext(), "User signed up and logged in through Facebook.",
Toast.LENGTH_SHORT).show();
showUserDetailsActivity();
} else {
Toast.makeText(getApplicationContext(), "User logged in through Facebook!",
Toast.LENGTH_SHORT).show();
showUserDetailsActivity();
}
}
});
}
private void showUserDetailsActivity() {
Intent intent = new Intent(this, UserDetailsActivity.class);
startActivity(intent);
}
}
Question:
Starting up the app (this tutorial), login page (page A) is shown, with a login in facebook button in middle.
If a user does not have facebook app in his device, the above code can run smoothly and successfully, after pressing login button, it will pop a dialog box and after logged in, the user details can be fetched and user details added to the data browser inside Parse.
However, if the user has already installed facebook app in the device, the dialog box would not appear, instead, it will open the facebook app and ask for login. This is where the problem happen. It shows for the permission dialog, and then after pressing "ok", the dialog is gone and return to the original page (page A).
The toast remarks "Uh oh. The user cancelled the Facebook login".
What is wrong with the code?? or the ADT environment? Should I further add anything in manifest?
I have researched as follows:
some say 'After a lot of attempts, the trick was a support.jar, specifically android-support-v4.jar. This comes with the new latest Facebook SDK but is not standard on your project. Use the Facebook one that is in their SDK and copy it into your libs folder and link.' (https://parse.com/questions/urgent-parsefacebookutilslogin-issue-android)
I was using the android:noHistory="true" on the manifest file for that activity. So whenever the facebook login activity was being opened, my activity was automatically being destroyed. But i do not have such history = true statement in the manifest.

Related

Android studio button onclick redirect condition when user is logged in and not logged in

I am new to coding, please I need help on this specific function I will be so grateful if anyone could help.
I am working on an android studio project, and on my activity (supposed Activity A) I want to place a button which when clicked it will open Supposed Activity B.
I have been able to setup onclick function and intent to open Activity B on button click.
But now what I want is if the user is not logged in then it should take the user to LoginActivity when that button is clicked, but when user is logged in it should take user direct to Activity B.
Please how can I achieve this on my Activity? Thanks in anticipation of a solution.
Below is my LoginActivity Code
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.sckoolboy.premiumapp.R;
public class Login extends AppCompatActivity {
EditText mEmail,mPassword;
Button mCreateBtn,mLoginBtn;
TextView forgotTextLink;
ProgressBar progressBar;
FirebaseAuth fAuth;
private FirebaseAuth auth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
auth = FirebaseAuth.getInstance();
if (auth.getCurrentUser() != null) {
startActivity(new Intent(Login.this, Main1.class));
finish();
}
setContentView(R.layout.activity_login);
mEmail = findViewById(R.id.Email);
mPassword = findViewById(R.id.password);
progressBar = findViewById(R.id.progressBar);
fAuth = FirebaseAuth.getInstance();
mLoginBtn = findViewById(R.id.loginBtn);
mCreateBtn = findViewById(R.id.createText);
forgotTextLink = findViewById(R.id.forgotPassword);
mLoginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String email = mEmail.getText().toString().trim();
String password = mPassword.getText().toString().trim();
if(TextUtils.isEmpty(email)){
mEmail.setError("Email is Required.");
return;
}
if(TextUtils.isEmpty(password)){
mPassword.setError("PremiumKey is Required.");
return;
}
if(password.length() < 6){
mPassword.setError("PremiumKey not valid");
return;
}
progressBar.setVisibility(View.VISIBLE);
// authenticate the user
fAuth.signInWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Toast.makeText(Login.this, "Premium Successfully Unlocked", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(),Main1.class));
}else {
Toast.makeText(Login.this, "Error ! " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
}
});
}
});
mCreateBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(),Register.class));
}
});
forgotTextLink.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final EditText resetMail = new EditText(v.getContext());
final AlertDialog.Builder passwordResetDialog = new AlertDialog.Builder(v.getContext());
passwordResetDialog.setTitle("Reset Password ?");
passwordResetDialog.setMessage("Enter Your Email To Received Reset Link.");
passwordResetDialog.setView(resetMail);
passwordResetDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// extract the email and send reset link
String mail = resetMail.getText().toString();
fAuth.sendPasswordResetEmail(mail).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(Login.this, "Reset Link Sent To Your Email.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Login.this, "Error ! Reset Link is Not Sent" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
passwordResetDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// close the dialog
}
});
passwordResetDialog.create().show();
}
});
}
}
using firebase authentication, how can i go about it from here
You can use an if block to switch between starting different activities, depending on whether the user was logged in or not.
For example, assuming loggedIn is the boolean variable storing whether the user was logged in, and button is the button,
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(v -> {
if (loggedIn) {
// Start ActivityB, user has logged in
Intent intent = new Intent(/* context here */, Main1.class);
startActivity(intent);
} else {
// Redirect to LoginActivity, user hasn't logged in
Intent intent = new Intent(/* context here */, Login.class);
startActivity(intent);
}
});
and the XML design for the new activity:
<!-- Root layout above..... -->
<Button
android:text="Log in"
android:id="#+id/button"/>
<!--Other elements below -->
You can get the login condition from Firebase's API, (reference made to https://stackoverflow.com/a/44585789/12204281), the method call should be:
FirebaseAuth.getInstance().getCurrentUser(), and this method returns null when user is not logged in.
So you can check if that value is null using equals operator and store it in loggedIn:
boolean loggedIn = FirebaseAuth.getInstance().getCurrentUser() != null;

Saving credentials in my app with Firebase UI

I am using Firebase UI, it is working fine.
When I open the app I give one phone number and I sign in, but when I close and again open the app again give me a code.
I want that when I close the app and again open it doesn't give me again the code.
I know then this make with one if but I don't know how to make the best.
I was using firebase UI, I did see something about smart lock password of google but I don't know if this is right because the storage should be local
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.IdpResponse;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.FirebaseDatabase;
import com.xx.xx.R;
import java.util.Arrays;
import java.util.List;
public class Login extends AppCompatActivity {
EditText et_login, et_password;
Button bt_login, bt_register;
private static int RC_SIGN_IN = 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
setContentView(R.layout.activity_login);
et_login = (EditText) findViewById(R.id.et_login);
et_password = (EditText) findViewById(R.id.et_password);
bt_login = (Button) findViewById(R.id.bt_login);
bt_register = (Button) findViewById(R.id.bt_register);
bt_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Login.this, MainActivity.class);
startActivity(intent);
finish();
}
});
bt_register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Login.this, RegisterActivity.class);
startActivity(intent);
}
});
// Choose authentication providers
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.PhoneBuilder().build());
// Create and launch sign-in intent
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.build(),
RC_SIGN_IN);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (resultCode == RESULT_OK) {
// Successfully signed in
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
//Save user to local database
// ...
} else {
// Sign in failed. If response is null the user canceled the
// sign-in flow using the back button. Otherwise check
// response.getError().getErrorCode() and handle the error.
// ...
}
}
}
}
The app should give me one number and save it, then when I close the app and open again it will not give me access again if not log in with before credential stored in the app.
What you can do is that in onStart check if the user is signed in or not, if the user is signed in then navigate to your MainActivity or any other Activity -
#Override
public void onStart() {
super.onStart();
// Check if the user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
// do your stuff
if (currentUser != null) {
// go to MainActivity
} else {
// user doesn't exist
}
}

Do any widely used Android apps have Facebook sharing with pre-populated text field?

I'm creating an Android app for a small business owner. I've implemented social sharing with a ShareActionProvider, and I have discovered that Facebook purposely does not allow apps to pre-populate posts. The user must enter their own text. (See this S.O. post and then this S.O. post ).
Multiple S.O. answers have indicated that by using the Facebook SDK, it is possible to achieve this result (pre-populating Facebook posts).
On the other hand, I learned that Facebook has [https://developers.facebook.com/docs/apps/review/prefill] (a policy) against doing this.
My questions are:
1) Is this really possible?
If so, how difficult is it to implement compared to the SharActionProvider?
2) Are there any popular or major apps whose Facebook sharing feature pre-populates text for the user?
3) Has Facebook been known to crack down on this policy? What has been their action towards people who break this policy?
This is the first Android app I've created and the first project I've done in 'real life'. I'm trying to figure out if adding this feature would be worth it for his business. He indicated he would like this feature to create an easy way to users to share content.
In my app I share the quotes from various famous personalities to social media. I have integrated Facebook SDK to enable user share it on their wall. I have not faced any crackdown from Facebook. App is being used over by 5K people as of now.
So to answer your questions,
Yes, it is possible. Not difficult to implement
I am not aware of other popular apps that use this feature
No crackdown or action from FB
This is what I do to share the quote on user's FB wall.
public void onClickFBShare(View view) {
quotview = (TextView) findViewById(R.id.MainText);
line = quotview.getText().toString(); //converting the text to String
Intent FBIntent = new Intent("android.intent.action.SHAREHELPER");
FBIntent.putExtra("quote", line);
startActivity(FBIntent);
}
The code to post the content is in Sharehelper.Java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphUser;
import com.facebook.widget.LoginButton;
import com.facebook.widget.LoginButton.UserInfoChangedCallback;
public class ShareHelper extends ActionBarActivity{
private LoginButton loginBtn;
private Button updateStatusBtn;
private TextView fbquote;
private TextView userName;
private UiLifecycleHelper uiHelper;
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private String message;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add code to print out the key hash
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.facebook.samples.hellofacebook",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {
} catch (NoSuchAlgorithmException e) {
}
Intent intent = getIntent();
message = intent.getStringExtra("quote");
uiHelper = new UiLifecycleHelper(this, statusCallback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.sharehelper_activity);
fbquote = (TextView)findViewById(R.id.FbTextView);
fbquote.setText(message);
userName = (TextView) findViewById(R.id.user_name);
loginBtn = (LoginButton) findViewById(R.id.fb_login_button);
loginBtn.setUserInfoChangedCallback(new UserInfoChangedCallback() {
#Override
public void onUserInfoFetched(GraphUser user) {
if (user != null) {
userName.setText("Hello, " + user.getName());
} else {
userName.setText("You are not logged");
}
}
});
updateStatusBtn = (Button) findViewById(R.id.update_status);
updateStatusBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
postStatusMessage();
}
});
buttonsEnabled(false);
}
private Session.StatusCallback statusCallback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
if (state.isOpened()) {
buttonsEnabled(true);
Log.d("FacebookSampleActivity", "Facebook session opened");
} else if (state.isClosed()) {
buttonsEnabled(false);
Log.d("FacebookSampleActivity", "Facebook session closed");
}
}
};
public void buttonsEnabled(boolean isEnabled) {
updateStatusBtn.setEnabled(isEnabled);
}
public void postStatusMessage() {
if (checkPermissions()) {
Request request = Request.newStatusUpdateRequest(
Session.getActiveSession(), message,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (response.getError() == null)
Toast.makeText(ShareHelper.this,
"Quote Shared successfully",
Toast.LENGTH_LONG).show();
}
});
request.executeAsync();
} else {
requestPermissions();
}
}
public boolean checkPermissions() {
Session s = Session.getActiveSession();
if (s != null) {
return s.getPermissions().contains("publish_actions");
} else
return false;
}
public void requestPermissions() {
Session s = Session.getActiveSession();
if (s != null)
s.requestNewPublishPermissions(new Session.NewPermissionsRequest(
this, PERMISSIONS));
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
buttonsEnabled(Session.getActiveSession().isOpened());
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onSaveInstanceState(Bundle savedState) {
super.onSaveInstanceState(savedState);
uiHelper.onSaveInstanceState(savedState);
}
}
It is possible to prefill the data, however it's really not recommended and support for it is non-existent. Facebook have explicitly highlighted it in their terms.
Pre-fill the user message parameter with any content the user didn't enter themselves, even if they can edit or delete that content before sharing. This applies to posts, comments, photo captions, and photo album captions.
While I've not seen Facebook crack down on it personally that doesn't mean that should do it. If it was a grey area you'd have grounds to fight a Facebook fight (i.e. removing a business page, blocking API access...) however it's very clear about not doing it.

Facebook Android Integration Error

I am facing a problem when logging into Facebook using my app, It shows following error
"App Not Setup : The Developer of this App have not setup this app properly for facebook login "
This is my code :
package com.example.dronacharyaratings;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.Toast;
public class login extends ActionBarActivity implements OnClickListener {
ImageButton imgbtn;
// Your Facebook APP ID
private static String APP_ID = "578242662259998"; // Replace with your App ID
// Instance of Facebook Class
#SuppressWarnings("deprecation")
private Facebook facebook = new Facebook(APP_ID);
#SuppressWarnings({ "deprecation", "unused" })
private AsyncFacebookRunner mAsyncRunner;
String FILENAME = "AndroidSSO_data";
private SharedPreferences mPrefs;
#SuppressWarnings("deprecation")
public void onCreate(final Bundle savedInstanceState1) {
super.onCreate(savedInstanceState1);
setContentView(R.layout.login);
getSupportActionBar().hide();
mAsyncRunner = new AsyncFacebookRunner(facebook);
imgbtn = (ImageButton)findViewById(R.id.imageButton1);
imgbtn.setOnClickListener(this);
}
public void onClick(View arg0) {
Log.d("Image Button", "button Clicked");
loginToFacebook();
}
#SuppressWarnings("deprecation")
private void loginToFacebook() {
// TODO Auto-generated method stub
mPrefs = getPreferences(MODE_PRIVATE);
String access_token = mPrefs.getString("access_token", null);
long expires = mPrefs.getLong("access_expires", 0);
if (access_token != null) {
facebook.setAccessToken(access_token);
Log.d("FB Sessions", "" + facebook.isSessionValid());
}
if (expires != 0) {
facebook.setAccessExpires(expires);
}
if (!facebook.isSessionValid()) {
facebook.authorize(this,
new String[] { "email", "publish_stream" },
new DialogListener() {
#Override
public void onCancel() {
// Function to handle cancel event
}
#Override
public void onComplete(Bundle values) {
// Function to handle complete event
// Edit Preferences and update facebook acess_token
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token",
facebook.getAccessToken());
editor.putLong("access_expires",
facebook.getAccessExpires());
editor.commit();
}
#Override
public void onFacebookError(FacebookError e) {
// TODO Auto-generated method stub
}
#Override
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
});
}
}
#SuppressWarnings("deprecation")
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
/**
* Function to show Access Tokens
* */
public void showAccessTokens() {
#SuppressWarnings("deprecation")
String access_token = facebook.getAccessToken();
Toast.makeText(getApplicationContext(),
"Access Token: " + access_token, Toast.LENGTH_LONG).show();
}
}
This issues only arises when your app isn't public.
To do that you should first login into your
developers.facebook.com
and in the status and review of your particular app
Toggle the button to yes where it says "Do you want to make
this app and all its live features available to the general
public? "
You are getting this error probably because your app is not public and only you as an admin have the access to login.For making the app as public and allowing others to use your app do the following steps.
1)Make sure you have a valid email in the "Contact Email" field in the settings -> Basic section.
2)Once you provide a valid e-mail then only you can make your app as public so that FB can contact you regarding your app.
3)In the "Status and Review" section change the option of "Do you want to make this app and all its live features available to the general public?" from "no" to yes and press confirm on the popup message.
you can see a red dot just next to your app name which confirms that your app is now available to public and all can login with their own credentials.
Happy facebooking!!!

How to Login into Gmail using OAuth in Android Application?

I am Developing an application which uses Login to Gmail.I gone through all tutorials,stackoverflow questions which is tagged under OAuth 2.0 and documents that are available in google and finally as per the guide lines given in official document of Google for OAuth 2.0 sample. I have created Client ID and everything that is required for installed applications i.e., for Android. Everything up to now works fine,and i called WebView to grant permission from the user,After that i got Accesstoken like 4/cR7XXXXXXXXXXXXXXX in the WebViewand saying something like Please copy this code,switch to your application and paste it here.I am confused here,i don't know what to do,to get back to my app from Webview .Am searching for the solution about two days but,Am not able to get good answer for my problem.Here is the code where i was got stoped.
Main.java where user have an OptionMenu to login. When the user clicks WebViewopens to enter gmail.
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Main extends Activity {
public static String REQUEST = "https://accounts.google.com/o/oauth2/auth?"
+ "client_id=XXXXXXXXXXX-gxxxx.apps.googleusercontent.com&"
+ "redirect_uri=urn:ietf:wg:oauth:2.0:oob&"
+ "scope=https://mail.google.com/mail/feed/atom&"
+ "response_type=code&" + "access_type=online";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 0:
if (requestCode != RESULT_OK || data == null) {
return;
}
String token = data.getStringExtra("token");
if (token != null) {
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
Intent intent_obj2 = new Intent(Main.this, Webview.class);
intent_obj2.setData(Uri.parse(REQUEST));
startActivityForResult(intent_obj2, 0);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Webview.java
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.Window;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class Webview extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_PROGRESS);
final WebView wb_obj = new WebView(this);
setContentView(wb_obj);
wb_obj.getSettings().setJavaScriptEnabled(true);
Intent intent = getIntent();
if (intent.getData() != null) {
wb_obj.loadUrl(intent.getDataString());
}
wb_obj.setWebChromeClient(new WebChromeClient() {
#Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
setProgress(newProgress * 10000);
}
});
wb_obj.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
setTitle(url);
System.out.println(url);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
System.out.println("in onPageFinsihed");
/*CookieSyncManager.getInstance().sync();
String s_cookie = CookieManager.getInstance().getCookie(url);
if (s_cookie == null) {
System.out.println(s_cookie);
return;
}else{
String web_title = wb_obj.getTitle().toString();
System.out.println("web tile" + web_title);
if (web_title.equalsIgnoreCase("Request for Permission")) {
} else {
String[] s_webtitle = web_title.split("=", 2);
String access_token = s_webtitle[1].toString();
//System.out.println("Access token" + access_token);
startActivity(new Intent(Webview.this, Main.class));
finish();
}*/
}
});
}
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new Intent(Webview.this, Main.class));
}
}
As per Webview.java i called finish() so that current activity gets killed but this is nit happening in this app,so that i will get token in onAcitivityResult().Please share Your answers thank you.
Below steps are require to login to Google.
1- Select an account from your device using below code
public static AccountManager accountManager;
accountManager = AccountManager.get(this);
Account[] accounts = accountManager.getAccountsByType("com.google");
2- Get a Token from selected account using below code
private void onAccountSelected(final Account account) {
accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, null, this, new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
useToken(account, token);
} catch (OperationCanceledException e) {
onAccessDenied();
} catch (Exception e) {
handleException(e);
}
}
}, null);
}
3- now Authenticate the Token using user account and Token. you will be able to login to google.
NOTE: you will get Authentication full code from here Authentication code , put your gmail a/c and token where required. now you are able to loging using OAuth.
4- for re login you have to invalidate your token using below code
accountManager.invalidateAuthToken("com.google", token);
5- after invalidate you have to get a new token using below code
String newToken = AccountManager.get(this).getAuthToken(new Account(account, "com.google"),
AUTH_TOKEN_TYPE, true, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
6- in your AndroidManifest.xml add below uses permissions
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
Thats all you require, now enjoy.
Consider using "localhost:port" as the redirect uri instead of urn:ietf:wg:oauth:2.0:oob& (for more details refer to https://developers.google.com/youtube/v3/guides/authentication#installed-apps) and trap this URL being loaded in the webview in the callback:
public boolean shouldOverrideUrlLoading (WebView view, String url).
For an alternative way of accessing the Gmail API with an OAuth2 token, you may consider the answers from this post: OAuth and Java (connecting to GMail).

Categories

Resources