Does Kotlin supports AIDL? - java

I have a simple AIDL definition and I want to use in Kotlin code but when it builds shows Unresolved reference error for all variables that uses the interface. but the same AIDL has no problem in Java code. does Kotlin support it? how to solve
here my AIDL in src/main/aidl/
// ServiceInterface.aidl
package com.example.test;
interface ServiceInterface {
void test(String arg1);
}
and activity code is
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.swiftytime.clientappcommunication.R
import com.example.test.ServiceInterface
class MainActivity : AppCompatActivity() {
var mServiceAidl: ServiceInterface? = null
var mIsBound = false
private val mConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
try {
mServiceAidl = ServiceInterface.Stub.asInterface(service)
Log.e("app", "Attached")
} catch (e: RemoteException) {
}
}
override fun onServiceDisconnected(className: ComponentName) {
mServiceAidl = null
Log.e("app", "Disconnected.")
}
}
private fun doBindService() {
val intent = Intent().apply {
component = ComponentName(
"com.example.test", "com.example.test.MyService"
)
}
bindService(
intent,
mConnection, Context.BIND_AUTO_CREATE
)
mIsBound = true
Log.e("app", "Binding.")
}
private fun doUnbindService() {
if (mIsBound) {
unbindService(mConnection)
mIsBound = false
Log.e("app", "Unbinding.")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
doBindService()
}
}
this is error
[ERROR] [org.gradle.api.Task] e: /Volumes/Projects/AndroidProject/ClientAppCommunication/app/src/main/java/com/example/test/MainActivity.kt: (16, 23): Unresolved reference: ServiceInterface

After many hours, I found the problem which is buildToolsVersion 29.0.0 generate wrong path for generated java files, I submitted a bug
Just changing to buildToolsVersion 28.0.3 solve the issue.
Update:
Problem Solved and now it works in buildToolsVersion 29.0.1

I'm using AIDL with Kotlin and what I have is interfaces written in Java and all model classes that are used by defined interfaces are written in Kotlin and it is working perfectly.
For example. I have I*Subscriber.aidl with method
void onSomeEventHappened(in AidlEvent event);
and also I have the .aidl file and .kt file for AidlEvent class.
AidlEvent.aidl file
// AidlEvent.aidl
parcelable AidlEvent;
AidlEvent.kt
data class AidlEvent(
val eventType: Int,
val eventMessage: String):
Parcelable {
// add parcelable methods
}
I'm not sure that you will be able to write .aidl interface in Kotlin, haven't managed to do that. It should not be an issue if you need to write few methods in Java, as you don't need to implement them in Java, you will just declare them.

Related

Object is not abstract and does not implement abstract member public abstract fun error in flutter with kotlin native code

I'm trying to call a native kotlin code inside my flutter application .. am doing it this way
flutter side
class NativeLocationServices {
static const currentLocationChannel = MethodChannel("com.deliveryrunner.driver/getCurrentLocation");
getCurrentNativeLocation() async {
// Either the permission was already granted before or the user just granted it.
final arguments = {"test":"it is working"};
final currentLocation = await currentLocationChannel.invokeMethod("currentLocation",arguments);
print(currentLocation);
}
}
kotlin side
package xxxxxx > here are my package name
import android.content.*
import io.flutter.embedding.android.FlutterActivity
import androidx.annotation.NonNull
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Intent
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import android.location.Location
class MainActivity : FlutterActivity() {
private val LOCATION_CHANNEL = "com.deliveryrunner.driver/getCurrentLocation";
private lateinit var channel: MethodChannel
private lateinit var fusedLocationClient: FusedLocationProviderClient
override fun onCreate(savedInstanceState: Bundle) {
GeneratedPluginRegistrant.registerWith(this)
MethodChannel(flutterView, CHANNEL).setMethodCallHandler {
call, result ->
if (call.method == "currentLocation") {
val arguments = call.arguments() as Map<String, String>
val test = arguments["test"]
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
// Got last known location. In some rare situations this can be null.
// result.success(location)
result.success("got the loation")
}
}
}
}
but I am getting this error when I try to run the app
e: D:\Flutter\src\flutter\.pub-cache\hosted\pub.dartlang.org\workmanager-0.4.1\android\src\main\kotlin\be\tramckrijte\workmanager\BackgroundWorker.kt: (132, 21): Object is not abstract and does not implement abstract member public abstract fun error(p0: String, p1: String?, p2: Any?): Unit defined in io.flutter.plugin.common.MethodChannel.Result
e: D:\Flutter\src\flutter\.pub-cache\hosted\pub.dartlang.org\workmanager-0.4.1\android\src\main\kotlin\be\tramckrijte\workmanager\BackgroundWorker.kt: (137, 25): 'error' overrides nothing
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':workmanager:compileDebugKotlin'.
> Compilation error. See log for more details
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 14s
Exception: Gradle task assembleDebug failed with exit code 1

