【问题标题】:ALBUM_ART column is deprecated from API 29 and so on, how to obtain path?API 29 等已弃用 ALBUM_ART 列,如何获取路径?
【发布时间】:2020-01-21 15:16:09
【问题描述】:

我们目前正在使用:MediaStore.Audio.AlbumColumns.ALBUM_ART 获取专辑封面的路径,并且正在成功获取路径,但在像素 3a (Android 10) 上除外。经过一些研究,ALBUM_ART 已弃用 API 29 及以上,如下所示:Here

在此链接中它说:“应用程序可能没有文件系统权限来直接访问此路径。应用程序不应尝试直接打开此路径,而应使用 ContentResolver#loadThumbnail 来获得访问权限。”

我的问题是:
1)我已经在应用程序清单上说明了外部存储访问权限(READ_EXTERNAL_STORAGE),并且在应用程序内导航时请求权限。为了获得路径,我必须提供哪些权限才能访问专辑封面?

2) 我似乎无法在线找到 loadThumbnail 上的任何内容(甚至通过代码在 ContentResolver 类上都找不到,而我正在使用目标并编译 SDK 29),如果 1) 无法完成,那该怎么办我使用 loadThumbnail,为什么它没有显示在代码上?

提前致谢。

【问题讨论】:

  • 作为 Android Q 范围存储功能的一部分,Google 宣布 SAF(存储访问框架)将取代正常的存储权限。这意味着即使您尝试使用存储权限,它也只会授予对要使用的文件和文件路径的特定类型文件的访问权限

标签: android deprecated android-10.0 albumart


【解决方案1】:

为了使用 ContentResolver 的方法,请确保您已经安装了最新的 SDK 和相关工具,并在您的代码中首先实例化一个 ContentResolver 对象,然后相应地使用它:

public class MainActivity extends AppCompatActivity {
    public ContentResolver resolver;
    Bitmap albumArt;
    Size size;
    Uri uriOfItem;

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

        resolver = new ContentResolver(this) {
            @NonNull
            @Override
            public Bitmap loadThumbnail(@NonNull Uri uri, @NonNull Size size, @Nullable CancellationSignal signal) throws IOException {
                return super.loadThumbnail(uri, size, signal);
            }
        };
        //uriOfItem = uri of your file
        size = new Size(100, 100);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                albumArt = resolver.loadThumbnail(uriOfItem, size, null);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

编辑:当谈到你的第一个问题时,@Rj_Innocent_Coder 是否不介意我在这里包括他的评论:

作为 Android Q 的范围存储功能的一部分,Google 宣布 SAF(存储访问框架)将取代正常的存储权限。这意味着即使您尝试使用存储权限,它也只会授予对特定类型文件的访问权限,以便使用 File 和 file-path

编辑 2:@hetoan2 发表评论后,我再次检查文档,我注意到 ContentResolver 是抽象的,因此无法使用 ContentResolver.loadThumbnail() 作为方法调用。 这意味着在活动中您也可以简单地使用以下内容

Bitmap albumArt = getContentResolver().loadThumbnail(uriOfFile, sizeOfAreaThatDisplaysThumbnail, cancellationSignalOrNull);

【讨论】:

  • 我认为没有必要在ContentResolver类中重载loadThumbnail方法。另外值得注意的是,传递给 loadThumbnail 方法的 Size 对象应该是专辑封面位图的所需输出大小(匹配您将其加载到的任何视图)。此外,应该为
  • @hetoan2 这对我来说也很奇怪,但这是我设法在我的 Android 工作室中看到该方法的唯一方法。至于参数,我没有费心解释它们,因为 OP 已经有指向最好解释它们的文档的链接。
  • 不使用loadThumbnail就没有别的办法了吗?如果我在构建工具 28(没有 loadThumbnail)中,使用 api 29 电话怎么办? (Android 10)
  • @Serge 如果 Build 版本低于 29,你仍然可以使用 MediaStore
  • 我需要该路径,因为它被发送到一些扬声器(反过来定期发回其所有元数据,包括此路径),然后应用程序使用此路径获取专辑封面。有可能的解决方法,但这些都需要对应用程序进行重大更改。理想的情况是拥有这条路!奇怪的是你不能得到这个路径 29+,如果是因为权限(正如他们在我上面发布的文档中所说的那样),那么 android 应该有一些方法允许它在清单中,所以我们可以获得那个路径..
【解决方案2】:

对于在这里遇到问题的其他人,这是对我有用的解决方案:

if(android.os.Build.VERSION.SDK_INT >= 29)
{
    val album = "Name Of Album"
    val artist = "Name of Artist"
    // Determine album ID first
    val cursor = context.contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
                MediaStore.Audio.Albums.ALBUM_ID,
                "${MediaStore.Audio.Albums.ALBUM} = '$album' AND 
                 ${MediaStore.Audio.Albums.ARTIST} = '$artist'"
                 ,null,null)
    val uri = if(cursor != null && cursor.count > 0)
    {
        cursor.moveToFirst()
        ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, cursor.getString(0).toLong())
    }
    else
    {
        // Dummy URI that will not return an image
        // If you end up here, the album is not in the DataStore
        MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI
    }
    val bm = try
    {
        // Set size based on size of bitmap you want returned
        context.contentResolver.loadThumbnail(uri, Size(50,50), null)
    }
    catch(e: java.lang.Exception)
    {
        // Return default image indicating no image available from DataStore
        BitmapFactory.decodeResource(context.resources, R.drawable.no_image)
    }
}

【讨论】:

    【解决方案3】:

    试试这个,它将使用 glide imageView 工作和加载

    int thumbColumn = audioCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns._ID);
       int _thumpId = audioCursor.getInt(thumbColumn);
       imgFilePath = "content://media/external/audio/albumart/"+_thumpId;  
       audioCursor.moveToPosition(i);
      Glide.with(getContext()).load(imgFilePath).placeholder(R.drawable.missed).into(tracksAlbumArt);
    

    更新 Andriod Studio 最新 4.2.X 和 targetSdkVersion 到 30

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 2019-11-11
      相关资源
      最近更新 更多