问题
Is it possible to do a Facebook Login in Android in an non-Activity class?
I have an activity which loads different "Setting Classes" for Social Media Logins etc. One of them is Facebook. This is a non Activity class which loads my Facebook-Settings.xml. There are some Switch Buttons etc. Save switch button status is working. I have also integrated the Facebook Login Button. But it seems the onSuccess is not called
What am I missing or doing wrong here? Is it even possible to login to Facebook in a non-activity class?
public class FacebookService extends SensorService {
public FacebookService() {
super("fb");
}
//add Sensorname UI
@Override
public void load() {
name.setText("FACEBOOOK");
}
//load settings xml-file if settings button is clicked
@Override
public int getSettingsViewId() {
FacebookSdk.sdkInitialize(context.getApplicationContext());
callbackManager = CallbackManager.Factory.create();
}
return R.layout.fb_settings;
}
//Saves Checked Buttons from Facebook Seetings
@Override
public void save(View settings) {
TextView text = (TextView) settings.findViewById(R.id.FBText);
switchPosts = (Switch) settings.findViewById(R.id.switchPosts);
}
//Creates View for Facebook Settings
//loads Check Buttons state from Shared preferences and updates view
@Override
public void createSettings(View settings) {
LoginButton loginButton = (LoginButton) settings.findViewById(R.id.login_button);
loginButton.setReadPermissions("public_profile, email, user_about_me, user_posts, user_friends, user_events, user_photos, user_likes, user_relationships, user_birthday");
getLoginDetails(loginButton);
}
protected void getLoginDetails(LoginButton login_button){
// Callback registration
login_button.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult login_result) {
Log.d("app", "FB Login");
accessToken = login_result.getAccessToken();
if(accessToken != null){
//statusFacebook.setText("Login Erfolgreich");
Log.d("app", "Login success");
}
else{
//statusFacebook.setText("Login fehlgeschlagen");
Log.d("app", "Login no success");
}
}
@Override
public void onCancel() {
// code for cancellation
}
@Override
public void onError(FacebookException exception) {
// code to handle error
}
});
}
private void setSwitches() {
//DO Something
}
}
I start the FacebookService.class from my Main Activity
protected void onCreate(Bundle savedInstanceState) {
....
ServiceManager.getInstance().setContext(this);
ServiceManager.getInstance().setRoot((ViewGroup)findViewById(R.id.service_view));
ServiceManager.getInstance().add(new FacebookService());
ServiceManager.getInstance().add(new TwitterService());
}
回答1:
You receive the result of login into onActivityResult method of your Activity or Fragment. Then into that method you must pass the result to the CallbackManager. This step is not automatic.
So you need something like this (this the Fragment's method)
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
If you want to implement login in non Activity class you must anyway add at least this code
回答2:
There is no documentation about it, but technically it is possible. Here is how I achieved this:
This is my MainActivity:
package com.saddan.facebook_login_mvc;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.login.widget.LoginButton;
public class MainActivity extends AppCompatActivity
{
LoginButton loginButton;
private FacebookLogin Login;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginButton=findViewById(R.id.login_button);
Login=new FacebookLogin(loginButton,this);
Login.facebookLogin();
Login.checkLoginStatus();
}
@Override
protected void onActivityResult(int requestCode, int resultCode,@Nullable Intent data) {
Login.onActivityResultFB(requestCode,resultCode,data);
super.onActivityResult(requestCode, resultCode, data);
}
}
And my Facebook Login Class is:
package com.saddan.facebook_login_mvc;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.AccessTokenTracker;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
public class FacebookLogin
{
private LoginButton loginButton;
private Context context;
private CallbackManager callbackManager;
public FacebookLogin(LoginButton loginButton, Context context)
{
this.loginButton = loginButton;
this.context = context;
}
public void facebookLogin()
{
callbackManager = CallbackManager.Factory.create();
loginButton.setPermissions(Arrays.asList("email","public_profile","user_friends"));
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>()
{
@Override
public void onSuccess(LoginResult loginResult)
{
Toast.makeText(context, "Login successfull", Toast.LENGTH_SHORT).show();
}
@Override
public void onCancel()
{
Toast.makeText(context, "cancel", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(FacebookException error)
{
Toast.makeText(context, "error log", Toast.LENGTH_SHORT).show();
}
});
}
public void onActivityResultFB(int requestCode, int resultCode, Intent data)
{
callbackManager.onActivityResult(requestCode, resultCode,data) ;
}
AccessTokenTracker accessTokenTracker=new AccessTokenTracker() {
@Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken)
{
if(currentAccessToken==null)
{
Toast.makeText(context,"User Logged out",Toast.LENGTH_LONG).show();
}
else
loadUserProfile(currentAccessToken);
}
};
private void loadUserProfile(AccessToken newAccessToken)
{
GraphRequest request = GraphRequest.newMeRequest(newAccessToken, new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(JSONObject object, GraphResponse response)
{
try {
String first_name = object.getString("first_name");
String last_name = object.getString("last_name");
String email = object.getString("email");
String id = object.getString("id");
String image_url = "https://graph.facebook.com/"+id+ "/picture?type=normal";
Log.d("Name", first_name+" "+last_name);
Log.d("email", email);
Log.d("image", image_url);
} catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(context, "exception", Toast.LENGTH_SHORT).show();
Log.d("Error_fb","fb"+e.getMessage());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields","first_name,last_name,email,id");
request.setParameters(parameters);
request.executeAsync();
}
public void checkLoginStatus()
{
if(AccessToken.getCurrentAccessToken()!=null)
{
loadUserProfile(AccessToken.getCurrentAccessToken());
}
}
}
One thing you really need to concentrate is onActivityResult method, which you can't use to any normal class,see my MainActivity and my Facebook login class how I override onActivityResult for facebook login.
If you are useing Fragment instead of Activity you can initialize like this
loginButton.setFragment(this);
Login=new FacebookLogin(loginButton,getActivity());
来源:https://stackoverflow.com/questions/41763702/android-facebook-login-in-non-activity-class