Android, NDK, routage Audio, forçant l'audio à travers le casque

cas d'Utilisation

  • Record Android Headset audio

environnement

  • Samsung Galaxy 5
  • Android 5.0
  • Bureau de Windows OS w/ audio USB périphérique de capture

mise en Œuvre

  • Crochet de l'appareil Android, sortie casque pour le système d'exploitation Windows entrée Ligne
  • enregistrer tout ce qui est envoyé à partir de L'appareil Android

énoncé du problème

  • si vous branchez la prise Audio pendant que l'audio est en lecture sur L'appareil Android la sortie audio de l'appareil est acheminée par la prise casque et l'enregistrement fonctionne correctement
  • une fois la lecture audio(par exemple. une chanson) s'est arrêté sur L'appareil Android, la prochaine fois qu'il va commencer la lecture audio utilisera le haut-parleur de l'appareil plutôt que la prise du casque ( utilisée pour l'enregistrement )

tentative de résolution de problème

  • un outil natif en ligne de commande C++ fonctionnant sous le compte shell (ne peut pas utiliser Java pour cela)
  • charger dynamiquement 'libmedia.si " et de l'appeler par exemple. android:: AudioSystem:: setForceUse (AUDIO_POLICY_FORCE_FOR_MEDIA, AUDIO_POLICY_FORCE_HEADPHONES)
  • rapports logcat:
    • 02-26 10:39:50.418 289 1707 échec de Permission ServiceManager: android.autorisation.MODIFY_AUDIO_SETTINGS from uid=2000 pid=19577
    • 02-26 10:39:50.418 289 1707 demande nécessite android.autorisation.MODIFICATION_AUDIO_SETTINGS

Questions

  • ayant à l'esprit que la solution doit fonctionner sur un dispositif non enraciné
    • Est-il un moyen d'accorder le 'android.autorisation.La permission de modifier la permission de_audio_settings sur le compte 'shell'?
    • Est-il un autre moyen de forcer l' système "à l'échelle de 1519610920" ( et non pas d'application spécifique ) audio dans le casque ?

code snap

            HRESULT forceAudioThroughHeadPhones() {
                typedef int(*SET_FORCE_USE)(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
                struct sigaction sa, osa;
                sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
                sa.sa_sigaction = [](int signo, siginfo_t* psi, void *data)->void { ucontext_t *uc = (ucontext_t *)data; };
                sigaction(SIGILL, &sa, &osa);
                void* hMod = dlopen("libmedia.so", RTLD_LAZY);
                sigaction(SIGILL, &osa, 0);
                if (0 == hMod)
                    return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
                SET_FORCE_USE setForceUse = (SET_FORCE_USE)dlsym(hMod, "_ZN7android11AudioSystem11setForceUseE24audio_policy_force_use_t25audio_policy_forced_cfg_t");
                if (0 == setForceUse)
                    return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
                android::status_t err;
                if (ERROR_SUCCESS != (err = setForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA, AUDIO_POLICY_FORCE_HEADPHONES)))
                    return E_FAIL;
                if (ERROR_SUCCESS != (err = setForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM, AUDIO_POLICY_FORCE_HEADPHONES)))
                    return E_FAIL;
                return S_OK;
            }
  • 'setForceUse' retourne -1, errno est égal à "Zéro".

mise à JOUR:

je reçois le même l'autorisation logcat erreurs lors de l'utilisation de adb shell appel de service ... :

10|shell@klte:/ $ service call media.audio_policy 1 i32 2 
Result: Parcel(ffffffff    '....')
1
demandé sur NadavRub 2015-02-26 11:59:36