Android FB API 3.0 - установить разрешения только один раз
Я пытаюсь понять, как работает новый API, поэтому мне удалось понять концепцию и удалось сделать свой собственный "мир привет", который входит в систему на facebook, выходит из системы и пытается загрузить изображение.
Теперь как в HelloFacebookSample, так и в SessionLoginSimple есть простой вход в facebook, а в HelloFacebookSample, когда вы нажимаете "Опубликовать фотографию", появляется новое диалоговое окно для входа в систему, поскольку разрешения не установлены.
это код из HelloFacebookSample:
private void performPublish(PendingAction action) {
Session session = Session.getActiveSession();
if (session != null) {
pendingAction = action;
if (session.getPermissions().contains("publish_actions")) {
// We can do the action right away.
handlePendingAction();
} else {
// We need to reauthorize, then complete the action when we get called back.
Session.ReauthorizeRequest reauthRequest = new Session.ReauthorizeRequest(this, PERMISSIONS).
setRequestCode(REAUTHORIZE_ACTIVITY).
setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
session.reauthorizeForPublish(reauthRequest);
}
}
}
Так как у нас нет "publish_actions", нам нужно повторно авторизовать.
В журнале SimpleSessionLogin выглядит так:
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
} else {
Session.openActiveSession(this, true, statusCallback);
}
}
Итак, я не могу понять, как запрашивать разрешения при входе в систему. Это вроде странно или сказать лишний, чтобы войти в службу дважды за пару секунд с точно таким же диалогом.
Звучит для пользователя, что что-то не так или странно.
Я хочу войти в facebook один раз с требуемыми разрешениями, но используя сеансы сеанса API 3.0, а не устаревшие.
Может кто-нибудь объяснить, как?
Ответы
Ответ 1
Session.OpenRequest имеет метод, позволяющий устанавливать разрешения. Однако с 3.0 SDK Facebook теперь просит, чтобы разработчики запрашивали "чтение" и "публикацию" разрешений отдельно. Поэтому, если вашему приложению нужно как читать информацию о пользователе, так и публиковать от их имени, вам нужно будет переадресовать вызов.
Ответ 2
Итак, вот фрагмент диалога, который я создал, который использует Facebook 3.0 SDK для Android. Он инкапсулирован, что означает, что все функции Facebook содержатся в фрагменте. Это фрагмент диалогового окна, поэтому он появляется поверх вашей текущей активности. Этот фрагмент позволяет вам войти в систему, а затем включить определенные виды, как только вы вошли в систему, используя класс UiHelper, включенный в Facebook.
public class FFragment extends DialogFragment {
private static final String TAG = "FacebookFragment";
private UiLifecycleHelper uiHelper;
private String mFilePath;
private Button shareButton, cancelButton;
private EditText mMessageText;
private TextView mMessageTitle;
private ProgressBar pBar;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.facebook_login, container, false);
LoginButton authButton = (LoginButton) view
.findViewById(R.id.authButton);
authButton.setFragment(this);
authButton.setPublishPermissions(Arrays.asList("publish_stream"));
shareButton = (Button) view.findViewById(R.id.shareButton);
mMessageText = (EditText) view.findViewById(R.id.facebook_post_text);
mMessageTitle = (TextView) view.findViewById(R.id.facebook_post_title);
cancelButton = (Button) view.findViewById(R.id.cancelButton);
pBar = (ProgressBar) view.findViewById(R.id.facebook_pbar);
cancelButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
FFragment.this.dismiss();
}
});
shareButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
publishPhoto();
}
});
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFilePath = getArguments().getString("file_path");
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}
/**
* After user selects to upload photo
*/
private void publishPhoto() {
pBar.setVisibility(View.VISIBLE);
GraphObject graphObject;
Bitmap bmap = BitmapFactory.decodeFile(mFilePath);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
Bundle params = new Bundle();
params.putByteArray("picture", byteArray);
params.putString("message", mMessageText.getText() + " " +
getActivity().getResources().getString("String goes here"));
Request request = new Request(Session.getActiveSession(), "me/photos",params,
HttpMethod.POST);
request.setCallback(new Request.Callback() {
@Override
public void onCompleted(Response response) {
if (response.getError()==null) {
Toast.makeText(getActivity(), "Successfully posted photo", Toast.LENGTH_SHORT).show();
FlurryAgent.logEvent(Globals.EVENT_FACEBOOK);
} else {
Toast.makeText(getActivity(), response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
}
pBar.setVisibility(View.GONE);
FFragment.this.dismiss();
}
});
request.executeAsync();
}
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
// Check for reading user_photos permission
shareButton.setVisibility(View.VISIBLE);
mMessageText.setVisibility(View.VISIBLE);
mMessageTitle.setVisibility(View.VISIBLE);
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
shareButton.setVisibility(View.GONE);
mMessageText.setVisibility(View.GONE);
mMessageTitle.setVisibility(View.GONE);
}
}
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
@Override
public void onResume() {
super.onResume();
uiHelper.onResume();
// For scenarios where the main activity is launched and user
// session is not null, the session state change notification
// may not be triggered. Trigger it if it open/closed.
Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed())) {
onSessionStateChange(session, session.getState(), null);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
}
Следующие строки кода - это то, что вы использовали бы в своей деятельности, чтобы показать диалог.
FFragment mFacebookFragment = new FFragment();
Bundle args = new Bundle();
args.putString("file_path", mFilePath);
mFacebookFragment.setArguments(args);
mFacebookFragment.show(getSupportFragmentManager(), "tag");
Во всяком случае, если вы посмотрите на onCreate, мы устанавливаем разрешения публикации. По умолчанию разрешения на чтение уже устанавливаются при запуске фрагмента.
Также сделайте это у вас в манифесте.
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>
Где @string/app_id - это идентификатор приложения, который вы создали при создании приложения facbeook на сайте разработчиков.
Также обязательно загрузите новый проект sdk facebook и укажите его как проект библиотеки.
Файл XML для размещения диалогового окна.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<com.facebook.widget.LoginButton
android:id="@+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_gravity="center_horizontal|top" />
<TextView
android:id="@+id/facebook_post_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Message to post with photo"
android:textColor="@android:color/white"
android:textSize="18dp"
android:textStyle="bold"
android:visibility="gone" />
<EditText
android:id="@+id/facebook_post_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minLines="3"
android:visibility="gone" />
<Button
android:id="@+id/shareButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center"
android:text="Post"
android:textStyle="bold"
android:visibility="gone" />
<Button
android:id="@+id/cancelButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Cancel"
android:textStyle="bold" />
</LinearLayout>
<ProgressBar
android:id="@+id/facebook_pbar"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:visibility="gone"
/>
Ответ 3
При авторизации/входе в приложение в первый раз вы можете запрашивать разрешения на чтение. Раньше я тоже тестировал этот новый SDK и был немного смущен.
Facebook хочет, чтобы пользователь был более уверен в своих способностях публикации в приложениях, сделав так, что вам нужно повторно авторизовать публикацию разрешений при первой попытке опубликовать действие OG. Если вы посмотрите на то, как Foursquare или Instagram публикует OG, у них есть флажок или кнопка Facebook, чтобы указать, что вы хотите разделить действие с FB. Вы можете реализовать что-то похожее на то, что я закончил делать, это отобразить кнопку после того, как пользователь разрешил приложение, которое просит их нажать, чтобы включить публикацию действий в Facebook.
Ответ 4
Facebook 3.0 api действительно ограничивается тем, что он не может одновременно читать и публиковать. Однако я нашел обходное решение, но вам нужно изменить библиотеку.
Просто добавьте это в Session.java:
public final void openForReadAndPublish(OpenRequest openRequest) {
open(openRequest, null);
}
Это приведет к пропуску проверок проверки, которые генерируют исключения. Конечно, теперь вам, возможно, понадобится сделать все более ручным. Вы также можете просто прокомментировать вызовы validatePermissions (openRequest, authType) в сеансе, и это должно сделать так, чтобы вы могли передавать любые разрешения, которые вы хотите.
Ответ 5
@Ming Li, Когда я создал сеанс, используя
public static final List<String> ALL_PERMISSIONS = Arrays.asList(
"read_friendlists",
"publish_stream",
"offline_access",
"email",
"read_stream",
"user_location" );
session.openForPublish(new Session.OpenRequest(this).setPermissions(ALL_PERMISSIONS).setCallback(statusCallback).setRequestCode(100));
Полученный сеанс имеет как разрешения (читать, так и публиковать). Поэтому я чувствую, что пользователи, которые хотят получить сеанс с чтением и публикацией, могут использовать openForPublish() api. Он работает...!!