一、要实现的功能
Facebook自带的LoginButton,点击授权完成后,登录按钮变成登出按钮,但是不是我想要的功能,因为缓存信息还在,下次登录的时候都不用授权而是直接就进来了,这样想要切换用户都不能。
所以我根据Facebook提供的Demo自定研究了一个适合自己需求的Demo,要求使用自定义的登录按钮进行登录操作并能够及时的清除缓存信息,这样下次进来的时候虽然需要重新登录授权,但是确是达到了切换用户的需求。
图片:
第一次进入应用:
点击按钮
授权完毕:
第二次进入:
二、代码如下:
1.布局文件
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragmentContainer" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="login with facebook" > </Button> </LinearLayout>activity_second.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/userinfo" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
MainActivity.java
点击进入登录授权的界面
/** * Copyright 2010-present Facebook. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.facebook.samples.switchuser; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.view.ContextMenu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.facebook.AppEventsLogger; import com.facebook.Request; import com.facebook.Response; import com.facebook.Session; import com.facebook.SessionLoginBehavior; import com.facebook.SessionState; import com.facebook.SharedPreferencesTokenCachingStrategy; import com.facebook.model.GraphUser; public class MainActivity extends FragmentActivity implements OnClickListener { private static final String TOKEN_CACHE_NAME_KEY = "TokenCacheName"; private Slot currentSlot; private Session session; private Session.StatusCallback sessionStatusCallback; public static final String TAG = "SettingsFragment"; private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sessionStatusCallback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { onSessionStateChange(session, state, exception); } }; SessionLoginBehavior loginBehavior = SessionLoginBehavior.SUPPRESS_SSO; currentSlot = new Slot(this, loginBehavior); if (savedInstanceState != null) { SharedPreferencesTokenCachingStrategy restoredCache = new SharedPreferencesTokenCachingStrategy(this, savedInstanceState.getString(TOKEN_CACHE_NAME_KEY)); session = Session.restoreSession(this, restoredCache, sessionStatusCallback, savedInstanceState); } btn = (Button) this.findViewById(R.id.btn); btn.setOnClickListener(this); } /*** * Fragment的方法,创建上下文菜单的时候调用 */ @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, view, menuInfo); getMenuInflater().inflate(R.menu.context_settings, menu); } /** * 清除Cache的方法 * * @param position */ private void clearCache() { if (currentSlot.getUserId() != null) { currentSlot.clear(); notifySlotChanged(); } } /** * 自定义授权按钮 */ @Override public void onClick(View arg0) { notifySlotChanged(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (currentSlot != null) { outState.putString(TOKEN_CACHE_NAME_KEY, currentSlot.getTokenCacheName()); } Session.saveSession(session, outState); } @Override protected void onResume() { super.onResume(); if (session != null) { session.addCallback(sessionStatusCallback); } // 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); } @Override protected void onPause() { super.onPause(); if (session != null) { session.removeCallback(sessionStatusCallback); } // 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 public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (session != null) { session.onActivityResult(this, requestCode, resultCode, data); } } // 授权后的回调的方法 private void onSessionStateChange(Session session, SessionState state, Exception exception) { if (state.isOpened()) { // Log in just happened. fetchUserInfo(); } else if (state.isClosed()) { // Log out just happened. Update the UI. } } private void fetchUserInfo() { if (session != null && session.isOpened()) { Request request = Request.newMeRequest(session, new Request.GraphUserCallback() { @Override public void onCompleted(GraphUser user, Response response) { if (response.getRequest().getSession() == session) { if (user != null) { Slot s = currentSlot; if (s != null) { s.update(user); Intent intent = new Intent(MainActivity.this, SecondActivity.class); intent.putExtra("userinfo", "id:" + s.getUserId() + ",username" + s.getUserName() + ",gender" + s.getGender()); s.clear(); startActivity(intent); } } } } }); request.executeAsync(); } } private void handleSlotChange(Slot newSlot) { if (session != null) { session.close(); session = null; } // 对用户进行授权操作,缓存信息保存到Session中 if (newSlot != null) { session = new Session.Builder(this).setTokenCachingStrategy(newSlot.getTokenCache()).build(); session.addCallback(sessionStatusCallback); Session.OpenRequest openRequest = new Session.OpenRequest(this); openRequest.setLoginBehavior(newSlot.getLoginBehavior()); openRequest.setRequestCode(Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE); session.openForRead(openRequest); } } private void notifySlotChanged() { handleSlotChange(currentSlot); } }
管理用户授权信息以及缓存信息的类
/** * Copyright 2010-present Facebook. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.facebook.samples.switchuser; import org.json.JSONException; import android.content.Context; import android.os.Bundle; import com.facebook.SessionLoginBehavior; import com.facebook.SharedPreferencesTokenCachingStrategy; import com.facebook.model.GraphUser; public class Slot { private static final String CACHE_NAME_FORMAT = "TokenCache%d"; private static final String CACHE_USER_ID_KEY = "SwitchUserSampleUserId"; private static final String CACHE_USER_NAME_KEY = "SwitchUserSampleUserName"; private String tokenCacheName; private String userName; private String userId; private String gender; private SharedPreferencesTokenCachingStrategy tokenCache; private SessionLoginBehavior loginBehavior; /** * 有参构造器 * * @param context * @param slotNumber * @param loginBehavior */ public Slot(Context context, SessionLoginBehavior loginBehavior) { this.loginBehavior = loginBehavior; this.tokenCacheName = String.format(CACHE_NAME_FORMAT,1); this.tokenCache = new SharedPreferencesTokenCachingStrategy(context, tokenCacheName); restore(); } /***** Get方法 ****/ public String getTokenCacheName() { return tokenCacheName; } public String getUserName() { return userName; } public String getUserId() { return userId; } public String getGender() { return gender; } public SessionLoginBehavior getLoginBehavior() { return loginBehavior; } public SharedPreferencesTokenCachingStrategy getTokenCache() { return tokenCache; } /** * 对外提供的方法 如果用户为空,直接返回 如果用户不为空,取出用户信息,并保存到本地 * * @param user */ public void update(GraphUser user) { if (user == null) { return; } userId = user.getId(); userName = user.getName(); try { gender = user.getInnerJSONObject().getString("gender"); } catch (JSONException e) { e.printStackTrace(); } Bundle userInfo = tokenCache.load(); userInfo.putString(CACHE_USER_ID_KEY, userId); userInfo.putString(CACHE_USER_NAME_KEY, userName); tokenCache.save(userInfo); } /** * 对外提供的方法 用于清除用户缓存信息,并同步将用户信息置为空 */ public void clear() { tokenCache.clear(); restore(); } /** * 取出缓存的用户信息的方法 */ private void restore() { Bundle userInfo = tokenCache.load(); userId = userInfo.getString(CACHE_USER_ID_KEY); userName = userInfo.getString(CACHE_USER_NAME_KEY); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.facebook.samples.switchuser" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="11" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:icon="@drawable/icon" android:label="@string/app_name" > <activity android:name="com.facebook.samples.switchuser.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.facebook.samples.switchuser.SecondActivity" > </activity> <activity android:name="com.facebook.LoginActivity" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id" /> </application> </manifest>
(感谢分享)