2013-03-02 5 views
5

Używam aplikacji AudioManager do odtwarzania dźwięku przez słuchawkę tuż przed wykonaniem połączenia, dlatego używam trybu SetMode aplikacji AudioManager (MODE_IN_CALL).Manipulator AudioManager interferencje MODE_IN_CALL

Nie mam żadnych problemów z wyjątkiem Galaxy S3, gdzie po prawidłowej grze muzyka dzwonek jest bardzo zniekształcony i bardzo głośny. Przeczytałem dokumentację SetMode:

The audio mode encompasses audio routing AND the behavior of the telephony 
layer. Therefore this method should only be used by applications that replace 
the platform-wide management of audio settings or the main telephony application. 
In particular, the MODE_IN_CALL mode should only be used by the telephony 
application when it places a phone call, as it will cause signals from the 
radio layer to feed the platform mixer. 

Podejrzewam, że mogą być sygnały z miksera platformy karmienia warstwą radiową.

Więc kod używam jest tak:

am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 
speakerWasOn = am.isSpeakerphoneOn(); 
speakerPrevMode = am.getMode(); 
bthA2dpWasOn = am.isBluetoothA2dpOn(); 
bthScoWasOn = am.isBluetoothScoOn(); 

if (BluetoothBR.bthOn && BluetoothBR.conectarBluetooth()) { 
    am.setMode(AudioManager.STREAM_VOICE_CALL); 
    am.setBluetoothA2dpOn(true); 
    am.setBluetoothScoOn(true); 

} else { 
    am.setSpeakerphoneOn(false); 
    am.setMode(AudioManager.MODE_IN_CALL); 
} 

Następnie używam MediaPlayer odtworzyć plik .mp3 w oddzielnym wątku:

private OnPreparedListener opl = new OnPreparedListener() { 
    public void onPrepared(MediaPlayer mp) { 
    try { 
     mp.setVolume(1.0f, 1.0f); 
     mp.start(); 

    } catch (Throwable e) { 
     e.printStackTrace(); 
     mp.release(); 
    } 
    } 
}; 

private OnCompletionListener ocl = new OnCompletionListener() { 
    public void onCompletion(MediaPlayer mp) { 
    stop(); 
    } 
}; 

public void run() { 
    synchronized (mp) { 
    FileInputStream fis = null; 
    try { 
     fis = new FileInputStream(getMp3FilePath()); 

     mp.setDataSource(fis.getFD()); 
     mp.setOnPreparedListener(opl); 
     mp.setOnCompletionListener(ocl); 
     mp.prepare(); 
     fis.close(); 

    } catch (Exception e) { 
     mp.release(); 
     if (fis != null) { 
     try { 
      fis.close(); 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
     } 
     } 
    } 
    } 
} 

public void stop() { 
    if (mp != null) { 
    try { 
     mp.stop(); 
     mp.release(); 
     mp.setVolume(0.5f, 0.5f); 
     mp.reset(); 

    } catch (Exception ignored) { 
    } 
    } 

    if (BluetoothBR.bthOn) { 
    BluetoothBR.desconectarBluetooth(); 
    } 
} 

A kiedy muzyka jest wykonywana I zadzwoń:

am.setSpeakerphoneOn(speakerWasOn); 
am.setMode(speakerPrevMode); 
am.setBluetoothA2dpOn(bthA2dpWasOn); 
am.setBluetoothScoOn(bthScoWasOn); 

dzieje się to tylko na Samsung Galaxy S3 (AFAIK) i został przetestowany w S2, Huawei, SonyEricsson i inne i działa poprawnie.

Jakieś pomysły? Dzięki

UPDATE:

I odkryli, że wszystko działa dobrze, jeśli wątek czeka 5 sekund, gdy kończy się muzyka i po ustawieniu Audiomanager do pierwotnego stanu.

am.setSpeakerphoneOn(speakerWasOn); 
am.setMode(speakerPrevMode); 
am.setBluetoothA2dpOn(bthA2dpWasOn); 
am.setBluetoothScoOn(bthScoWasOn); 

long ctime = System.currentTimeMillis(); 
while (System.currentTimeMillis() - ctime < 5000); 
+0

STREAM_VOICE_CALL NIE jest trybem, jego wartością jest 0, więc faktycznie ustawiasz tryb na MODE_NORMAL, który jest równy 0. – behelit

Odpowiedz

1

Miałem ten sam problem. Po zakomentowaniu tej linii:

am.setMode(AudioManager.MODE_IN_CALL); 

Wszystko działało dobrze dla mnie.

Powiązane problemy