前言
海外版app內建三方登入分享,早期采用umeng sdk,由于googleplay對使用者隐私及使用者資料的使用有比較嚴格規定。正好 umeng sdk會背景采集app資訊,觸發使用者隐私相關政策條款。結果就是google play對上架的app下架處理。為了徹底解決不得已移除umeng sdk登入分享元件,采用官方Sdk,進行內建。
如何解決被 google play 下架應用重新上架問題:
1.官方解決方案
聯系客服,根據 google官方提供的解決方案,在app使用者隐私協定中添加對使用者資料如何合理使用的解釋條款。重新上架送出稽核。原以為問題得以解決。正常了一個版本,緊跟着就拒絕上架了。
拒絕原因: umeng share存在擷取使用者資料情況
2.徹底解決
移除app中所有與umeng關聯的代碼包括 [統計,分享,登入]等,雖然時間成本高。能徹底解決。
步驟
2.1 移除jar,sdk 依賴,初始化代碼。
2.2 內建sdk
下面采用sdk登入方式,如果對 使用 FirebaseUI 向 Android 應用輕松添加登入機制感興趣,檢視引用部分。
幫助文檔入口
facebook 登入 入口facebook 分享入口google sdk 入口
代碼示例
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(分享内容)
如下圖
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 驗證
上面方案經過驗證可行