mobile-dev-inc / dadb

A Kotlin/Java library to connect directly to an Android device without an adb binary or an ADB server
Apache License 2.0
1.01k stars 72 forks source link

Discover returns an error #37

Open victorjaviermartin opened 1 year ago

victorjaviermartin commented 1 year ago

Hi guys,

I'm Victor, and I'm trying to run the library in a poc application to know how to use it. But the first method that I'm trying is "discover", but it returning me a FileNotFoundException

I'm doing:

fun discover(){
        try {
            val result = Dadb.discover("localhost")
            binding.tvcommandline.text = "" + result.toString()
        }catch (ex: java.lang.RuntimeException){
            binding.tvcommandline.text = "Failed to discover emulator. No adb device found"
            ex.printStackTrace()
        }
    }

The error is:

Caused by: java.io.FileNotFoundException: .android/adbkey: open failed: ENOENT (No such file or directory)

Some advice?

I'm testing on a Samsung S20 Ultra with Android 12 and connected via USB.

Thank you

sharpordie commented 1 year ago

Dadb doesn't create the keypair automatically on Android device. You have to create those keys manually and use them in the discover method.

This is a code sample to create them in your application's cache directory.

class YourViewModel(application: Application) : AndroidViewModel(application) {

    val context by lazy { getApplication<Application>().applicationContext }

    suspend fun keygen(refresh: Boolean = false): AdbKeyPair = withContext(IO) {
        val tempdir = context.cacheDir
        val pvtFile = File(tempdir, "adbkey")
        val pubFile = File(tempdir, "adbkey.pub")
        if (refresh || !pubFile.exists() || !pvtFile.exists()) {
            if (pubFile.exists()) pubFile.delete()
            if (pvtFile.exists()) pvtFile.delete()
            AdbKeyPair.generate(pvtFile, pubFile)
        }
        AdbKeyPair.read(pvtFile, pubFile)
    }

    suspend fun onButtonClicked() = viewModelScope.launch {
        val handler = Dadb.discover("localhost", keygen())
    }        
}        
victorjaviermartin commented 1 year ago

Hi @sharpordie with those lines, discover returns me a "null"

Leland-Takamine commented 1 year ago

@victorjaviermartin Can you please paste the whole stack trace?

@sharpordie Dadb does actually generate the adb key automatically now: https://github.com/mobile-dev-inc/dadb/blob/42a0125c47b196418fffdf4cdf6fdc04935e523e/dadb/src/main/kotlin/dadb/AdbKeyPair.kt#L77

sharpordie commented 1 year ago

@Leland-Takamine Victor asked for an Android solution. The HOME environment variable doesn't exist by default on Android. So my code uses the current application's cache directory.

Unfortunately I don't use dadb anymore on Android. I will retry my code this week, I am sure it worked properly.

@victorjaviermartin Did you allow the adb connection on your target device?

victorjaviermartin commented 1 year ago

Yes @sharpordie. I need to test again to take the full stacktrace, but I don't have time at the moment. Sorry.

sharpordie commented 1 year ago

@victorjaviermartin Sorry for the long waiting time.

Here is a working project using an old version (0.0.11) of Dadb: https://github.com/sharpordie/hisendal

I quickly tested with version 1.2.4, but it doesn't work unfortunately. I hope this will be helpful to you anyway.

victorjaviermartin commented 1 year ago

@victorjaviermartin Sorry for the long waiting time.

Here is a working project using an old version (0.0.11) of Dadb: https://github.com/sharpordie/hisendal

I quickly tested with version 1.2.4, but it doesn't work unfortunately. I hope this will be helpful to you anyway.

Thank you, I will take a look

sharpordie commented 1 year ago

@victorjaviermartin Well, this should work fine with the latest version of Dadb. https://github.com/sharpordie/hisendal

It's still using the ugly GlobalScope.async. This is used to throw an exception if the target device has not accepted the connection yet and prevents it from blocking endlessly.

Please tell me if it works with your devices.

I'm not working with Dadb anymore for the moment, my initial goal was to use Dadb on Android and iOS through Kotlin Multiplatform and use it in my Flutter projects with Klutter. But that's way too much for my narrow brain. The fact that Dadb doesn't allow to pair with Android 11+ devices is also a serious problem.

victorjaviermartin commented 1 year ago

Thank you @sharpordie but unfortunately this is obsolete from android 11+. Thank you for your effort.

sharpordie commented 1 year ago

I guess copying adbkey files from an authorized machine with the "pair" command to hisendal's cache folder doesn't work. That would be too straightforward? Or I wouldn't understand Google's action to make the connection so painful.

Damn, I'll have to find an Android 11+ emulator with bridged network capability to test.