Cannot login facebook from menuItem (Android Studio Kotlin) - kotlin

I can't log in to Facebook from the menu item, but I can log out from a menu item. Only the Facebook login button can log in.
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId){
R.id.login -> {
if (AccessToken.getCurrentAccessToken() != null) {
GraphRequest(
AccessToken.getCurrentAccessToken(), "/me/permissions/", null, HttpMethod.DELETE,
GraphRequest.Callback {
AccessToken.setCurrentAccessToken(null)
LoginManager.getInstance().logOut()
}
).executeAsync()
}
else
{
LoginManager.getInstance().logInWithReadPermissions(this, listOf("public_profile"))
}
true
}
else -> super.onOptionsItemSelected(item)
}
}

Related

How to navigate back to the correct one screen before the previous in jetpack compose?

I have four compose screens and by clicking on their items user leads to my AdShowScreen then after watching the ad they lead to the FinalShow screen. like the image below
Now I want to navigate correctly back from finalShowScreen to one of the four compose screens that came from by overriding the back press button in FinalShowScreen.
This is my navGraph.
#SuppressLint("UnrememberedMutableState")
#Composable
fun MyNavGraph(
navController: NavHostController) {
val actions = remember(navController) { MainActions(navController) }
NavHost(
navController = navController,
startDestination = BottomNavItems.First.route
) {
composable(BottomNavItems.First.route) {
FirstScreen(actions)
}
composable(BottomNavItems.Second.route) {
SecondScreen(navController, actions)
}
composable(BottomNavItems.Third.route) {
ThirdScreen()
}
composable(Screens.Fourth.route) {
FourthScreen(navController, actions)
}
composable("${Screens.FinalShow.route}/{maskArg}") {
val maskArg = it.arguments?.getString("maskArg")
if (maskArg != null) {
FinalShowScreen(
maskArg = maskArg, navController,actions
)
}
}
composable("${Screens.RewardedShow.route}/{maskArg}") {
val maskArg = it.arguments?.getString("maskArg")
if (maskArg != null) {
RewardedShowCompose(
maskArg = maskArg, navController = navController, actions = actions
)
}
}
}
}
class MainActions(navController: NavController) {
val goToRoute: (String) -> Unit = { route ->
navController.navigate(route) {
navController.graph.startDestinationRoute?.let { rout ->
popUpTo(rout) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}
}
}
I'm trying this code below but It doesn't work. it goes back to AdShowScreen
val gotoAdShow: (String, String) -> Unit = { maskArg, route ->
navController.navigate("$route/$maskArg") {
navController.graph.startDestinationRoute?.let { rout ->
popUpTo(rout) {
saveState = true
inclusive = true
}
}
launchSingleTop = true
restoreState = true
}
}
Why are you using
navController.navigate(route) {
navController.graph.startDestinationRoute?.let { rout ->
popUpTo(rout) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}
What if instead you use navHostController.popBackStack("ad", inclusive = true) directly?
To navigate back from the final screen to the first one, add this to the FourthScreen Composable;
BackHandler {
navController.navigate(BottomNavItems.First.route) // Or to whichever route you want to navigate to
}
Also, it is not a good practice to pass the navController to other Composables because it will make your UI pretty hard to test.

Pass custom object to authenticated routes

I was wondering if there was a way to configure the Authentication plugin so that I can pass some params (e.g. a user object) to my route handlers (similar to how UserIdPrincipal is passed in).
As an example, it might look something like this
install(Authentication) {
basic("auth-basic") {
validate { credentials ->
val user = userRepo.verifyUser(credentials.name, credentials.password)
if (user != null) {
// UserIdPrincipal(credentials.name) // current impl
user // desired
} else {
log.info("Unauthorized route access with credential name: ${credentials.name}")
null
}
}
}
}
then in my routes, I could do something like
post("/foo") {
val user = call.receive<User>()
}
You can implement the Principal interface for your User class to receive it in a route. Here is an example:
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(Authentication) {
basic("auth-basic") {
realm = "Access to the '/' path"
validate { credentials ->
if (credentials.name == "jetbrains" && credentials.password == "foobar") {
userRepo.verifyUser(credentials.name, credentials.password)
} else {
null
}
}
}
}
routing {
authenticate("auth-basic") {
get("/login") {
val user = call.principal<User>()
println("Hello ${user?.name}")
}
}
}
}.start(wait = true)
}
class User(val name: String): Principal

Flutter - Get data with an Event Channel from Kotlin to Dart

