Ошибка разрешения визуализатора Android

Я работаю над простым приложением визуализатора, которое слушает вывод звука, производит FFT(обрабатывается API визуализатора), выполняет небольшую математику и отправляет информацию по беспроводной связи. У меня проблемы с запуском Visualizer API на Android 8.0 на Oneplus3, но он отлично работает на обоих симулированных телефонах с Android 6.0 и 8.0.

Вот как я запрашиваю разрешения, которые, по моему мнению, мне нужны, сначала в манифесте:

<manifest>
    <application>
        ...rest of application...
    </application>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

</manifest>

Далее я запрашиваю некоторые разрешения во время выполнения:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTextMessage = (TextView) findViewById(R.id.message);
    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

    if (ContextCompat.checkSelfPermission(getApplicationContext(), permission.MODIFY_AUDIO_SETTINGS) == PackageManager.PERMISSION_DENIED)
        Log.d("App", "No MODIFY_AUDIO_SETTINGS" );
    else
        Log.d("App", "Yes MODIFY_AUDIO_SETTINGS" );
    if (ContextCompat.checkSelfPermission(getApplicationContext(), permission.RECORD_AUDIO) == PackageManager.PERMISSION_DENIED)
        Log.d("App", "No RECORD_AUDIO" );
    else
        Log.d("App", "Yes RECORD_AUDIO" );

    Log.d("App","Requesting permissions" );
    ActivityCompat.requestPermissions( this, new String[]
            {
                    permission.MODIFY_AUDIO_SETTINGS,
                    permission.RECORD_AUDIO
            },1 );
    Log.d("App","Requested perms");
}

Я считаю, что это должно напечатать текущее состояние разрешений, а затем запросить все разрешения, которые мне нужны. При новой установке он запрашивает RECORD_AUDIO ( MODIFY_AUDIO_SETTINGS не является опасным разрешением и, по-видимому, предоставляется автоматически). Асинхронно это называется:

public void onRequestPermissionsResult (int requestCode,
                                 String[] permissions,
                                 int[] grantResults)
{
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    boolean success = true;
    for( int i = 0; i < permissions.length; ++i ) {
        if (grantResults[i] == PackageManager.PERMISSION_GRANTED ) {
            Log.d("App",permissions[i]+" granted");
        } else {
            Log.d("App",permissions[i]+" denied");
            Toast.makeText(getApplicationContext(), "Needed " + permissions[i], Toast.LENGTH_SHORT).show();
            success = false;
        }
    }
    if( success ) {
        Log.d("App","Setting up visualizer");
    }
}

В Android 8.0 журнал показывает, что у нас есть оба разрешения, и что если мы их запросим, ​​они будут предоставлены. Но когда мы приступим немного позже (запуск визуализатора в настоящее время привязан к нажатию кнопки),

D/App: Yes MODIFY_AUDIO_SETTINGS
D/App: Yes RECORD_AUDIO
D/App: Requesting permissions
D/App: Requested perms
D/AppTracker: App Event: start
D/OpenGLRenderer: HWUI GL Pipeline
D/AppTracker: App Event: stop
I/Adreno: QUALCOMM build                   : 08cdca0, I5f270ba9bc
          Build Date                       : 09/18/17
          OpenGL ES Shader Compiler Version: EV031.20.00.04
          Local Branch                     : 
          Remote Branch                    : refs/tags/AU_LINUX_ANDROID_LA.UM.6.5.R1.08.00.00.312.025
          Remote Branch                    : NONE
          Reconstruct Branch               : NOTHING
I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
I/Adreno: PFP: 0x005ff087, ME: 0x005ff063
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 2
D/App: android.permission.MODIFY_AUDIO_SETTINGS granted
D/App: android.permission.RECORD_AUDIO granted
D/App: Setting up visualizer
D/AppTracker: App Event: start
I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8996.so from the current namespace instead.
E/AudioEffect: set(): AudioFlinger could not create effect, status: -1
E/visualizers-JNI: Visualizer initCheck failed -3
E/Visualizer-JAVA: Error code -3 when initializing Visualizer.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: net.rsaxvc.blequalizer, PID: 15981
                  java.lang.RuntimeException: Cannot initialize Visualizer engine, error: -3
                      at android.media.audiofx.Visualizer.<init>(Visualizer.java:218)
                      at net.rsaxvc.blequalizer.MainActivity.setupVisualizerFxAndUI(MainActivity.java:133)
                      at net.rsaxvc.blequalizer.MainActivity.access$000(MainActivity.java:22)
                      at net.rsaxvc.blequalizer.MainActivity$1.onNavigationItemSelected(MainActivity.java:63)
                      at android.support.design.widget.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:182)
                      at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
                      at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
                      at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
                      at android.support.design.internal.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:95)
                      at android.view.View.performClick(View.java:6289)
                      at android.view.View$PerformClick.run(View.java:24800)
                      at android.os.Handler.handleCallback(Handler.java:789)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6809)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
D/AppTracker: App Event: crash
Application terminated.

При звонке

mVisualizer = new Visualizer(0);

Мы видим: "E/AudioEffect: set(): AudioFlinger не смог создать эффект, состояние: -1", из media/libmedia/AudioEffect.cpp, похоже, что audioFlinger->createEffect не удалось и вернул -1, равное PERMISSION_DENIED, из-за следующего кода в services/audioflinger/AudioFlinger.cpp:

// check audio settings permission for global effects
if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
    lStatus = PERMISSION_DENIED;
    goto Exit;
}

и это в libs/audioflinger/AudioFlinger.cpp:

static bool settingsAllowed() {
#ifndef HAVE_ANDROID_OS
    return true;
#endif
#if AUDIOFLINGER_SECURITY_ENABLED
    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
    return ok;
#else
    if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
        LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
    return true;
#endif
}

Я предполагаю, что нативный код не получает того разрешения, которое видит код Java. Или, что нативный код выполняется как процесс, отличный от самого приложения.

Это похоже на ошибку Android Visualizer только в Android 6.0, где приложение просто не запрашивало разрешения во время выполнения.

1 ответ

Решение

В процессе разработки этого приложения мой телефон обновился до версии Android 8.0. AFAICT, это что-то сломало. Наконец, удаление и переустановка приложения исправили это.

Другие вопросы по тегам