当前位置: 首页 > 面试题库 >

来自文件提供商Uri的Android 7.0通知声音未播放

白嘉志
2023-03-14
问题内容

我正在更改应用程序代码以支持Android
7,但是在我的NotificationCompat.Builder.setSound(Uri)中,从FileProvider传递Uri时,通知没有播放声音,在Android
6中,使用Uri.fromFile()可以正常工作。

mp3文件位于:

/ Animeflv /缓存/.sounds/

这是我的通知代码:

knf.animeflv.RequestBackground

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_not_r)
.setContentTitle(NotTit)
.setContentText(mess);
...
mBuilder.setVibrate(new long[]{100, 200, 100, 500});
mBuilder.setSound(UtilSound.getSoundUri(not)); //int

这是我的UtilSound.getSoundUri(int)

public static Uri getSoundUri(int not) {
        switch (not) {
            case 0:
                return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            default:
                try {
                    File file=new File(Environment.getExternalStorageDirectory()+"/Animeflv/cache/.sounds",getSoundsFileName(not));
                    if (file.exists()) {
                        file.setReadable(true,false);
                        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
                            return FileProvider.getUriForFile(context, "knf.animeflv.RequestsBackground",file);
                        }else {
                            return Uri.fromFile(file);
                        }
                    }else {
                        Log.d("Sound Uri","Not found");
                        return getSoundUri(0);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    return getSoundUri(0);
                }
        }
    }

在AndroidManifest.xml中:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="knf.animeflv.RequestsBackground"
    android:exported="false"
    android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
</provider>

provider_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="_.sounds" path="Animeflv/cache/.sounds/"/>
</paths>

问题答案:

以下是我刚刚发表的博客文章,此处转载是因为,为什么呢?

您可以Notification通过on之类的方法
setSound()在上添加自定义铃声NotificationCompat.BuilderUri正如Stack
Overflow上
的一些人所报道的那样,这需要一个,并在Android
7.0上引起问题 。

如果您使用file: Uri的价值观,他们不再在Android
7.0的工作,如果你targetSdkVersion是24或更高,因为声音Uri是检查是否符合在禁令file:
Uri值。

但是,如果您尝试使用content:
Urifrom等功能FileProvider,则您的声音将无法播放…,因为Android没有对该内容的读取权限。

以下是解决此问题的一些选项。

手术刀:grantUriPermissions()

您始终可以通过上grantUriPermissions()的方法向其他应用授予内容权限Context。挑战在于知道要向 授予权限。

在Nexus 6P(Android 6.0 …仍…)和Nexus 9(Android 7.0)上可以使用的功能是:

grantUriPermission("com.android.systemui", sound,
    Intent.FLAG_GRANT_READ_URI_PERMISSION);

(这里soundUri你使用的是带有setSound()

我不能说这是否适用于所有设备和所有Android OS版本。

断头台:没有更多的用户文件

android.resource作为一种方案,对于的Uri值可以很好地工作setSound()。与其允许用户从文件中选择自己的铃声,不如让他们选择您作为应用程序中的原始资源提供的几种铃声之一。但是,如果这表示丧失了应用程序功能,则您的用户可能会不满意。

轴:使用自定义ContentProvider

FileProvider导出时无法使用-启动时崩溃。但是,在这种情况下,唯一content:
Uri不会出现其他问题的方法就是提供者所在的位置exported,并且没有读取访问权限(或者恰好需要某种权限,com.android.systemui或者恰好持有该权限
)。

最后,我会为这个选项添加到 我的StreamProvider,因为一些“只读”提供功能的一部分。

但是,您可以为此选择自己的提供商。

电锯:禁止禁令

以下代码段阻止了所有StrictMode与VM行为有关的检查(即,除主应用程序线程行为外的其他检查),包括对file: Uri值的禁止:

StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().build());

另外,您可以使用自己VmPolicy想要的任何规则来配置自己,而无需调用detectFileUriExposure()

这使您可以file: Uri在任何地方使用值。Google禁止使用的理由很充分file:
Uri,因此从长远来看,尝试避免使用该禁止措施可能会咬伤不幸的身体部位。

核弹:低一点targetSdkVersion

这也消除了对file:
Uri价值的禁止,以及targetSdkVersion24岁以上的孩子选择参加的所有其他行为。值得注意的是,Toast
如果用户进入分屏多窗口模式,这将导致您的应用显示“可能无法使用分屏” 。

真正的解决方案:Android中的修复程序

NotificationManager应呼吁grantUriPermissions() 对我们来说,还是应该给我们一些其他的方式,以联想
FLAG_GRANT_READ_URI_PERMISSIONUri我们使用自定义 Notification声音。
敬请期待进一步的发展。



 类似资料:
  • 我正在从调用firebase api的应用服务器向用户发送数据消息。用户正在接收通知,但通知到达时不会播放声音。 这是代码 有什么问题吗???

  • 我使用了较新的NotificationCompat builder,无法获得发出声音的通知。它将振动并闪烁灯光。android文档中说要设置一种我已经使用过的样式: 但是没有声音? 完整的代码:

  • 我正在试着扮演一个角色。wav文件每次按下鼠标时,程序都会正常启动,但当我点击精灵时,我发现一个错误,有人知道是什么问题吗?我正在使用IntelliJ,SDK 15 这是我试图播放声音的部分 我得到这个错误:

  • 我在我的应用程序中为某些通知添加声音,就像这样: 播放通知声音时,即使将耳机插入手机,也会通过扬声器播放,因此扬声器和耳机都会播放该声音。 如果插上耳机,有没有办法只通过耳机播放声音?

  • 有了一个机器人,我试着用discord在一个音频通道中播放一个音频文件(mp3)。js、ffmpeg和opusscript。 基本上,这就是它的工作原理: 因此,音频播放,但在结束前停止(例如,对于5s音频文件,它在3s后停止)。机器人留在频道中,我可以再次播放,但对于我的所有文件,它在结束前停止。我怎样才能解决这个问题?

  • 大家好, 我有一个基于Java的手机(三星星2 526 0)和它的三个星期,我试图提出一个解决方案,以接收收到的电子邮件通知。手机配置了一个定期检查至少30分钟,但我需要一个更频繁的控制(最多5分钟)。 我已经尝试了无数的解决方案,我想出了最接近的一个,是一个自定义的mujmail midlet,它通过imap支持我的gmail邮箱,多亏了netbeans编辑器。重点是,我修改了mujmail的轮