我在Facebook开发者发布了一个错误: https://developers.facebook.com/bugs/1598537583730278/
从facebook-android-sdk-4.4.0.zip获取HelloFacebookSample,并使其适应Android Studio。
build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.hellofacebook"
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.facebook.android:facebook-android-sdk:4.4.0'
}
我在HelloFacebookSampleActivity.java中添加了日志,如下所示:
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.example.hellofacebook;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.facebook.*;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.ProfilePictureView;
import com.facebook.share.ShareApi;
import com.facebook.share.Sharer;
import com.facebook.share.model.SharePhoto;
import com.facebook.share.model.SharePhotoContent;
import com.facebook.share.model.ShareLinkContent;
import com.facebook.share.widget.ShareDialog;
import java.util.ArrayList;
import java.util.Arrays;
public class HelloFacebookSampleActivity extends FragmentActivity {
private static final String PERMISSION = "publish_actions";
private static final Location SEATTLE_LOCATION = new Location("") {
{
setLatitude(47.6097);
setLongitude(-122.3331);
}
};
private final String PENDING_ACTION_BUNDLE_KEY =
"com.example.hellofacebook:PendingAction";
private Button postStatusUpdateButton;
private Button postPhotoButton;
private ProfilePictureView profilePictureView;
private TextView greeting;
private PendingAction pendingAction = PendingAction.NONE;
private boolean canPresentShareDialog;
private boolean canPresentShareDialogWithPhotos;
private CallbackManager callbackManager;
private ProfileTracker profileTracker;
private ShareDialog shareDialog;
private FacebookCallback<Sharer.Result> shareCallback = new FacebookCallback<Sharer.Result>() {
@Override
public void onCancel() {
Log.d("HelloFacebook", "Canceled");
}
@Override
public void onError(FacebookException error) {
Log.d("HelloFacebook", String.format("Error: %s", error.toString()));
String title = getString(R.string.error);
String alertMessage = error.getMessage();
showResult(title, alertMessage);
}
@Override
public void onSuccess(Sharer.Result result) {
Log.d("HelloFacebook", "Success!");
if (result.getPostId() != null) {
String title = getString(R.string.success);
String id = result.getPostId();
String alertMessage = getString(R.string.successfully_posted_post, id);
showResult(title, alertMessage);
}
}
private void showResult(String title, String alertMessage) {
new AlertDialog.Builder(HelloFacebookSampleActivity.this)
.setTitle(title)
.setMessage(alertMessage)
.setPositiveButton(R.string.ok, null)
.show();
}
};
private enum PendingAction {
NONE,
POST_PHOTO,
POST_STATUS_UPDATE
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(this.getApplicationContext());
callbackManager = CallbackManager.Factory.create();
Log.e("FACEBOOK SAMPLE", "ON CREATE");
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Log.e("FACEBOOK SAMPLE", "ON SUCCESS");
handlePendingAction();
updateUI();
}
@Override
public void onCancel() {
Log.e("FACEBOOK SAMPLE", "ON CANCEL");
if (pendingAction != PendingAction.NONE) {
showAlert();
pendingAction = PendingAction.NONE;
}
updateUI();
}
@Override
public void onError(FacebookException exception) {
Log.e("FACEBOOK SAMPLE", "ON ERROR");
if (pendingAction != PendingAction.NONE
&& exception instanceof FacebookAuthorizationException) {
showAlert();
pendingAction = PendingAction.NONE;
}
updateUI();
}
private void showAlert() {
new AlertDialog.Builder(HelloFacebookSampleActivity.this)
.setTitle(R.string.cancelled)
.setMessage(R.string.permission_not_granted)
.setPositiveButton(R.string.ok, null)
.show();
}
});
shareDialog = new ShareDialog(this);
shareDialog.registerCallback(
callbackManager,
shareCallback);
if (savedInstanceState != null) {
String name = savedInstanceState.getString(PENDING_ACTION_BUNDLE_KEY);
pendingAction = PendingAction.valueOf(name);
}
setContentView(R.layout.main);
profileTracker = new ProfileTracker() {
@Override
protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
updateUI();
// It's possible that we were waiting for Profile to be populated in order to
// post a status update.
handlePendingAction();
}
};
profilePictureView = (ProfilePictureView) findViewById(R.id.profilePicture);
greeting = (TextView) findViewById(R.id.greeting);
postStatusUpdateButton = (Button) findViewById(R.id.postStatusUpdateButton);
postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickPostStatusUpdate();
}
});
postPhotoButton = (Button) findViewById(R.id.postPhotoButton);
postPhotoButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickPostPhoto();
}
});
// Can we present the share dialog for regular links?
canPresentShareDialog = ShareDialog.canShow(
ShareLinkContent.class);
// Can we present the share dialog for photos?
canPresentShareDialogWithPhotos = ShareDialog.canShow(
SharePhotoContent.class);
}
@Override
protected void onResume() {
super.onResume();
// Call the 'activateApp' method to log an app event for use in analytics and advertising
// reporting. Do so in the onResume methods of the primary Activities that an app may be
// launched into.
AppEventsLogger.activateApp(this);
updateUI();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name());
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onPause() {
super.onPause();
// Call the 'deactivateApp' method to log an app event for use in analytics and advertising
// reporting. Do so in the onPause methods of the primary Activities that an app may be
// launched into.
AppEventsLogger.deactivateApp(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
profileTracker.stopTracking();
}
private void updateUI() {
boolean enableButtons = AccessToken.getCurrentAccessToken() != null;
postStatusUpdateButton.setEnabled(enableButtons || canPresentShareDialog);
postPhotoButton.setEnabled(enableButtons || canPresentShareDialogWithPhotos);
Profile profile = Profile.getCurrentProfile();
if (enableButtons && profile != null) {
profilePictureView.setProfileId(profile.getId());
greeting.setText(getString(R.string.hello_user, profile.getFirstName()));
} else {
profilePictureView.setProfileId(null);
greeting.setText(null);
}
}
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
// These actions may re-set pendingAction if they are still pending, but we assume they
// will succeed.
pendingAction = PendingAction.NONE;
switch (previouslyPendingAction) {
case NONE:
break;
case POST_PHOTO:
postPhoto();
break;
case POST_STATUS_UPDATE:
postStatusUpdate();
break;
}
}
private void onClickPostStatusUpdate() {
performPublish(PendingAction.POST_STATUS_UPDATE, canPresentShareDialog);
}
private void postStatusUpdate() {
Profile profile = Profile.getCurrentProfile();
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentTitle("Hello Facebook")
.setContentDescription(
"The 'Hello Facebook' sample showcases simple Facebook integration")
.setContentUrl(Uri.parse("http://developers.facebook.com/docs/android"))
.build();
if (canPresentShareDialog) {
shareDialog.show(linkContent);
} else if (profile != null && hasPublishPermission()) {
ShareApi.share(linkContent, shareCallback);
} else {
pendingAction = PendingAction.POST_STATUS_UPDATE;
}
}
private void onClickPostPhoto() {
performPublish(PendingAction.POST_PHOTO, canPresentShareDialogWithPhotos);
}
private void postPhoto() {
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.icon);
SharePhoto sharePhoto = new SharePhoto.Builder().setBitmap(image).build();
ArrayList<SharePhoto> photos = new ArrayList<>();
photos.add(sharePhoto);
SharePhotoContent sharePhotoContent =
new SharePhotoContent.Builder().setPhotos(photos).build();
if (canPresentShareDialogWithPhotos) {
shareDialog.show(sharePhotoContent);
} else if (hasPublishPermission()) {
ShareApi.share(sharePhotoContent, shareCallback);
} else {
pendingAction = PendingAction.POST_PHOTO;
// We need to get new permissions, then complete the action when we get called back.
LoginManager.getInstance().logInWithPublishPermissions(
this,
Arrays.asList(PERMISSION));
}
}
private boolean hasPublishPermission() {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
return accessToken != null && accessToken.getPermissions().contains("publish_actions");
}
private void performPublish(PendingAction action, boolean allowNoToken) {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken != null || allowNoToken) {
pendingAction = action;
handlePendingAction();
}
}
}
连接后,facebook活动显示没有错误,但是当我点击取消或ok按钮时,它会返回HelloFacebookSampleActivity但它会触发onCreate()函数。 如http://developer.android.com/reference/android/app/Activity.html中所述,即使活动仍然在活动堆栈中,也可以随时停止和终止活动,在这种情况下,当应用程序返回时,它会触发onCreate()。 结果,回调被重新初始化,并且无法从认证中获得响应。 这个错误发生在LG G2 mini上,而不是三星Galaxy s4。 该应用程序似乎工作正常。
我的当前应用程序遇到了这个问题,即使是逐步执行facebook android sdk教程,我也遇到了与官方示例应用程序相同的问题。
如果我在HelloFacebookSampleActivity中进入手机菜单,然后返回应用程序,则onCreate()不一定会被触发,如果我在重新打开应用程序之前等待足够长的时间,它确实有效。
我希望我做错了。
无论如何,请提前感谢您提供任何帮助。
Android Studio版本:1.2.2
测试电话:带有Android 5.0.2的LG G2 mini,带有Android 5.0.1的Samsung Galaxy S4
SDK版本:4.4.0
答案 0 :(得分:1)
我也面临同样的问题,我通过覆盖onActivityResult
方法找到了解决方案。
将此方法放入我的活动类后,所有回调都将起作用
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
}