Bon*_*oni 4 android facebook android-jetpack-compose
我开始开发一个 100% 使用 Jetpack compose 编写的新项目,这意味着我们没有任何片段,而且我们也遵循单一活动模式。
现在我必须实现 Facebook 登录,但我陷入困境,因为他们仍在使用已弃用的 onActivityResult 而不是新的合约 api。
这是我试图遵循的文档,任何帮助将不胜感激。
谢谢你们,
试试这个它会起作用:
val callbackManager = CallbackManager.Factory.create()
val loginManager = LoginManager.getInstance()
val context = LocalContext.current
loginManager.logIn(
context as ActivityResultRegistryOwner,
callbackManager,
listOf("email")
)
loginManager.registerCallback(
callbackManager,
object : FacebookCallback<LoginResult?> {
override fun onCancel() {
TODO("onCancel")
}
override fun onError(error: FacebookException) {
TODO("onError")
}
override fun onSuccess(result: LoginResult?) {
TODO("onSuccess")
}
})
Run Code Online (Sandbox Code Playgroud)
您必须等待这个问题得到解决。
现在,您可以callbackManager使用 从 Activity 传递到 Compose 树CompositionLocalProvider,如下所示:
val LocalFacebookCallbackManager =
staticCompositionLocalOf<CallbackManager> { error("No CallbackManager provided") }
class MainActivity : FragmentActivity() {
private var callbackManager = CallbackManager.Factory.create();
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Theme {
CompositionLocalProvider(
LocalFacebookCallbackManager provides callbackManager
) {
LoginScreen()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
callbackManager.onActivityResult(requestCode, resultCode, data)
super.onActivityResult(requestCode, resultCode, data)
}
}
@Composable
fun LoginScreen() {
val callbackManager = LocalFacebookCallbackManager.current
DisposableEffect(Unit) {
LoginManager.getInstance().registerCallback(
callbackManager,
object : FacebookCallback<LoginResult> {
override fun onSuccess(loginResult: LoginResult) {
println("onSuccess $loginResult")
}
override fun onCancel() {
println("onCancel")
}
override fun onError(exception: FacebookException) {
println("onError $exception")
}
}
)
onDispose {
LoginManager.getInstance().unregisterCallback(callbackManager)
}
}
val context = LocalContext.current
Button(onClick = {
LoginManager.getInstance()
.logInWithReadPermissions(context.findActivity(), Arrays.asList("public_profile"));
}) {
Text("FB Login")
}
}
fun Context.findActivity(): Activity? = when (this) {
is Activity -> this
is ContextWrapper -> baseContext.findActivity()
else -> null
}
Run Code Online (Sandbox Code Playgroud)
更通用的解决方案是将 facebook 逻辑移至视图模式,然后传递,然后您必须创建自己的回调管理器,如下所示:
ActivityResultCallbackManager.kt
val LocalActivityResultCallbackManager =
staticCompositionLocalOf<ActivityResultCallbackManager> { error("No ActivityResultCallbackManager provided") }
interface ActivityResultCallbackI {
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean
}
class ActivityResultCallbackManager {
private val listeners = mutableListOf<ActivityResultCallbackI>()
fun addListener(listener : ActivityResultCallbackI) {
listeners.add(listener)
}
fun removeListener(listener : ActivityResultCallbackI) {
listeners.remove(listener)
}
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) : Boolean =
listeners.any { it.onActivityResult(requestCode, resultCode, data) }
}
Run Code Online (Sandbox Code Playgroud)
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var callbackManager = ActivityResultCallbackManager()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
Theme {
CompositionLocalProvider(
LocalActivityResultCallbackManager provides callbackManager
) {
LoginScreen()
}
}
}
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
if (!callbackManager.onActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data)
}
}
}
Run Code Online (Sandbox Code Playgroud)
FacebookLoginViewModel.kt
class FacebookLoginViewModel : ViewModel(), ActivityResultCallbackI {
sealed class LoginState {
object Initial: LoginState()
object Processing: LoginState()
data class Success(val loginResult: LoginResult): LoginState()
data class Error(val exception: FacebookException): LoginState()
}
private var callbackManager = CallbackManager.Factory.create()
var state by mutableStateOf<LoginState>(LoginState.Initial)
private set
init {
LoginManager.getInstance().registerCallback(
callbackManager,
object : FacebookCallback<LoginResult> {
override fun onSuccess(loginResult: LoginResult) {
state = LoginState.Success(loginResult)
}
override fun onCancel() {
state = LoginState.Initial
}
override fun onError(exception: FacebookException) {
state = LoginState.Error(exception)
}
}
)
}
override fun onCleared() {
super.onCleared()
LoginManager.getInstance().unregisterCallback(callbackManager)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean =
callbackManager.onActivityResult(requestCode, resultCode, data)
fun login(context: Context) {
state = LoginState.Processing
LoginManager.getInstance()
.logInWithReadPermissions(context.findActivity(), Arrays.asList("public_profile"));
}
}
Run Code Online (Sandbox Code Playgroud)
LoginScreen.kt
@Composable
fun LoginScreen() {
val viewModel: FacebookLoginViewModel = viewModel()
val callbackManager = LocalActivityResultCallbackManager.current
DisposableEffect(Unit) {
callbackManager.addListener(viewModel)
onDispose {
callbackManager.removeListener(viewModel)
}
}
val context = LocalContext.current
Column {
Text(viewModel.state.toString())
Button(onClick = {
viewModel.login(context)
}) {
Text("FB Login")
}
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以尝试构建此分支,它包含此拉取请求的更改。它增加了合约API的支持,但尚未被接受。仔细检查更改,这不是官方的!
| 归档时间: |
|
| 查看次数: |
4716 次 |
| 最近记录: |