【问题标题】:How to test an Android native code snippet with Codename One?如何使用 Codename One 测试 Android 原生代码片段?
【发布时间】:2016-11-06 08:40:46
【问题描述】:

首先,我习惯于使用 Java 进行编程,这就是我使用 Codename One 来开发移动应用程序的原因。

但有时我会看到一些我对测试感兴趣的 Android“格式”代码。感谢Codename one tutorial,我知道如何设置基本的本机界面。

例如,我想测试这个snippet about real time sound processing。但是,它涉及使用此方法中可用的数据初始化 Android onCreate() 方法中的一些变量,例如 am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); 使用 this,在 Codename One Native Interface 中没有相同的引用。也许我不必使用onCreate() 方法(可以be reached from Codename One)但我不是Android 大师(也不是CN1 大师!),所以我不知道。

因此,我必须进行哪些更改才能在 Codename One 本机界面中测试本机 Android 代码?也许有一种我很高兴听到的方法。

编辑已解决:本机接口实现中使用的代码有效

这是 original Android code 的 Codename One 本机接口实现。实际上,Android 的onCreate() 方法没有被使用,但是其中初始化的东西已经转移到initRecordAndTrack() 方法中,该方法在适合Codename One 的形式时被调用。它使用@akash 描述的相同方法,因此将this 替换为com.codename1.impl.android.AndroidNativeUtil.getActivity()

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.media.MediaPlayer;
import android.content.Context;

public class KestudisNativeInterfaceImpl {

boolean isRecording = false;
AudioManager am = null;
AudioRecord record = null;
AudioTrack track = null;

public void initRecordAndTrack() {
    android.app.Activity ctx = com.codename1.impl.android.AndroidNativeUtil.getActivity();

    am = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
    am.setSpeakerphoneOn(true);
    int min = AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
            min);
//    if (AcousticEchoCanceler.isAvailable())
//    {
//        AcousticEchoCanceler echoCancler =  AcousticEchoCanceler.create(record.getAudioSessionId());
//        echoCancler.setEnabled(true);
//    }
    int maxJitter = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
    track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter,
            AudioTrack.MODE_STREAM);

    (new Thread() {
        @Override
        public void run() {
            recordAndPlay();
        }
    }).start();
}

public void startRecordAndPlay() {
    record.startRecording();
    track.play();
    isRecording = true;
}

public void stopRecordAndPlay() {
    record.stop();
    track.pause();
    isRecording = false;
}

private void recordAndPlay() {
    short[] lin = new short[1024];
    int num = 0;
    am.setMode(AudioManager.MODE_IN_COMMUNICATION);
    while (true) {
        if (isRecording) {
            num = record.read(lin, 0, 1024);
            track.write(lin, 0, num);
        }
    }
}

public boolean isSupported() {
    return true;
}

}

非常感谢,

干杯

【问题讨论】:

    标签: android codenameone


    【解决方案1】:

    看看这个链接 https://www.codenameone.com/how-do-i---access-native-device-functionality-invoke-native-interfaces.html

    在android中this通常是指上下文,并且要访问CN1中的上下文,您可以将this替换为com.codename1.impl.android.AndroidNativeUtil.getActivity()

    希望对你有帮助

    【讨论】:

    • 我还建议在添加本机接口后使用包含源代码,然后在 Android Studio 中调试本机代码,如果事情不起作用codenameone.com/blog/…
    • 谢谢@akash!这就是我在写完问题后也发现的,它有效。我将发布我使用的代码。我已经阅读了你提到的@Shai 的博客文章,如果我需要调试,它可能会在未来变得很方便。感谢您的提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多