На Android 7 (с root-доступом) libusb_init не работает с LIBUSB_ERROR_OTHER
Я пытаюсь использовать libusb в приложении для Android, он встроен в собственный модуль Android и построен с помощью cmake. Код вызывает только libusb_init и возвращает строку для действия, и он систематически терпит неудачу с LIBUSB_ERROR_OTHER.
Дело в том, что я могу заставить его работать, когда он запускается из небольшой программы командной строки, выполняющей только libusb_init, которую мы запускаем с помощью оболочки adb. В этом случае он возвращает успех.
Устройство (Samsung Galaxy Tab E) работает под управлением Android 7 и имеет root-права, с помощью Magisk Manager я даю своему приложению root-права, но это не похоже на выполнение "su" в командной строке.
В основном я пробовал с версией 20 и 22 (в других наших проектах мы используем в основном версию 20).
Я уже пробовал много решений и обходных путей stackru, но они были либо неэффективны, либо их невозможно было реализовать (например, из-за ограничений ROM).
Вот как я вызываю libusb.c:
#include <jni.h>
#include <string>
extern "C" {
#include "libusb.h"
}
using namespace std;
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
string hello = "Hello from C++";
libusb_context **lusb;
int rc = libusb_init(lusb);
return env->NewStringUTF(hello.c_str());
}
И вот как я вызываю этот код из Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
//The purpose of this is to ask for root access, handled with
//Magisk Manager in my case
Runtime.getRuntime().exec("su")
fab.setOnClickListener { view ->
Snackbar.make(view, "Result = ${stringFromJNI()}", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
external fun stringFromJNI(): String
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
Небольшая программа, которую я запускаю из командной строки (она работает независимо от того, root я или нет):
#include <iostream>
extern "C" {
#include "libusb.h"
}
using namespace std;
int main (int argc, char* argv[]) {
libusb_context *lusb;
int rc = libusb_init(&lusb);
if ( rc != LIBUSB_SUCCESS ) {
cout << "Failed to open api. Error: " << libusb_error_name(rc) << endl;
return 1;
}
cout << "This worked" << endl;
return 0;
}