Russian Qt Forum
Апрель 26, 2024, 00:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: (РЕШЕНО) Просьба помочь с правильным оформлением JNI-кода  (Прочитано 10217 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Ноябрь 02, 2016, 19:57 »

Мне нужно вызвать из Qt-приложения функции AudioManager. В программировании на Java я полный плавающий 0.0 (можно интерпретировать и как смайлик). Поэтому прошу помощи в правильном оформлении подключаемого к проекту файла с интерфейсами для вызова функций Android AudioManager. Вроде понятно как к ним обратиться из C++ кода, и как это подключить к проекту. Пока нужна помощь толко по правильному оформлению Java кода. Изучать подробно Java сейчас некогда, надо сделать проект, он на 99.99% на Qt. На Java нужны только эти функции, поскольку их увы в Qt для Android нет. Вот написал такое глядя на различные примеры и обсуждения в Сети, пока без тел методов (там вроде тоже понятно какие методы AudioManager вызвать). Что здесь не правильно, чего не хватает, что лишнее? Буду невероятно признателен за исправление этого кода до состояния, когда он без сообщений об ошибках подключится к проекту и заработает.

Код:
// VolumeControl.java

package org.myfirm.myapp

import org.myfirm.myapp.QtApplication
import org.myfirm.myapp.QtActivity
import android.media.AudioManager

public class VolumeControl extends QtActivity
{
    public void Mute(){
    }

    public void VolumeUp(){
    }

    public void VolumeDn(){
    }
}
« Последнее редактирование: Ноябрь 07, 2016, 22:44 от Гурман » Записан

2^7-1 == 127, задумайтесь...
VPS
Гость
« Ответ #1 : Ноябрь 02, 2016, 20:27 »

В андроиде не силён, но вот что заметил:
Строки с package и import должны заканчиваться ";"
Код
Java
package org.myfirm.myapp;
 
Также вызывает сомнение правильность полного имени импортируемых классов QtApplication (в заготовке он вроде не используется, поэтому может быть лишним) и QtActivity.
Возможно надо так:
Код
Java
package org.myfirm.myapp;
 
import org.qtproject.qt5.android.bindings.QtActivity;
import android.media.AudioManager;
 
« Последнее редактирование: Ноябрь 02, 2016, 20:47 от vps » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Ноябрь 02, 2016, 20:53 »

Ну, точка с запятой - это синтаксис... выругается при трансляции. Меня больше всё-таки интересуют правильные инклюды и оформление имени класса.  В фирменном примере Qt оно выглядит так:

Код:
public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity

хотя в обсуждениях в форумах после extends обычно указано только QtActivity. Или просто Activity. Я не знаю, как правильно.
Записан

2^7-1 == 127, задумайтесь...
VPS
Гость
« Ответ #3 : Ноябрь 02, 2016, 21:01 »

Код:
public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity
Можно и так писать, тогда строка, импортирующая данный класс будет лишней и её можно опустить.

P/S: здесь видно, что класс QtActivity наследует класс android.app.Activity.
« Последнее редактирование: Ноябрь 02, 2016, 21:06 от vps » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #4 : Ноябрь 06, 2016, 19:32 »

up

Накрутил чего-то, приложение собирается, функции вроде должны вызываться, но управление громкостью не производится. Есть круговой слайдер, при его вращении вызываются два метода С++:

Код:
void volCtrl::volumeUp()
{
#ifdef __ANDROID__
    QAndroidJniObject::callStaticMethod<void>( "org/myfirm/myapp/PlayControl", "volumeUp" );
    qDebug()<<"volup";
#endif
}

void volCtrl::volumeDn()
{
#ifdef __ANDROID__
    QAndroidJniObject::callStaticMethod<void>( "org/myfirm/myapp/PlayControl", "volumeDn" );
    qDebug()<<"voldn";
#endif
}
Java код выглядит так

Код:
package org.myfirm.myapp;

import org.myfirm.myapp.QtActivity;
import android.media.AudioManager;

public class PlayControl extends QtActivity
{
    public static void VolumeUp(){
        AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
        am.adjustVolume(ADJUST_RAISE, FLAG_SHOW_UI);
    }

    public static void VolumeDn(){
        AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
        am.adjustVolume(ADJUST_LOWER, FLAG_SHOW_UI);
    }
}

при вращении слайдера выводится volup и voldn в консоль, но больше ничего не происходит

что не так, и что сделать, чтобы было так как надо?
Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #5 : Ноябрь 06, 2016, 20:57 »

Cделал так

Код:
QAndroidJniObject r = QAndroidJniObject::callStaticObjectMethod<jstring>( "org/myfirm/myapp/PlayControl", "volumeDn");
if( !r.isValid() )
            qCritical()<<"Object not valid";

ну это и получил... Что может быть не так?

Да и QAndroidJniObject::isClassAvailable("org/myfirm/myapp/PlayControl") тоже возвращает false.
« Последнее редактирование: Ноябрь 06, 2016, 22:22 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Ноябрь 06, 2016, 23:04 »

Фух... кажется нашёл в чём проблема - посмотрел на пример Qt Notifier, и сделал всё как в нём. Наверно дело сдвинулось после того, как я создал маршрут src/org/myfirm/myapp в каталоге, который задан переменной ANDROID_PACKAGE_SOURCE_DIR проекта. До этого эта скотина просто молча не компилировала файл PlayControl.java, потому что не находила его. Молча... Теперь он стал компилироваться - вылезли сообщения об ошибках. И хоть бы кто-нибудь помог, уточнил, что исходник должен лежать в пути, который совпадает с package - я же специально о таких вещах спрашивал. Два дня коту под хвост из-за разбирательств с этой дебильной джавой. Это ж надо маразм какой - исходник нельзя где угодно положить и маршрут в проекте указать.

Java must die! Qt forewer! Смеющийся
Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #7 : Ноябрь 07, 2016, 13:19 »

Упёрся... Поддержка JNI в Qt позволяет вызывать только статические методы. Но для управления AudioManager-ом нужны не статические вызовы. То есть, нужен объект класса. Сделал так:

Код:
public class PlayControl extends org.qtproject.qt5.android.bindings.QtActivity
{
    public PlayControl(){}

    public void _VolumeUp(){
        AudioManager am = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
        am.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
    }

    public static void VolumeUp(){
        new PlayControl()._VolumeUp();
    }
}
в С++ коде вызываю
Код:
void PlCtrlwidget::volumeUp()
{
#ifdef __ANDROID__
    QAndroidJniObject::callStaticMethod<void>( "org/myfirm/myapp/PlayControl", "volumeUp");
#endif
}
При первом вызове в консоль приложения вылетает одно сообщение о том, что исключение возникло при обработке исключения:
Цитировать
W/dalvikvm(28824): Exception thrown (Ljava/lang/RuntimeException;) while throwing internal exception (Ljava/lang/NoSuchMethodError;
И больше ничего не происходит, дальнейшие вызовы никак не отрабатываются, очевидно JNI-объект умер.

Делал просто пустую функцию на Java, в которой ничего нет - при вызове получаю это же сообщение. Всё, дальше не знаю, что с этим грёбаным (литературное выражение, встречается у Солженицына в "Один день Ивана Денисовича") JNI делать.
« Последнее редактирование: Ноябрь 07, 2016, 13:48 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Ноябрь 07, 2016, 13:39 »

Всё, дальше не знаю, что с этим грёбанным (литературное выражение, встречается ..
Встречается или нет - но "н" там точно одно
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #9 : Ноябрь 07, 2016, 13:49 »

Всё, дальше не знаю, что с этим грёбанным (литературное выражение, встречается ..
Встречается или нет - но "н" там точно одно
Есть вариант, когда два н - "грёбанный в рот". Но ладно уж, пусть будет одно.
Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #10 : Ноябрь 07, 2016, 14:49 »

Вызов работает

Код:
public static void VolumeUp(){
        return 101;
    }

Код:
void PlCtrlwidget::volumeUp()
{
#ifdef __ANDROID__
    qDebug()<<QAndroidJniObject::callStaticMethod<jint>( "org/myfirm/myapp/PlayControl", "volumeUp");
#endif
}

печатает 101. Валится при попытке вызвать статический метод из не статического.

Код:
public static int VolumeUp(){
        new PlayControl()._VolumeUp();
        return 101;
    }

Код:
void PlCtrlwidget::volumeUp()
{
#ifdef __ANDROID__
    qDebug()<<QAndroidJniObject::callStaticMethod<jint>( "org/myfirm/myapp/PlayControl", "volumeUp");
#endif
}

сначала напечатал случайное число и выдал то же сообщение об исключении, а при последующих вызовах выдаёт 0.

Код:
public static int PlayPauseDn(){
        PlayControl p = new PlayControl();
        p._PlayPauseDn();
        return 202;
    }

разумеется та же фигня.

Если создать объект в С++ коде

Код:
    public int _VolumeUp(){
        return 111;
    }
Код:
void PlCtrlwidget::VolumeUp()
{
#ifdef __ANDROID__
    QAndroidJniObject o("org/myfirm/myapp/PlayControl");
    qDebug()<<o.callMethod<jint>( "_VolumeUp" );
#endif
}

Исключение не вываливается, но и ничего не вызывается - печатает 0.

ЗНАТОКИ JAVA, КАК ВЫЗВАТЬ НЕ СТАТИЧЕСКИЙ МЕТОД КОРРЕКТНО?
« Последнее редактирование: Ноябрь 07, 2016, 18:08 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #11 : Ноябрь 07, 2016, 16:57 »

Трындец какой-то...

Код:
public int _VolumeUp(){
        return 101;
    }
Код:
void PlCtrlwidget::volumeUp()
{
#ifdef __ANDROID__
    QAndroidJniObject a = QtAndroid::androidActivity();
    qDebug()<<a.isValid()<<a.callMethod<jint>( "_volumeUp");
#endif
}

печатает true 0, исключения нет.

Тупик.
« Последнее редактирование: Ноябрь 07, 2016, 18:03 от Гурман » Записан

2^7-1 == 127, задумайтесь...
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #12 : Ноябрь 07, 2016, 17:56 »

а это законно — возвращать что-либо из void метода?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #13 : Ноябрь 07, 2016, 18:03 »

а это законно — возвращать что-либо из void метода?
там на самом деле int, другое объявление в форум скопировал

исправил
« Последнее редактирование: Ноябрь 07, 2016, 18:06 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #14 : Ноябрь 07, 2016, 22:44 »

В конце концов получилось вызывать AudioManager из статического метода и покрутить громкость Qt-шным кнобом на экране планшета. Полный код того, что у меня заработало. Может тут есть что-то лишнее, пусть знатоки покажут.

Код:
package org.myfirm.myapp;

import org.qtproject.qt5.android.bindings.QtApplication;
import org.qtproject.qt5.android.QtNative;
import android.media.AudioManager;
import android.content.Context;

public class PlayControl extends org.qtproject.qt5.android.bindings.QtActivity
{
    private static AudioManager a() {
        return (AudioManager) QtNative.activity().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
    }

    public static void VolumeUp(){
        a().adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
    }

    public static void VolumeDn(){
        a().adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
    }
}

Но обратиться к не статитческим методам JNI-класса - ни в какую. Если у кого-то получится работающий вариант, просьба в студию.
Записан

2^7-1 == 127, задумайтесь...
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.124 секунд. Запросов: 22.