应用程序不要求在MacOS 10.14 Mojave中访问麦克风的权限 [英] Application doesn't ask for permission to access microphone in MacOS 10.14 Mojave

查看:171
本文介绍了应用程序不要求在MacOS 10.14 Mojave中访问麦克风的权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是开发用于飞行模拟的应用程序的团队的一部分.这些应用程序之一也在MacOS上运行,并且需要访问麦克风才能与在线虚拟空中交通管制进行通信. 从MacOS 10.14开始,麦克风访问不再起作用.过去,它可以在任何以前的MacOS版本中完美运行.我已经读过,从10.14开始,MacOS会询问用户权限,但是此对话框永远不会出现.使用portaudio作为音频库,可以成功打开音频输入流.没有警告,没有错误,也没有指出问题.它只是不返回任何音频输入.

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.

我了解到,许多其他项目(甚至是商业项目)也存在类似的问题.但是我找不到他们最终如何解决的. 我知道该应用捆绑包需要在Info.plist中添加特定键

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>

但这没有帮助. 其他人则建议添加<key>CFBundleDisplayName</key>可以解决此问题.但事实并非如此.

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

也许值得一提的是,该应用程序未签名.这是一个业余时间的业余项目,我不愿意为苹果的代码签名过程每年花费99美元.可能是罪魁祸首吗?

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?

欢迎任何建议或想法.

作为临时的解决方法,我们告诉用户通过控制台从应用程序捆绑包中启动二进制文件,从而解决了该问题.但是我也想为应用程序捆绑包本身正确地修复它.

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.

推荐答案

从10.14开始,MacOS会询问用户权限,但此对话框永远不会出现

这正是我的问题. Mac Mojave和Catalina中有一个严重的错误.

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

就我而言,我的客户在Catalina上面临此问题.我通过JNLP启动JAR.由于最新版本的MacOS中与安全相关的更改,应用程序应该获得访问麦克风,屏幕记录,全盘访问等的权限.在Java应用程序(通过JNLP运行)的情况下,理想情况下,应该寻求许可的是Java.但是,这不会发生.我的用户没有看到询问麦克风许可的对话框.他们甚至尝试使用最新的Java版本8.仍然没有运气.我挣扎了很多天.终于,这对我有用:

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:

我检测OS是否是MacOS Cataline,如果是,我只是再次使用javaws启动同一JNLP.为了避免递归,只有在我第一次检测到applet时才执行此操作.这是代码:

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:

以下是完整的代码:

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;             
}

这篇关于应用程序不要求在MacOS 10.14 Mojave中访问麦克风的权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