前言

海外版app集成三方登录分享,早期采用umeng sdk,由于googleplay对用户隐私及用户数据的使用有比较严格规定。正好 umeng sdk会后台采集app信息,触发用户隐私相关政策条款。结果就是google play对上架的app下架处理。为了彻底解决不得已移除umeng sdk登录分享组件,采用官方Sdk,进行集成。

如何解决被 google play 下架应用重新上架问题:

Android 集成原生google,facebook 登录分享sdk_ide

1.官方解决方案

联系客服,根据 google官方提供的解决方案,在app用户隐私协议中添加对用户数据如何合理使用的解释条款。重新上架提交审核。原以为问题得以解决。正常了一个版本,紧跟着就拒绝上架了。
拒绝原因: umeng share存在获取用户数据情况

Android 集成原生google,facebook 登录分享sdk_facebook_02


2.彻底解决

移除app中所有与umeng关联的代码包括 [统计,分享,登录]等,虽然时间成本高。能彻底解决。

步骤

2.1 移除jar,sdk 依赖,初始化代码。

2.2 集成sdk

下面采用sdk登录方式,如果对 使用 FirebaseUI 向 Android 应用轻松添加登录机制感兴趣,查看引用部分。

帮助文档入口

​facebook 登录 入口​​​​facebook 分享入口​​​​google sdk 入口​

代码示例

facebook

class LoginWithFacebookUtils(val context: Activity) {

var callbackManager: CallbackManager? = null
//使用fiebase进行获取需要设置
//var callbackCredentials: ((AuthCredential) -> Unit)? = null

init {
callbackManager = CallbackManager.Factory.create()
// registerCallback()
}

private fun registerCallback(facebookCallback: FacebookCallback<LoginResult>) {
if (facebookCallback != null) {
LoginManager.getInstance().registerCallback(callbackManager, facebookCallback)
} else {
LoginManager.getInstance().registerCallback(callbackManager, object :
FacebookCallback<LoginResult> {
override fun onSuccess(result: LoginResult) {
// val credentials = FacebookAuthProvider.getCredential(result.accessToken.token)
// callbackCredentials?.invoke(credentials)

}
override fun onCancel() {
println("cancel")
}
override fun onError(error: FacebookException?) {
error?.printStackTrace()
print("${error?.message}")
}
})
}
}

fun startLoginFacebook(facebookCallback: FacebookCallback<LoginResult>) {
isLoginIn()
registerCallback(facebookCallback)
LoginManager.getInstance().logInWithReadPermissions(context, Arrays.asList("public_profile"));


}

fun startLoginFacebook(facebookCallback: SimpleFaceBookCallBack<LoginResult>) {
isLoginIn()
registerCallback(facebookCallback)
LoginManager.getInstance().logInWithReadPermissions(context, Arrays.asList("public_profile"));
}

/**
* 退出登录
*/
fun isLoginIn() {
val accessToken = AccessToken.getCurrentAccessToken()
val isLoggedIn = accessToken != null && !accessToken.isExpired
if (isLoggedIn) {
val loginManager = LoginManager.getInstance()
loginManager.logOut()
}
}

open abstract class SimpleFaceBookCallBack<LoginResult> : FacebookCallback<LoginResult> {
override fun onSuccess(result: LoginResult?) {
print("success")
}

override fun onCancel() {
Log.e("error", "cancel")
}

override fun onError(error: FacebookException?) {
Log.e("error", "$error")
}
}

}

调用入口

public void toFacebookLogin() {
loginWithFacebookUtils = new LoginWithFacebookUtils(this);
//login
loginWithFacebookUtils.startLoginFacebook(new LoginWithFacebookUtils.SimpleFaceBookCallBack<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
thirdUserInfo = new ThirdUserInfo();
// App code
thirdUserInfo.setType("facebook");
thirdUserInfo.setOpenid(loginResult.getAccessToken().getUserId());
UserRequest.makeUserRequest(new GetUserCallback(LoginActivity.this).getCallback());
}

});
}

2.3 facebook 分享
之前接入的是umeng三方分享,分享图文+url方式很方便。例如

友盟分享图文
UMWeb web = new UMWeb(shareUrl);
web.setTitle(title);//标题
web.setThumb(image); //缩略图
web.setDescription(content);//描述
new ShareAction(getActivity())
.setPlatform(share_media)//传入平台
// .withText(mShareDate.content)//分享内容
.withMedia(web)
.setCallback(umShareListener)//回调监听器
.share();

facebook 的分享翻遍了官方sdk文档,没有直接进行图文分享的api,找到一个Html解析分享方式,但是需要web页面添加一些元数据,供facebook抓取。

分享源码

