2017-06-29 9 views
0

J'ai fait une application Android, qui diffuse la voix à partir du réseau wifi local. Pour écouter et diffuser, j'utilise l'API Opus C dans JNI pour décoder, et OpenSL Audio pour lire. J'appelle le JNI du Service, comme ça.OpenSL audio sur Android arrêter quand je verrouille l'écran 5.0.1 OK 6.0.1 pas OK

public class StreamService extends Service { 

     private NativeReceiver mNativeReceiver; 
... 

@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // Gérer la requête 
     mNativeReceiver = new NativeReceiver(); 
     mCanPlay = mNativeReceiver.init(); 
      mNativeReceiver.startNativeReceiver(); 
    ...   
    return Service.START_NOT_STICKY; 
} 

œuvres de très bien, quand je clique sur mon bouton, ce service est appelé, et je me sonder de mon smartphone Android. MAIS, quand je verrouille l'écran de mon smartphone, le son est comme "coupé", quand je déverrouille le son est en train de jouer. Seulement sur 6.0.X pas sur 5.0.X

Donc, ma première pensée était le paquet réseau a été arrêté, j'ai fait un débogage et mon smartphone continue à recevoir des paquets réseau.

Mon service en cours d'exécution, seul le son est coupé.

Pour la OpenSL JNI, j'utilise ce bout de code:

Pour appeler mon JNI:

public void startNativeReceiver() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
       // set priority 
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
       start(); 
      } 
     }).start(); 
    } 

Et qui appellent ceci:

const int queue_elements_num = 20; 
    const int start_after = 4; 
    SpscCircularQueue *queue = NULL; 

    OpusDecoder *opus_dec = NULL; 
    uint32_t samplerate = 24000; 
    float frame_length = 20; 

    bool player_initialized = false; 
    bool player_started = false; 
    int frames_in_queue = 0; 

    while (!rcv_th_terminate) { 
     ssize_t rcv_len = read(udp_sock, rcv_buf, sizeof(rcv_buf)); 
     if (rcv_len <= 0) { 
      __android_log_print(ANDROID_LOG_WARN, "SMPlayer", 
          "Failed to receive UDP data"); 
      continue; 
     } 
     __android_log_print(ANDROID_LOG_INFO, "SMPlayer", 
          "reading"); 
     if (!player_initialized) { 
      if (rcv_buf[0] != 0x01) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "Unsupported version of SMPlayer " 
            "streaming protocol"); 
       return NULL; 
      } 
      /* initialize decoder */ 
      int opus_err = 0; 
      opus_dec = opus_decoder_create(samplerate, 1, &opus_err); 
      if (!opus_dec) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "unable to initialize OPUS decoder, " 
            "error code - %d", opus_err); 
       return NULL; 
      } 

      /* initialize circular queue */ 
      uint32_t frame_buf_size = samplerate/1000 * frame_length * 2; 
      queue = spsc_circular_queue_alloc(queue_elements_num, frame_buf_size); 
      if (!queue) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "unable to allocate SPSC Circular Queue"); 
       opus_decoder_destroy(opus_dec); 
       return NULL; 
      } 

      /* initialize the play and start the playback */ 
      osl_player_init(queue, samplerate); 
      player_initialized = true; 
     } else { 
      int dec_samples = opus_decode(opus_dec, rcv_buf + 2, rcv_len - 2, 
             (int16_t *)dec_buf, sizeof(dec_buf), 0); 
      if (dec_samples <= 0) { 
       __android_log_print(ANDROID_LOG_ERROR, "SMPlayer", 
            "failed to decode the data"); 
       osl_player_terminate(); 
       spsc_circular_queue_free(queue); 
       opus_decoder_destroy(opus_dec); 
       exit(EXIT_FAILURE); 
      } 

      while (!spsc_circular_queue_push(queue, dec_buf) && !rcv_th_terminate) 
       usleep((useconds_t)(frame_length * 1000.0)); 

      if (!player_started) { 
       frames_in_queue++; 

       if (frames_in_queue == start_after) { 
        osl_player_jumpstart(queue); 
        player_started = true; 
       } 
      } 
     } 
    } 

    osl_player_terminate(); 

    if (empty_buf_cnt) 
     __android_log_print(ANDROID_LOG_DEBUG, "SMPlayer", 
          "Empty buffers played: %" PRIu64, empty_buf_cnt); 

    spsc_circular_queue_free(queue); 
    opus_decoder_destroy(opus_dec); 
} 

Toutes les idées?! Merci un looot !!

EDIT: Sur Android 5.0.1, ça marche, sur Android 6.0.1 ça ne marche pas?! Pourquoi ??

EDIT2: Mes autorisations

<uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 

    <application 
     android:allowBackup="true" 

EDIT 3: Je ne consignent pas, j'écoute seulement

EDIT 4: Après les autorisations de vente, enregistrement audio, aucun changement, sur Android Marshmallow (Samsung S5) quand je verrouille l'écran, mon application est comme en sourdine!

+0

regardez ceci pour vérifier vos permissions et ajouter les nécessaires. https://developer.android.com/training/permissions/requesting.html –

+0

RECORD_AUDIO est une autorisation dangereuse ... vous devez l'ajouter à l'exécution pour corriger dans guimauve –

+0

Je l'ajoute pour essayer, mais je ne pense pas J'ai besoin de cette permission, parce que je n'enregistre pas, mais seulement écouter via le réseau wifi, mais je vais l'essayer rapidement;) – maathor

Répondre

0

Je pense que votre permission expire dans les versions Android 6.0 et supérieures, ainsi vous vérifiez vos permissions si votre permission est dans l'autorisation dangereuse puis donnez-la dynamiquement.

+1

Je ne comprends pas la permission que vous avez? Dans mon manifeste? – maathor