1.定制需求,合入第三方藍(lán)牙模塊,發(fā)送媒體數(shù)據(jù)傳輸?shù)降谌皆O(shè)備上;
(遇到問(wèn)題:第三方藍(lán)牙模塊發(fā)送數(shù)據(jù)過(guò)到第三方設(shè)備,但是本機(jī)的媒體應(yīng)用還走了當(dāng)前設(shè)備的喇叭,需要切換到耳機(jī)模式)
2.走AudioManager 模塊只能配置當(dāng)前進(jìn)程的媒體輸出方式;
if(mAudioManager==null) {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
}
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
// mAudioManager.setMode(AudioManager.MODE_INVALID);
// mAudioManager.stopBluetoothSco(); //停止藍(lán)牙耳機(jī)
// mAudioManager.setBluetoothScoOn(false); //設(shè)藍(lán)牙ScoOn關(guān)閉,藍(lán)牙耳機(jī)則會(huì)停止
// mAudioManager.setSpeakerphoneOn(false); //設(shè)置外放話筒關(guān)閉
3.通過(guò)AudioSystem設(shè)置時(shí)好像也沒(méi)有效果,當(dāng)設(shè)備走設(shè)備系統(tǒng)藍(lán)牙的時(shí)候才有效;
/*
try {
@SuppressLint("PrivateApi") Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
setForceUse.invoke(null, FOR_COMMUNICATION, FORCE_SPEAKER);
// setForceUse.invoke(null, FOR_MEDIA, FORCE_NONE);
//setForceUse.invoke(null, FOR_COMMUNICATION, FORCE_NONE);
} catch (Exception e) {
e.printStackTrace();
}
*/
通過(guò)日志定位
audio_platform: mode(0),devices(0x2):platform device:OUT_DULSPK(0x4)
4.為了簡(jiǎn)易處理,直接添加一個(gè)屬性配置,來(lái)控制hal層的獲取的通道
\hardware\aw\audio\hal\platform.c
int get_platform_device(audio_mode_t mode, audio_devices_t devices,
const struct platform *platform)
{
struct platform_info *info = platform->info;
int pdev = OUT_NONE;
/* 1. get platform device */
if (devices & AUDIO_DEVICE_BIT_IN) {
audio_devices_t indev = devices & (~AUDIO_DEVICE_BIT_IN);
/* record device */
if (indev & AUDIO_DEVICE_IN_BUILTIN_MIC) {
pdev = (platform->uc & UC_DMIC) ? IN_DMIC : IN_AMIC;
} else if (indev & AUDIO_DEVICE_IN_WIRED_HEADSET) {
pdev = IN_HPMIC;
} else if (indev & AUDIO_DEVICE_IN_ALL_SCO) {
pdev = IN_BTSCO;
} else {
pdev = IN_AMIC;
}
} else {
/* playback device */
int headphone = AUDIO_DEVICE_OUT_WIRED_HEADSET |
AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
pdev = OUT_EAR;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER &&
devices & headphone) {
pdev = (platform->uc & UC_DUAL_SPK) ? OUT_DULSPK_HP : OUT_SPK_HP;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
pdev = (platform->uc & UC_DUAL_SPK) ? OUT_DULSPK : OUT_SPK;
} else if (devices & headphone) {
pdev = OUT_HP;
} else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
pdev = OUT_BTSCO;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
pdev = OUT_HDMI;
} else {
pdev = OUT_SPK;
}
}
/* phone record and playback */
if (AUDIO_MODE_IN_CALL == mode) {
if (devices & AUDIO_DEVICE_BIT_IN) {
pdev = (platform->uc & UC_DPHONE)? IN_DPH_REC : IN_APH_REC;
} else {
pdev = (platform->uc & UC_DPHONE)? OUT_DPH_PLAY : OUT_APH_PLAY;
}
}
/* TODO: force use platform device */
/* add attribute start */
char str[50] = "null";
char djgd_speaker[10];
char djgd_fm_speaker[10];
property_get("persist.sys.djgd_speaker", djgd_speaker, "");
property_get("persist.sys.djgd_fm_speaker", djgd_fm_speaker, "");
ALOGV("persist.sys.djgd_speaker :%s(%d)",djgd_speaker, strstr(djgd_speaker, "1"));
ALOGV("persist.sys.djgd_fm_speaker :%s(%d)",djgd_fm_speaker, strstr(djgd_fm_speaker, "1"));
if (strstr(djgd_speaker, "1") !=NULL || strstr(djgd_fm_speaker, "1") !=NULL)
{
pdev = OUT_HP;
}
/* add attribute end*/
ALOGV("mode(%#x),devices(%#x):platform device:%s(%#x)",
mode, devices, pdev2str(str, pdev), pdev);
return pdev;
}
5.經(jīng)測(cè)試發(fā)現(xiàn),只修改上面的位置還會(huì)有些問(wèn)題,就是當(dāng)有媒體還在播放時(shí)會(huì)有占用通道沒(méi)有沒(méi)被釋放,導(dǎo)致媒體通道沒(méi)有切花過(guò)來(lái);
Index: \hardware\aw\audio\hal\audio_hw.c
===================================================================
*/
#define LOG_TAG "audio_hw_primary"
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
+static int m_platform_device = 4;
+
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
size_t bytes)
{
@@ -999,6 +1001,24 @@
int platform_device = 0;
ALOGV("out_write");
+ platform_device = get_platform_device(adev->mode, adev->out_devices,
+ adev->platform);
+ ALOGV("platform_device :%d,m_platform_device %d",platform_device,m_platform_device);
+ if (platform_device != m_platform_device )
+ {
+ m_platform_device=platform_device;
+ ALOGV("m_platform_device :%d",m_platform_device);
+ /*pthread_mutex_lock(&out->lock);
+ out->standby = 0;
+ pthread_mutex_lock(&adev->lock);
+ ret = start_output_stream(out);
+ pthread_mutex_unlock(&adev->lock);*/
+ out_standby(&out->stream.common);
+ usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
+ out_get_sample_rate(&out->stream.common));
+ pthread_mutex_unlock(&out->lock);
+ return bytes;
+ }
pthread_mutex_lock(&out->lock);
if (out->standby) {
out->standby = 0;
@@ -1021,6 +1041,7 @@
platform_plugins_process_read_write(adev->platform, ON_OUT_WRITE,
out->config, (void*)buffer,
out_frames * frame_size);
+
/* audio dump data write */
debug_dump_data(buf, out_frames * frame_size, &out->dd_write_out);
if(out->equalizer != NULL)