/**
* facebook分享
* 1.如果没有安装facebook 会唤起网页版facebook 进行登录
*
*/
object ShareWithFaceBook {
val TAG = "ShareWithFaceBook"
var callbackManager: CallbackManager? = null

init {
callbackManager = CallbackManager.Factory.create()
}

/**
* 分享链接
*/
fun shareUrl(context: Activity, url: String) {
val content = ShareLinkContent.Builder()
.setContentUrl(Uri.parse(url))
.build()
// 对话框
val shareDialog = ShareDialog(context)
// 分享回调G
shareDialog.registerCallback(callbackManager, object : FacebookCallback<Sharer.Result?> {
override fun onSuccess(result: Sharer.Result?) {
Log.e(TAG, "onSuccess")
}

override fun onCancel() {
Log.e(TAG, "onCancel")
}

override fun onError(error: FacebookException) {
Log.e(TAG, "onError$error")
}
})
shareDialog.show(content)
}

/**
* 分享图片
*/
fun shareImage(context:Activity,imagePath: String) {
val filePath: String = imagePath
val image = BitmapFactory.decodeFile(filePath)
val photo = SharePhoto.Builder()
.setBitmap(image)
.build()
// 对话框
val shareDialog = ShareDialog(context)
val content = SharePhotoContent.Builder()
.addPhoto(photo)
.build()
shareDialog.show(content)
}

fun shareImage(context: Activity, drawable: Int) {
val image = BitmapFactory.decodeResource(context.resources, drawable)
val photo = SharePhoto.Builder()
.setBitmap(image)
.build()
val content = SharePhotoContent.Builder()
.addPhoto(photo)
.build()
// 对话框
val shareDialog = ShareDialog(context)
shareDialog.registerCallback(callbackManager,object : FacebookCallback<Sharer.Result?> {
override fun onSuccess(result: Sharer.Result?) {
Log.e(TAG, "onSuccess")
}

override fun onCancel() {
Log.e(TAG, "onCancel")
}

override fun onError(error: FacebookException) {
Log.e(TAG, "onError$error")
}
})
shareDialog.show(content)
// ShareApi.share(content, object : FacebookCallback<Sharer.Result?> {
// override fun onSuccess(result: Sharer.Result?) {
// Log.e(TAG, "onSuccess")
// }
//
// override fun onCancel() {
// Log.e(TAG, "onCancel")
// }
//
// override fun onError(error: FacebookException) {
// Log.e(TAG, "onError$error")
// }
// })
}

/**
* 分享视频
*/
fun shareVideo(videoUrl: Uri) {
val video = ShareVideo.Builder()
.setLocalUrl(videoUrl)
.build();
val content = ShareVideoContent.Builder()
.setVideo(video)
.build();

}



}

tips:
facebok 分享文案需要分享图片或者url调起facebook 个人主页后填写,fecebook 支持web界面登录,即使本地没有安装facebook,也可以进行facebok登录或者分享。分享api需要装在一个ShareDialog容器中。

val shareDialog = ShareDialog(context)
shareDialog.show(分享内容)

如下图

Android 集成原生google,facebook 登录分享sdk_facebook_03


2.4 google 登录

/**
* google 登录封装
*/
class LoginWithGoogleUtils(val context: Activity) {

private val TAG = "LoginWithGoogle"
private val GOOGLE_SIGN_IN = 9001
private val activity = context
private var googleApiAvailability: GoogleApiAvailability? = null
public var googleSignInClient: GoogleSignInClient? = null

init {
googleApiAvailability = GoogleApiAvailability.getInstance()
googleSignInClient = getGoogleSignInOptions()
}


/**
* google service 是否可用
*/
fun isGoogleServiceAvailable(): Int {
return googleApiAvailability?.isGooglePlayServicesAvailable(context)!!
}

private fun getGoogleSignInOptions(): GoogleSignInClient {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestProfile()
.build()

return GoogleSignIn.getClient(context, gso)
}

fun startLoginGoogle() {
context.startActivityForResult(
googleSignInClient?.signInIntent, GOOGLE_SIGN_IN
)
}

fun startLoginGoogleAfterLoginOut() {
googleSignInClient?.signOut()
context.startActivityForResult(
googleSignInClient?.signInIntent, GOOGLE_SIGN_IN
)
}

fun onActivityResult(requestCode: Int, data: Intent?, callGoogleLoginResult: GoogleLoginResult) {
if (requestCode == GOOGLE_SIGN_IN) {
try {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
handleSignInResult(task, callGoogleLoginResult)
} catch (e: ApiException) {
if (e.statusCode == 7) {
Toast.makeText(activity, "NETWORK_ERROR", Toast.LENGTH_SHORT).show()
Log.e(TAG, e.message)
} else {
Log.e(TAG, e.message)
}
}
}
}


private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>, callGoogleLoginResult: GoogleLoginResult) {
val account = completedTask.getResult(ApiException::class.java)
account?.let { callGoogleLoginResult.callBack(it) }
Log.d(TAG, account.toString())
}

interface GoogleLoginResult {

fun callBack(account: GoogleSignInAccount)
}

}

tips:
google 登录在不翻墙的情况下,登录提示apiExcetpin code ==7 。需要try 一下

2.5 验证

上面方案经过验证可行

引用

​使用 FirebaseUI 向 Android 应用轻松添加登录机制​