I have the following problem that I am already working on for over 20 hours: I want to use an Event Channel to get a data stream from the Spotify SDK. On the native side, I can automatically display the status of a current song by subscribing to my PlayerState. My goal is to be able to access this data stream with my Flutter app. On the native side I can output the data flow without problems. But I also want to be able to access this data in my Flutter App. The problem is that I do not get the data from Kotlin to Dart. I can not execute the command mEventSink?.success(position) because the mEventSink is zero.
It would be really great if someone could help me with this problem.
//...
class Spotifysdk04Plugin(private var registrar: Registrar): MethodCallHandler, EventChannel.StreamHandler {
//...
private var mEventSink: EventChannel.EventSink? = null
companion object {
#JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "spotifysdk")
channel.setMethodCallHandler(Spotifysdk04Plugin(registrar))
val eventChannel = EventChannel(registrar.messenger(), "timerStream")
eventChannel.setStreamHandler(Spotifysdk04Plugin(registrar))
}
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "loginAppRemote") {
//...
} else if(call.method == "initEventStream") {
try {
spotifyAppRemote!!.playerApi.subscribeToPlayerState()
.setEventCallback { playerState: PlayerState? ->
Log.d("test", "test24")
var position = playerState!!.playbackPosition.toDouble()
Log.d("playbackPosition1", position.toString())
if(mEventSink != null) {
Log.d("test", "test25")
mEventSink?.success(position)
} else {
Log.d("test", "mEventSink == null")
}
}
} catch (err:Throwable) {
Log.v("initEventStreamError",err.message.toString())
result.success(false)
}
} else {
result.notImplemented()
}
}
override fun onCancel(arguments: Any?) {
mEventSink = null
}
override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink) {
mEventSink = eventSink
}
}
I found a solution:
override fun onListen(p0: Any?, p1: EventChannel.EventSink?) {
mEventSink = p1
Log.d("test", "test1")
if(spotifyAppRemote == null) {
Log.d("test", "test2")
}
val connectionParams = ConnectionParams.Builder(clientId)
.setRedirectUri(redirectUri)
.showAuthView(true)
.build()
SpotifyAppRemote.connect(registrar.context(), connectionParams, object : Connector.ConnectionListener {
override fun onConnected(appRemote: SpotifyAppRemote) {
spotifyAppRemote = appRemote
if(spotifyAppRemote != null) {
Log.d("test", "test3")
spotifyAppRemote!!.playerApi.subscribeToPlayerState()
.setEventCallback { playerState: PlayerState? ->
Log.d("test", "test24")
var position = playerState!!.playbackPosition.toDouble()
Log.d("playbackPosition1", position.toString())
if(mEventSink != null) {
Log.d("test", "test25")
mEventSink?.success(position)
} else {
Log.d("test", "mEventSink == null")
}
}
}
Log.d("Spotify App Remote Login", "Connected!")
}
override fun onFailure(throwable: Throwable) {
Log.e("Spotify App Remote Login", "Error!", throwable)
}
})
}

go to another activity on Menu Item selection in kotlin

l added Options menu item Selected in toolbar of my app . l want add action on click on item even go to another activity . l Intent but does not work
override fun onOptionsItemSelected(item: MenuItem): {
when (item.itemId) {
R.id.flightarrbeforbgw ->
Intent intent = new Intent(this, FlightsArrivelBeforBGW.class);
this.startActivity(intent)
else ->
return null
}
}
l try with is code and his worked fine
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
//noinspection SimplifiableIfStatement
if (id == R.id.searchflights) {
val intent = Intent(this, FlightsArrivelBeforBGW::class.java)
this.startActivity(intent)
return true
}
if (id == R.id.flightarrbeforbgw) {
Toast.makeText(this, "Android Menu is Clicked", Toast.LENGTH_LONG).show()
return true
}
if (id == R.id.flight_dep_list) {
Toast.makeText(this, "Android Menu is Clicked", Toast.LENGTH_LONG).show()
return true
}
return super.onOptionsItemSelected(item)
}
Your intent is not formatted correctly. This is how it's supposed to be:
Intent (this, YourActivity::class.java)
So your code should look like this:
when (item.itemId) {
R.id.flightarrbeforbgw ->{
this.startActivity(Intent(this,FlightsArrivelBeforBGW::class.java))
return true
}
else -> super.onOptionsItemSelected(item)
}

What's the right way to get permissions for phone call intent

