c语言播放手机安卓系统默认铃声的代码举例?
时间: 2024-01-19 18:01:54 浏览: 155
以下是一个使用C语言在Android系统上播放默认铃声的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>
#include <android/native_activity.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#define LOG_TAG "RingtonePlayer"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
//声明OpenSLES会话接口对象、音频播放器对象和回调接口
SLObjectItf engineObject;
SLEngineItf engineEngine;
SLObjectItf outputMixObject;
SLObjectItf audioPlayerObject;
SLPlayItf audioPlayerPlay;
SLAndroidSimpleBufferQueueItf audioPlayerBufferQueue;
//声明默认铃声ID和缓存大小
static const char defaultRingtoneUri[] = "content://settings/system/ringtone";
short buffer[4096];
//声明C函数,用于从Java代码调用
JNIEXPORT void JNICALL Java_com_example_ringtoneplayer_RingtonePlayer_playRingtone(JNIEnv* env, jobject thiz)
{
SLresult result;
//初始化OpenSLES引擎
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
//初始化混音器对象
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
//初始化音频播放器对象
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_44_1, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN };
SLDataSource audioSrc = { &loc_bufq, &format_pcm };
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
SLDataSink audioSnk = { &loc_outmix, NULL };
const SLInterfaceID ids[1] = { SL_IID_BUFFERQUEUE };
const SLboolean req[1] = { SL_BOOLEAN_TRUE };
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &audioPlayerObject, &audioSrc, &audioSnk, 1, ids, req);
result = (*audioPlayerObject)->Realize(audioPlayerObject, SL_BOOLEAN_FALSE);
result = (*audioPlayerObject)->GetInterface(audioPlayerObject, SL_IID_PLAY, &audioPlayerPlay);
result = (*audioPlayerObject)->GetInterface(audioPlayerObject, SL_IID_BUFFERQUEUE, &audioPlayerBufferQueue);
//打开默认铃声文件
jclass contextClass = (*env)->FindClass(env, "android/content/Context");
jfieldID systemFieldID = (*env)->GetStaticFieldID(env, contextClass, "SYSTEM_SERVICE", "Ljava/lang/String;");
jstring stringObj = (*env)->NewStringUTF(env, "audio");
jobject audioManagerObj = (*env)->CallObjectMethod(env, thiz, (*env)->GetStaticMethodID(env, contextClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"), stringObj);
jclass audioManagerClass = (*env)->GetObjectClass(env, audioManagerObj);
jmethodID getRingtoneURIID = (*env)->GetMethodID(env, audioManagerClass, "getRingtoneUri", "(I)Landroid/net/Uri;");
jobject ringtoneURI = (*env)->CallObjectMethod(env, audioManagerObj, getRingtoneURIID, 1);
jstring ringtoneUriString = (jstring)(*env)->CallObjectMethod(env, ringtoneURI, (*env)->GetMethodID(env, (*env)->FindClass(env, "android/net/Uri"), "toString", "()Ljava/lang/String;"));
const char* ringtonePath = (*env)->GetStringUTFChars(env, ringtoneUriString, 0);
//打开音频文件,并将缓存数据填充到音频播放器对象的缓存队列
FILE* file = fopen(ringtonePath, "rb");
if (file == NULL) {
LOGE("Failed to open file");
return;
}
fseek(file, sizeof(short) * 44, SEEK_SET);
while (1) {
result = fread(buffer, sizeof(short), 4096 / sizeof(short), file);
if (result < 1) {
break;
}
result = (*audioPlayerBufferQueue)->Enqueue(audioPlayerBufferQueue, buffer, result * sizeof(short));
}
//开始播放音频
result = (*audioPlayerPlay)->SetPlayState(audioPlayerPlay, SL_PLAYSTATE_PLAYING);
result = (*audioPlayerBufferQueue)->RegisterCallback(audioPlayerBufferQueue, playerCallback, NULL);
result = (*audioPlayerBufferQueue)->Enqueue(audioPlayerBufferQueue, buffer, 0);
}
//回调函数,用于处理缓存队列已被耗尽的情况
void playerCallback(SLAndroidSimpleBufferQueueItf queue, void* context)
{
}
阅读全文