E/GraphResponse: Unsupported get request. Android Studio facebook login

I have problem with Facebook login app. I was fallowing this tutorial . I took every step and on the end i converted MainAcktivity into kotlin file. Application after login in or logout is stopping.
and I'm receiving follow error in Logcat:
2021-05-22 19:23:12.963 9521-9545/com.example.XXX_login E/GraphResponse: {HttpStatus: 400, errorCode: 100, subErrorCode: 33, errorType: GraphMethodException, errorMessage: Unsupported get request. Object with ID '111111111111111' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api}
2021-05-22 19:23:46.065 9521-9521/com.example.XXX_login E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.XXX_login, PID: 9521
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter oldAccessToken
at com.example.XXX_login.MainActivity$accessTokenTracker$1.onCurrentAccessTokenChanged(Unknown Source:2)
at com.facebook.AccessTokenTracker$CurrentAccessTokenBroadcastReceiver.onReceive(AccessTokenTracker.java:110)
at androidx.localbroadcastmanager.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:313)
at androidx.localbroadcastmanager.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:121)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Here is my MainActivity.kt file:
package com.example.XXX_login
import com.facebook.FacebookSdk
import com.facebook.appevents.AppEventsLogger
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.facebook.*
import com.facebook.login.LoginManager
import com.facebook.login.LoginResult
import com.facebook.login.widget.LoginButton
import org.json.JSONException
import com.squareup.picasso.Picasso as Picasso1
//import java.util.*
class MainActivity : AppCompatActivity() {
private var callbackManager: CallbackManager? = null
private lateinit var loginButton: LoginButton
private var imageView: ImageView? = null
private var textView: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loginButton = findViewById(R.id.login_button)
textView = findViewById(R.id.tv_name)
imageView = findViewById(R.id.tv_profilePic)
callbackManager = CallbackManager.Factory.create()
//permisions do logowania
loginButton.setPermissions(
listOf(
"user_gender",
"email",
"user_location",
"user_birthday"
)
)
loginButton.registerCallback(callbackManager, object : FacebookCallback<LoginResult?> {
override fun onSuccess(loginResult: LoginResult?) {
Log.d("Demo", "Zalogowano!")
}
override fun onCancel() {
Log.d("Demo", "Wylogowano")
}
override fun onError(error: FacebookException) {
Log.d("Demo", "Bład logowania:")
}
})
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
callbackManager!!.onActivityResult(requestCode, resultCode, data)
super.onActivityResult(requestCode, resultCode, data)
val graphRequest =
GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { `object`, response ->
//tworzenie pliku JSON z pobieranymi przez Graph danymi
Log.d("Demo", `object`.toString())
try {
val name = `object`.getString("name")
val pic = `object`.getJSONObject("picture").getJSONObject("data").getString("url")
textView!!.text = name
Picasso1.get().load(pic).into(imageView)
} catch (e: JSONException) {
e.printStackTrace()
}
}
val bundle = Bundle()
//informacjie pozyskiwane z facebooka= defaultowe i na podstawie wcześniej wydanych permissions
bundle.putString(
"fields",
"gender, name, first_name, last_name, email, birthday, location, picture"
)
graphRequest.parameters = bundle
graphRequest.executeAsync()
}
//tracker do sprawdzania czy użytkownik jest zalogowany, jestli token sie zmieni to wywowała sie ta metoda
//wylogowywanie sie
var accessTokenTracker: AccessTokenTracker = object : AccessTokenTracker() {
override fun onCurrentAccessTokenChanged(
oldAccessToken: AccessToken,
currentAccessToken: AccessToken
) {
if (currentAccessToken == null) {
LoginManager.getInstance().logOut()
textView!!.text = ""
imageView!!.setImageResource(0)
}
}
}
override fun onDestroy() {
super.onDestroy()
accessTokenTracker.stopTracking()
}
}
I had have read in the internet for answer for this problem but i've could't find something that could work.
This is because in Kotlin you have to specify the variable as nullable if it will be null in any case.
The error is in this function
var accessTokenTracker: AccessTokenTracker = object : AccessTokenTracker() {
override fun onCurrentAccessTokenChanged(
oldAccessToken: AccessToken,
currentAccessToken: AccessToken
) {
if (currentAccessToken == null) {
LoginManager.getInstance().logOut()
textView!!.text = ""
imageView!!.setImageResource(0)
}
}
}
here in the onCurrentAccessTokenChanged() function you are expecting the currentAccessToken to be null, but you have not made currentAccessToken as nullable hence it will fail and crash. Since only nullable elements can get null value assigned after initialisation in Kotlin. Therefore here you can make the variables as nullable and the problem will be solved.
You can make any variable as nullable like this
currentAccessToken : Type? , where the Type can be Int, String or any supported or custom type.
var accessTokenTracker: AccessTokenTracker = object : AccessTokenTracker() {
override fun onCurrentAccessTokenChanged(
oldAccessToken: AccessToken?,
currentAccessToken: AccessToken?
) {
if (currentAccessToken == null) {
LoginManager.getInstance().logOut()
textView!!.text = ""
imageView!!.setImageResource(0)
}
}
}
This will solve your problem.
It is always recommended that you make the variables as Nullable if you think that the variable might accommodate null at any time in the future in any case to avoid such crashes.

