授权登录功能的实现主要是通过智汀云盘App发起一个携带要获取权限参数的意图去启动智汀App,智汀App根据权限参数获取相应的授权信息(包括家庭信息、用户信息和登录凭证)并通过广播发送消息,智汀云盘接收到广播消息之后进行保存授权信息和登录操作,当然进入智汀App之后的那个家庭,必须是有绑定SA的家庭。
1) 智汀云盘主要代码实现:
/**
* 登录界面
*/
public class LoginActivity extends BaseMVPDBActivity implements LoginContract.View {
private String mUri = "zt://com.yctc.zhiting/sign?type=1&user_package_name=com.yctc.zhiting"; // 启动智汀App地址
private MyBroadcastReceiver mReceiver; // 授权登录广播
...
@Override
protected void initData() {
super.initData();
//注册广播接受者,接收授权成功返回广播信息
mReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//zt.com.yctc.zhiting.sign 自行定义action 即可
intentFilter.addAction("zt.com.yctc.zhiting.sign");
registerReceiver(mReceiver, intentFilter);
if (!TextUtils.isEmpty(SpUtil.getString("loginInfo"))){
toMain(SpUtil.getString("loginInfo"), false);
}
}
...
/**
* 点击事件
*/
public class OnClickHandler{
public void onClick(View view){
int viewId = view.getId();
if (viewId == R.id.tvLogin){ // 登录
if (AppUtil.isMobile_spExist(CDApplication.getContext(), "com.yctc.zhiting")) { // 已安装智汀,执行授权登录
LogUtil.d("=================登录============");
Intent intent = new Intent();
intent.setData(Uri.parse(mUri));//参数拼接在URI后面 type=1是授权页面,user_package_name使用者包名,后续参数可自行添加
intent.putExtra("needPermissions", "user,area");//这里Intent也可传递参数,但是一般情况下都会放到上面的URL中进行传递
intent.putExtra("appName", UiUtil.getString(R.string.to_third_party_name));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}else { // 未安装智汀,提示用户安装
ToastUtil.show(getResources().getString(R.string.main_please_install_zhiting));
}
}
}
}
/**
* 接收授权登录广播
*/
private class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 授权成功之后返回的信息
String backInfo = intent.getStringExtra("backInfo");
SpUtil.put("loginInfo", backInfo);
toMain(backInfo, true);
}
}
/**
* 去主界面
* @param json
*/
private void toMain(String json, boolean delay){
Constant.authBackBean = GsonConverter.getGson().fromJson(json, AuthBackBean.class); // 授权信息
if (Constant.authBackBean!=null) {
HomeCompanyBean homeCompanyBean = Constant.authBackBean.getHomeCompanyBean(); // 家庭
if (homeCompanyBean!=null) {
String url = homeCompanyBean.getSa_lan_address();
if (!TextUtils.isEmpty(url)) {
HttpConfig.baseUrl = homeCompanyBean.getSa_lan_address();
HttpConfig.baseTestUrl = homeCompanyBean.getSa_lan_address();
HttpConfig.uploadFileUrl = HttpConfig.baseTestUrl+HttpConfig.uploadFileUrl;
HttpConfig.downLoadFileUrl = HttpConfig.baseTestUrl+HttpConfig.downLoadFileUrl;
HttpConfig.downLoadFolderUrl1 = HttpConfig.baseTestUrl+HttpConfig.downLoadFolderUrl1;
HttpConfig.downLoadFolderUrl2 = HttpConfig.baseTestUrl+HttpConfig.downLoadFolderUrl2;
}
Constant.HOME_NAME = homeCompanyBean.getName();
}
Constant.cookies = Constant.authBackBean.getCookies();
Constant.scope_token = Constant.authBackBean.getStBean().getToken(); // scopeToken
Constant.USER_ID = Constant.authBackBean.getUserId(); // 用户 id
Constant.userName = Constant.authBackBean.getUserName(); // 用户名称
if (delay) { // 是否需要延时, 主要解决oppo没有跳转到主界面,直接到桌面的问题
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
switchToActivity(MainActivity.class);
finish();
}
}
}
2) 智汀主要代码实现:
/**
* 启动页
*/
public class SplashActivity extends BaseActivity {
...
/**
* 1 授权登录
*/
private String type;
/**
* 第三方应用需要的权限
*/
private String needPermissions;
/**
* 第三方app的名称
*/
private String appName;
...
@Override
protected void initIntent(Intent intent) {
super.initIntent(intent);
Uri uri = intent.getData();
if (uri != null) {
type = uri.getQueryParameter("type");
}
needPermissions = intent.getStringExtra("needPermissions");
appName = intent.getStringExtra("appName");
if (type!=null && type.equals("1") && CurrentHome!=null){ // 如果是授权过来且当前家庭不为空,直接调整授权界面
Bundle bundle = new Bundle();
bundle.putString(IntentConstant.NEED_PERMISSION, needPermissions);
bundle.putString(IntentConstant.APP_NAME, appName);
// 如果type不为空且为1的情况下到授权界面,否则直接到主界面
switchToActivity(AuthorizeActivity.class, bundle);
finish();
}else { // 否则,正常流程
checkPermissionTask();
}
}
...
/**
* 去到主界面/授权界面
*/
private void toMain() {
UiUtil.starThread(() -> {
List homeList = dbManager.queryHomeCompanyList();
if (CollectionUtil.isNotEmpty(homeList)){
CurrentHome = homeList.get(0);
UiUtil.runInMainThread(() -> {
if (wifiInfo != null) {
for (HomeCompanyBean home : homeList) {
if (HomeFragment.homeLocalId > 0){ // 之前打开过,没退出,按Home键之前的那个家庭
if (home.getLocalId() == HomeFragment.homeLocalId){
CurrentHome = home;
break;
}
}
if (home.getMac_address() != null && home.getMac_address().
equalsIgnoreCase(wifiInfo.getBSSID()) && home.isIs_bind_sa()) { // 当前sa环境
CurrentHome = home;
break;
}
}
}
UiUtil.postDelayed(() -> {
Bundle bundle = new Bundle();
bundle.putString(IntentConstant.TYPE, type);
bundle.putString(IntentConstant.NEED_PERMISSION, needPermissions);
bundle.putString(IntentConstant.APP_NAME, appName);
// 如果type不为空且为1的情况下到授权界面,否则直接到主界面
switchToActivity(type!=null && type.equals("1") ? AuthorizeActivity.class : MainActivity.class, bundle);
finish();
}, 1500);
});
}
});
}
...
/**
* 授权界面
*/
public class AuthorizeActivity extends MVPBaseActivity implements AuthorizeContract.View {
@BindView(R.id.tvName)
TextView tvName;
@BindView(R.id.tvJoin)
TextView tvJoin;
@BindView(R.id.rvScopes)
RecyclerView rvScopes;
@BindView(R.id.tvTips)
TextView tvTips;
/**
* 第三方应用需要的权限
*/
private String needPermissions;
/**
* 第三方app的名称
*/
private String appName;
private ScopesAdapter scopesAdapter;
private Handler mainThreadHandler;
private DBManager dbManager;
private WeakReference mContext;
private int userId;
private String userName; // 用户名称
private String[] permissions; // 同意授权的信息
...
@Override
protected void initData() {
super.initData();
mContext = new WeakReference<>(getActivity());
dbManager = DBManager.getInstance(mContext.get());
mainThreadHandler = new Handler(Looper.getMainLooper());
getUserInfo();
permissions = needPermissions.split(",");
// 同意授权的信息数据
List data = new ArrayList<>();
if (permissions.length>0){
for (int i=0; i scopes = new ArrayList<>();
for (String permission : permissions){
scopes.add(permission);
}
ScopeTokenRequest scopeTokenRequest = new ScopeTokenRequest(scopes);
// 获取token接口
mPresenter.getScopeToken(scopeTokenRequest.toString());
}
}
/**
* 获取 SCOPE 列表成功
* @param scopesBean
*/
@Override
public void getScopesSuccess(ScopesBean scopesBean) {
if (scopesBean!=null){
if (CollectionUtil.isNotEmpty(scopesBean.getScopes())){
List data = new ArrayList<>();
if (!TextUtils.isEmpty(needPermissions)) {
for (ScopesBean.ScopeBean scopeBean : scopesBean.getScopes()) {
for (String permission : permissions){
if (scopeBean.getName().equals(permission)){
data.add(scopeBean);
}
}
}
scopesAdapter.setNewData(data);
}
}
}
}
@Override
public void getScopesFail(int errorCode, String msg) {
ToastUtil.show(msg);
}
/**
* 获取 SCOPE Token成功
* @param scopeTokenBean
*/
@Override
public void getScopeTokenSuccess(ScopeTokenBean scopeTokenBean) {
if (scopeTokenBean!=null){
ScopeTokenBean.STBean stBean = scopeTokenBean.getScope_token();
if (stBean!=null){
Intent intent = new Intent();
AuthBackBean authBackBean = new AuthBackBean(Constant.CurrentHome.getUser_id(), userName, Constant.CurrentHome, stBean);
if (UserUtils.isLogin()){
authBackBean.setCookies(PersistentCookieStore.getInstance().get(HttpUrl.parse(HttpUrlConfig.getLogin())));
}else {
authBackBean.setCookies(new ArrayList<>());
}
intent.setAction("zt.com.yctc.zhiting.sign");
intent.putExtra("backInfo", authBackBean.toString());
sendBroadcast(intent);
LibLoader.finishAllActivity();
}else {
ToastUtil.show(UiUtil.getString(R.string.main_login_fail));
}
}else {
ToastUtil.show(UiUtil.getString(R.string.main_login_fail));
}
}
@Override
public void getScopeTokenFail(int errorCode, String msg) {
ToastUtil.show(msg);
}
...
}
3) 还有最重要的一点是需要在智汀的清单文件为其他App/浏览器提供入口:
4) 授权信息类:
/**
* 授权信息类
*/
public class AuthBackBean extends Request {
private int userId; // 用户id
private String userName; // 用户昵称
private HomeCompanyBean homeCompanyBean; // 家庭信息
private ScopeTokenBean.STBean stBean; // 授权token和过期时间
private List cookies; // 登录SC时的cookie
...
}
public class HomeCompanyBean {
private int id;//云端家庭id
private int roomAreaCount;//房间个数
private int location_count; // 房间数量
private int role_count; // 角色数量
private int user_count; // 成员数量
@SerializedName("sa_user_id")
private int user_id; // sa用户id
private boolean is_bind_sa; //是否绑定sa
private boolean selected; // 标识是否被选中
private String name;//家庭名称
private String sa_lan_address; // sa地址
private String sa_user_token; // sa token
private String ss_id;//wifi id
private String mac_address;//wifi地址
...
}
public class ScopeTokenBean {
/**
* scope_token : {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjgyNDc2NzgsInNhX2lkIjoidGVzdC1zYS10ZXN0Iiwic2NvcGVzIjoidXNlcixhcmVhIiwidWlkIjozfQ.HM_pLMTYw_Yzz4kWQIERWU9FnmP6SM_ejV1M0GMXbAc","expires_in":2592000}
*/
private STBean scope_token;
...
public static class STBean {
/**
* token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjgyNDc2NzgsInNhX2lkIjoidGVzdC1zYS10ZXN0Iiwic2NvcGVzIjoidXNlcixhcmVhIiwidWlkIjozfQ.HM_pLMTYw_Yzz4kWQIERWU9FnmP6SM_ejV1M0GMXbAc
* expires_in : 2592000
*/
private String token;
private int expires_in; // 有效期,单位为秒
...
}
}
如果你对本文有任何疑问或者高见,关注智汀公众号共同交流探讨(欢迎加入微信号:13326423643可以免费赠送“智能开关或其他智能硬件”哦)。
ZHITING
微信扫码二维码,关注我的公众号