How to request permissions using Kotlin.
I am trying to make a phone call function
fun buChargeEvent(view: View){
var number: Int = txtCharge.text.toString().toInt()
val intentChrage = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:$number")
startActivity(intentChrage)
}
I added user permissions in manifest
but still having the same
error .
You need to add permission to your manifest first
<uses-permission android:name="android.permission.CALL_PHONE" />
After permission added in manifest following code would work fine for you "Number_to_call" will be youe number that is need to be replaced
val call = Intent(Intent.ACTION_DIAL)
call.setData(Uri.parse("tel:" +"Number_to_call"))
startActivity(call)
You need to add the run time permission. Download the source code from here
//Click function of layout:
rl_call.setOnClickListener {
if (boolean_call) {
phonecall()
}else {
fn_permission(Manifest.permission.CALL_PHONE,CALLMODE)
}
}
// Request permission response
fun fn_permission(permission:String,mode:Int){
requestPermissions(permission, object : PermissionCallBack {
override fun permissionGranted() {
super.permissionGranted()
Log.v("Call permissions", "Granted")
boolean_call=true
phonecall()
}
override fun permissionDenied() {
super.permissionDenied()
Log.v("Call permissions", "Denied")
boolean_call=false
}
})
}
// function to call intent
fun phonecall() {
val intent = Intent(Intent.ACTION_CALL);
intent.data = Uri.parse("tel:1234567890s")
startActivity(intent)
}
Thanks!
First you need to add permission to your manifest first :
<uses-permission android:name="android.permission.CALL_PHONE" />
This bit of code is used on the place of your method :
fun buChargeEvent(view: View) {
var number: Int = txtCharge.text.toString().toInt()
val callIntent = Intent(Intent.ACTION_CALL)
callIntent.data = Uri.parse("tel:$number")
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this as Activity,
Manifest.permission.CALL_PHONE)) {
} else {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.CALL_PHONE),
MY_PERMISSIONS_REQUEST_CALL_PHONE)
}
}
startActivity(callIntent)
}
You need to request the runtime permission, since Android 6.0 certain permissions require you to ask at install and again at runtime.
Following the instructions here explains how to ask for permission at runtime.
This is the complete code for runtime permissions for Call Phone
Step 1:- add permission in manifest
<uses-permission android:name="android.permission.CALL_PHONE" />
Step 2:- Call this method checkAndroidVersion() in onCreate()
fun checkAndroidVersion() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkAndRequestPermissions()) {
} else {
}
} else {
// do code for pre-lollipop devices
}
}
val REQUEST_ID_MULTIPLE_PERMISSIONS = 1
fun checkAndRequestPermissions(): Boolean {
val call = ContextCompat.checkSelfPermission(this#MainActivity, Manifest.permission.CALL_PHONE)
val listPermissionsNeeded = ArrayList<String>()
if (call != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CALL_PHONE)
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this#MainActivity, listPermissionsNeeded.toTypedArray(), REQUEST_ID_MULTIPLE_PERMISSIONS)
return false
}
return true
}
fun checkAndRequestPermissions(): Boolean {
val call = ContextCompat.checkSelfPermission(this#MainActivity, Manifest.permission.CALL_PHONE)
val listPermissionsNeeded = ArrayList<String>()
if (call != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CALL_PHONE)
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this#MainActivity, listPermissionsNeeded.toTypedArray(), REQUEST_ID_MULTIPLE_PERMISSIONS)
return false
}
return true
}
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
Log.d("in fragment on request", "Permission callback called-------")
when (requestCode) {
REQUEST_ID_MULTIPLE_PERMISSIONS -> {
val perms = HashMap<String, Int>()
// Initialize the map with both permissions
perms[Manifest.permission.CALL_PHONE] = PackageManager.PERMISSION_GRANTED
// Fill with actual results from user
if (grantResults.size > 0) {
for (i in permissions.indices)
perms[permissions[i]] = grantResults[i]
// Check for both permissions
if (perms[Manifest.permission.CALL_PHONE] == PackageManager.PERMISSION_GRANTED
) {
print("Storage permissions are required")
// process the normal flow
//else any one or both the permissions are not granted
} else {
Log.d("in fragment on request", "Some permissions are not granted ask again ")
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// // shouldShowRequestPermissionRationale will return true
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.READ_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(this#MainActivity, Manifest.permission.ACCESS_FINE_LOCATION)) {
showDialogOK("Call permission is required for this app",
DialogInterface.OnClickListener { dialog, which ->
when (which) {
DialogInterface.BUTTON_POSITIVE -> checkAndRequestPermissions()
DialogInterface.BUTTON_NEGATIVE -> {
}
}// proceed with logic by disabling the related features or quit the app.
})
} else {
Toast.makeText(this#MainActivity, "Go to settings and enable permissions", Toast.LENGTH_LONG)
.show()
// //proceed with logic by disabling the related features or quit the app.
}//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
}
}
}
}
}
fun showDialogOK(message: String, okListener: DialogInterface.OnClickListener) {
AlertDialog.Builder(this#MainActivity)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show()
}
**Step 3**:- On button click
fun buChargeEvent(view: View){
if(checkAndRequestPermissions(){
var number: Int = txtCharge.text.toString().toInt()
val intentChrage = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:$number")
startActivity(intentChrage)
}
}