make simple code but app has stopping work in kotlin

l am try to learn kotlin language , and the first app to me is take data fro json array . but the problem is when start to debug app l got FATAL EXCEPTION: main and app has stopping working . In my Android App, I desgin the following json data construction
my code is :
package com.example.ali.test
import android.os.AsyncTask
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.view.*
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val url = "https://mysafeinfo.com/api/data?list=presidents&format=json"
Download().execute(url)
}
// full class for json api
inner class Download : AsyncTask<String,String,String>(){
override fun onPreExecute() {
}
// for build connection
override fun doInBackground(vararg p0: String?): String{
try {
val url = URL(p0[0])
val urlConnect = url.openConnection() as HttpURLConnection
urlConnect.connectTimeout = 700
val inputStream = urlConnect.inputStream
val dataJsonAsStr = covertStreamToString(urlConnect.inputStream)
publishProgress(dataJsonAsStr)
} catch (e: Exception){
}
return ""
}
// for get items from json api
override fun onProgressUpdate(vararg values: String?) {
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
}
}
fun handleJson (jsonString: String?){
val jsonArray = JSONArray(jsonString)
val list = ArrayList<FlightShdu>()
var x = 0
while (x < jsonArray.length()){
val jsonObject = jsonArray.getJSONObject(x)
list.add(FlightShdu(
jsonObject.getInt("id"),
jsonObject.getString("nm")
))
x++
}
val adapter = ListAdapte(this#MainActivity,list)
flightShdu_list.adapter = adapter
}
// for connection api
fun covertStreamToString (inputStream: InputStream): String {
val bufferReader = BufferedReader(InputStreamReader(inputStream))
var line:String
var allString:String=""
try {
do{
line=bufferReader.readLine()
if (line!=null)
allString+=line
}while (line!=null)
bufferReader.close()
}catch (ex:java.lang.Exception){}
return allString;
}
}
error in console :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ali.test, PID: 24738
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 
Caused by: org.json.JSONException: End of input at character 0 of
at org.json.JSONTokener.syntaxError(JSONTokener.java:449)
at org.json.JSONTokener.nextValue(JSONTokener.java:97)
at org.json.JSONArray.<init>(JSONArray.java:92)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.example.ali.test.MainActivity.handleJson(MainActivity.kt:68)
at com.example.ali.test.MainActivity$Download.onPostExecute(MainActivity.kt:59)
at com.example.ali.test.MainActivity$Download.onPostExecute(MainActivity.kt:27)
at android.os.AsyncTask.finish(AsyncTask.java:660)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386) 
any one have any idea please ?
Your doInBackground() always returns an empty string, "". This empty string will be passed as the parameter to onPostExecute, which in turns uses this empty string as a parameter to handleJson. When you try to create a JSON array from this empty string it throws an exception at index 0, as it doesn't have any more data and it's not a valid json.
You need to return the result of the network call from doInBackground() instead of an empty string.
**
Use your code like this example below:
**
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val s = tvDisplay.text.toString()
btnOk.setOnClickListener {
Download().execute(s)
}
}
inner class Download : AsyncTask<String, Void, Void>() {
override fun doInBackground(vararg ss: String?): Void? {
validate(ss[0]!!)
return null
}
}
private fun validate(s:String) {
if(s.isNotEmpty()){
runOnUiThread {
Toast.makeText(this, "Working :)", Toast.LENGTH_SHORT).show()
}
}
else{
runOnUiThread {
Toast.makeText(this, "Not Working :(", Toast.LENGTH_SHORT).show()
}
}
}
}

