Application doesn't ask for permission to access microphone in MacOS 10.14 Mojave

会有一股神秘感。 提交于 2020-05-13 08:05:15

问题


I'm part of a team developing applications for flight simulation. One of these applications is running also on MacOS and needs access to the microphone to communicate with online virtual air traffic control. Starting with MacOS 10.14 microphone access is no longer working. It used to work perfectly in any previous version of MacOS. I've read that starting with 10.14, MacOS will ask the user for permission, but this dialog never appears. Using portaudio as the audio library, audio input stream is successfully opened. No warning, no errors, nothing pointing to a problem. It just doesn't return any audio input.

I learned that many other projects - even commercial ones - have similar problems. But I couldn't find out how they eventually solved it. I'm aware that the app bundle needs to add a specific key in Info.plist

<key>NSMicrophoneUsageDescription</key>
<string>This application needs access to your Microphone virtual ATC.</string>

but this didn't help. Others suggested that adding <key>CFBundleDisplayName</key> fixes the problem. But it didn't.

It is maybe worth to note that the application is not signed. Its is a spare time hobby project for which I'm not willing to spend 99 $ a year for Apple's code signing process. Could that be the culprit?

Any advice or ideas are welcome.

As a temporary workaround, we told users to start the binary from the app bundle via console, which fixes the problem. But I would like to properly fix it also for the app bundle itself.


回答1:


The solution that worked for me is to reset PRAM. There are some system settings that are stored in there.

During boot up, press and hold Command + Option + P + R. The computer will restart and when you hear the startup sound the 2nd time, you may release.

Run the app again, and the permission dialog should show up.




回答2:


starting with 10.14, MacOS will ask the user for permission, but this dialog never appears

This was exactly my problem. There is this serious bug in Mac Mojave and Catalina.

In my case my customers were facing this issue on Catalina. I launch JAR through JNLP. Because of security related changes in latest versions of MacOS, applications should get permissions to access microphone, screen recording, full disk access etc. In case of Java applications (running through JNLP) ideally it's Java which should be seeking for permission. However, it doesn't happen. My users were not seeing dialog asking for microphone permission. They tried even with latest Java version 8. Still no luck. I struggled for many many days. Finally this is what has worked for me:

I detect if OS is MacOS Cataline and if yes, I just launch same JNLP again using javaws. To avoid recursion I do this only when I detect applet running first time. Here is code:

Here is complete code:

private boolean IsAlreadyRunning()
{
    System.out.println("Checking if applet already running by opening applet locked file");
    try
    {
        file_locked_by_applet=new File("my_java_application.lock");
        // createNewFile atomically creates a new, empty file ... if and only if a file with this name does not yet exist. 

        System.out.println("Locked file path: " + file_locked_by_applet.getAbsolutePath());

        if (file_locked_by_applet.createNewFile())
        {
            System.out.println("Opened applet locked file successfully");
            file_locked_by_applet.deleteOnExit();
            return false;
        }

        System.out.println("Cannot open applet locked file. Applet might be already running.");
        return true;
    }
    catch (IOException e)
    {
        System.out.println("Exception while opening applet locked file. Applet might be already running.");
        e.printStackTrace();
        return true;
    }
}

private boolean IsOSMacCatalina()
{
    System.out.println("Checking if current operating system is MacOS Catalina");
    String OS = System.getProperty("os.name").toLowerCase();
    String OSVersion = System.getProperty("os.version").toLowerCase();      
    String OSArch = System.getProperty("os.arch").toLowerCase();

    System.out.println("OS detected: " + OS);
    System.out.println("OS version detected: " + OSVersion);
    System.out.println("OS arch detected: " + OSArch);

    if (OS.contains ("mac os") && OSVersion.contains("10.15"))
    {   
            System.out.println("Operating system: Mac Catalina detected");
            return true;
    }

    System.out.println("Operating system is not Mac Catalina");
    return false;

}

// Method that first gets invoked by applet at the beginning
public void start() 
{
    super.start();
    System.out.println("Starting applet here");
    System.out.println("JNLP file name: " + System.getProperty("jnlpx.origFilenameArg"));
    System.out.println("JVM command line: " + ManagementFactory.getRuntimeMXBean().getInputArguments());

if ((!IsOSMacCatalina()) || IsAlreadyRunning())
{
    System.out.println("Either OS is not Catalina or applet is already launched with bash and javaws. Continuing with applet...");
}
else
{
    try
    {
        System.out.println("Applet running first time on Mac Catalina. Starting again with bash and javaws");

        // "javaws -wait" causes javaws to start java process and wait for it to exit
        String javawsCommandLine = "javaws -wait \"" + System.getProperty("jnlpx.origFilenameArg").replace("\\","/") + "\"";
        System.out.println("bash javaws command line to run: " + javawsCommandLine);
        // String[] args = new String[] {"bash", "-c", javawsCommandLine}; // Works on Windows where Bash is installed
        String[] args = new String[] {"/bin/bash", "-c", javawsCommandLine};
        System.out.println("---\nStarting bash javaws process withh args:");
        for (String arg: args)
            System.out.println(arg);
        System.out.println("\n---");

        // Runtime.getRuntime() discouraged. Hence we using ProcessBuilder
        // Process proc = Runtime.getRuntime().exec("bash -c \"" + javawsCommandLine + "\"");

        Process proc = new ProcessBuilder(args).start();

        System.out.println("Waiting for bash process to finish");
        proc.waitFor();
        System.out.println("Bash process finished. Deleting instance locked file");
        file_locked_by_applet.delete();
        System.out.println("Stopping applet here");
    }
    catch (java.io.IOException e) 
    {
        e.printStackTrace();
    }
    catch (java.lang.InterruptedException e)
    {
        e.printStackTrace();
    }
    return;             
}


来源:https://stackoverflow.com/questions/55727488/application-doesnt-ask-for-permission-to-access-microphone-in-macos-10-14-mojav

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!