【问题标题】:Detect if another app is requesting the microphone检测是否有其他应用正在请求麦克风
【发布时间】:2017-12-18 19:09:21
【问题描述】:

我在 SO 上看到了多个问题,说无法看到其他应用何时想要使用麦克风 (Unable to access microphone when another app is using it in Android)。但是,我知道这是可能的,因为 Shazam 有一个“自动”功能,可以实现我想要的确切功能:在其他应用程序不使用麦克风时持续收听音频。

目前,当我使用我的应用并使用 Snapchat 等应用时,我无法录制带音频的视频,因为 Snapchat 不会接管麦克风。但是,正如我之前所说,在这种情况下,Shazam 的自动功能可以正常工作。

那么,当其他应用想要使用麦克风时,我该如何收听呢?只要不需要root手机或类似的东西,我就可以使用“黑客”的东西。

编辑: Shazam 从来没有这个功能,他们的应用程序在运行时无法将麦克风让给其他应用程序。

【问题讨论】:

  • 你有解决办法吗?,我正在为此苦苦挣扎
  • @KareemElsayed 我发布了目前最好的解决方案

标签: android audio-recording


【解决方案1】:

这是我目前最好的解决方案。无法监听其他应用程序请求麦克风,因此我创建了一个 UsageStats 检查器,它每 3 秒运行一次,以查看当前打开的应用程序是否具有请求音频的能力。如果您有更好的东西或对此进行改进,请告诉我。

注意:您必须将权限添加到应用清单:

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />

    AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
    int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
            android.os.Process.myUid(), getPackageName());

    if (mode != AppOpsManager.MODE_ALLOWED) {
        Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
        startActivity(intent);
    }

    if (otherAppAudioTimer != null) {
        otherAppAudioTimer.cancel();
    }

    otherAppAudioTimer = new Timer();
    otherAppAudioTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            UsageStatsManager usm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
            long now = System.currentTimeMillis();
            final List<UsageStats> queryUsageStats = usm.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, now - (1000 * 60 * 60), now);
            if (queryUsageStats != null && queryUsageStats.size() > 0) {
                SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>();
                for (UsageStats usageStats : queryUsageStats) {
                    mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
                }
                if (!mySortedMap.isEmpty()) {
                    String currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
                    boolean hasRecordAudio = getPackageManager()
                            .checkPermission(Manifest.permission.RECORD_AUDIO, currentApp)
                            == PackageManager.PERMISSION_GRANTED;

                    if (getApplicationContext().getPackageName().equals(currentApp)) {
                        Log.e("hasAudio", "Current app is self");
                        return;
                    }


                    if (hasRecordAudio) {
                        //the current app can record audio
                    } else {
                        //the current app cannot record audio
                    }

                }
            }
        }
    }, 0, 3000);

【讨论】:

  • 来自the docsPACKAGE_USAGE_STATS。 . .是系统级权限,不会授予第三方应用。然而 。 . .设备用户可以通过设置应用授予权限。
  • @KevinKrumwiede 是的,它不是由 Android 隐式授予的,但在我的代码中,Intent 代码会发出请求以允许该权限(如果用户还没有)。这也是为什么我需要在权限中使用忽略
  • ACTION_USAGE_ACCESS_SETTINGS 的文档说它可能不适用于所有设备。在 Lollipop 的早期,我读到包括三星和 LG 在内的主要制造商已经从他们的许多设备中删除了它。你遇到过这个问题吗?
  • @KevinKrumwiede 不,但这是一个“黑客”,我使用的方法有很多问题,但这是实现我想要的最佳方法。当 Android 提供更好的东西时,我会使用它/更新它(又名广播监听器,就像 AudioManager
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
相关资源
最近更新 更多