IONIC 3 : UnhandledPromiseRejectionWarning when generating APK File

I'm facing problems when generating apk file. I get the following error.
Command : ionic cordova build android
Output :
> cordova build android
Android Studio project detected
ANDROID_HOME=C:\Users\****\AppData\Local\Android\Sdk
JAVA_HOME=C:\Program Files\Java\jdk-9.0.4
(node:17504) UnhandledPromiseRejectionWarning: Unhandled promise rejection (reje
ction id: 1): CordovaError: Requirements check failed for JDK 1.8 or greater
(node:17504) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate th
e Node.js process with a non-zero exit code.
[13:47:49] lint finished in 8.47 s
This is the content of my rest file rest.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class RestProvider {
private baseUrl = 'http://localhost/project/web/rest/mobile/v1/';
private nomsvillesUrl = this.baseUrl + 'ville/nomsvilles/1';
constructor(public http: HttpClient) {
console.log('Hello RestProvider Provider');
}
getNomvilles(): Observable<string[]> {
return this.http.get(this.nomsvillesUrl)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res;
return body || { };
}
private handleError (error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const err = error || '';
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
This is the content of my main class main.ts
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { RestProvider } from '../../providers/rest/rest';
#Component({
selector: 'page-main',
templateUrl: 'main.html',
})
export class MainPage {
villes: string[]
errorMessage: string
constructor(public navCtrl: NavController, public navParams: NavParams, public rest: RestProvider) {
}
ionViewDidLoad() {
this.getVilles();
}
getVilles() {
this.rest.getNomvilles().subscribe(
villes => this.villes = villes,
error => this.errorMessage = <any>error
);
}
}
Please help me ! I want to know how to handle Promise in order to prevent promise rejection.
Thank you .
The error has nothing related to your code. It's asking for jdk 1.8 or higher you can download it from this link. But first uninstall jdk 1.9 you're using because it's not compatible with android.
Then create a environment variable JAVA_HOME=C:\path\to\jdk\bin

value Engine is not a member of object android.speech.tts.TextToSpeech

In java, using android-19, this works fine:
import android.speech.tts.TextToSpeech.Engine;
But in scala:
import android.speech.tts.TextToSpeech.Engine
^
error: value Engine is not a member of object android.speech.tts.TextToSpeech
This is weird because I can import EngineInfo without problems, but it does not recognize the class Engine, although it is clearly in the android.jar
Any fix or workaround? Is this a scala issue? I'm developping on Eclipse 3.7 using AndroidProguardScala v51 and Scala IDE version 3.0.1
EDIT
The context in which I am using this is for example the following:
if(resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
mTts = new TextToSpeech(this, mTtsListener)
}
Unfortunately, TextToSpeech.Engine is declared non-static which means something like this:
public class TextToSpeech {
public class Engine {
// ...
}
// ...
}
So according to this, you can't access it. Here's my workaround using a wrapper:
object ConstantsWrapper {
private val cls = classOf[TextToSpeech#Engine]
def apply(fieldName: String) = cls.getDeclaredField(fieldName).get(null)
.toString
val CHECK_VOICE_DATA_PASS = apply("CHECK_VOICE_DATA_PASS")
// Insert more here
}
if (resultCode == ConstantsWrapper.CHECK_VOICE_DATA_PASS) {
mTts = new TextToSpeech(this, mTtsListener)
}

Categories

Resources