Android 10:通过 MediaStore 获取带有位置信息的图库

2023-11-28

查看 Android 10 中引入的存储访问更改here,现在默认编辑位置信息。

Google 要求我们致电setRequireOriginal()在“MediaStore”对象上,以媒体的 uri 作为参数。当您一张一张地获取媒体时,这是可行的,但是当我们查询整个画廊的 ContentResolver 时呢?

请参阅此示例:

String[] projection = {
        MediaStore.Files.FileColumns._ID,
        MediaStore.Files.FileColumns.DATA,
        MediaStore.Files.FileColumns.MEDIA_TYPE,
        MediaStore.Images.Media.DATE_TAKEN,
        MediaStore.Images.Media.WIDTH,
        MediaStore.Images.Media.HEIGHT,
        MediaStore.Images.Media.LATITUDE, // <----- THIS
        MediaStore.Images.Media.LONGITUDE, // <----- THIS
        MediaStore.Images.Media.MIME_TYPE,
};

String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
        + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;

Uri queryUri = MediaStore.Files.getContentUri("external");

Cursor cursor = null;
MediaStore a ;

try {
    cursor = context.getContentResolver().query(queryUri, projection, selection,
            null, MediaStore.Images.Media.DATE_TAKEN + " DESC");


}
catch (NullPointerException ex){
}

从 Q 开始,纬度和经度始终设置为 0。有没有办法获取一批媒体的位置数据(假设ACCESS_MEDIA_LOCATION清单中添加了权限吗?


不幸的是,MediaStore.Images.Media.LATITUDE 和 MediaStore.Images.Media.LONGITUDE 是在 Android Q 中已弃用.

解决办法因为这是使用ExifInterface像这样:

Cursor cursor = null;
try {
    String[] projection = {
            MediaStore.Files.FileColumns._ID,
            MediaStore.Images.Media.DATE_TAKEN,
            MediaStore.Images.Media.WIDTH,
            MediaStore.Images.Media.HEIGHT,
            MediaStore.MediaColumns.TITLE,
            MediaStore.Images.Media.MIME_TYPE,
            MediaStore.Images.Media.LATITUDE,
            MediaStore.Images.Media.LONGITUDE
    };
    cursor = getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            projection,
            null,
            null,
            MediaStore.Images.Media.DATE_TAKEN + " DESC");


    int idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID);
    int titleColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.TITLE);
    int latColumn = BuildCompat.isAtLeastQ() ? -1
            : cursor.getColumnIndexOrThrow(MediaStore.Images.Media.LATITUDE);
    int longColumn = BuildCompat.isAtLeastQ() ? -1
            : cursor.getColumnIndexOrThrow(MediaStore.Images.Media.LONGITUDE);
    while (cursor.moveToNext()) {

        Uri photoUri = Uri.withAppendedPath(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                cursor.getString(idColumn));
        String title = cursor.getString(titleColumn);

        final double[] latLong;
        if (BuildCompat.isAtLeastQ()) {
            photoUri = MediaStore.setRequireOriginal(photoUri);
            InputStream stream = getContentResolver().openInputStream(photoUri);
            if (stream == null) {
                Log.w(TAG, "Got a null input stream for " + photoUri);
                continue;
            }

            ExifInterface exifInterface = new ExifInterface(stream);
            double[] returnedLatLong = exifInterface.getLatLong();
            // If it returns null, fall back to {0.0, 0.0}.
            latLong = returnedLatLong != null ? returnedLatLong : new double[2];

            // After using ExifInterface, the stream should not be reused.
            stream.close();
        } else {
            latLong = new double[]{
                    cursor.getFloat(latColumn),
                    cursor.getFloat(longColumn)
            };
        }

        Log.i(TAG, title + " | lat: " + latLong[0] + " | lng: " + latLong[1]);
    }
} catch (NullPointerException | IOException ex) {
    Log.e(TAG, "Caught exception", ex);
} finally {
    if (cursor != null) {
        cursor.close();
    }
}

这是目前在 Android Q 上获取照片经纬度的唯一方法。

这需要持有ACCESS_MEDIA_LOCATION允许。请注意,此权限不是“用户在设置 UI 中可见”(source),这意味着用户不会看到请求权限的弹出窗口,即使它是运行时权限。这意味着您必须在运行时请求许可(与清单文件相反),但用户不必同意。在此处添加此内容是因为您可能想知道为什么没有显示额外的 UI 弹出窗口。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 10:通过 MediaStore 获取带有位置信息的图库 的相关文章

  • 计算Android设备的PPI

    如何计算 Android 设备的 PPI 最特别的是 Android 平板电脑 请注意 我想计算设备的 PPI 而不是 DPI 就像一二三一样简单 让我们来计算一下PPI to Nexus 5 例如 float LCD Diagonal 4
  • Android webview 滚动不起作用

    我正在尝试在网络视图中向下滚动到页面底部 我正在使用谷歌在其教程中提供的网络视图示例 我正在使用这行代码来尝试滚动 但它不起作用 mWebView pageDown true 关于如何使其以编程方式滚动有什么建议吗 谢谢 public cl
  • 如何强制 Eclipse 将 xml 布局和样式显示为文本?

    我最近升级到带有 ADT 20 0 3 的 Eclipse 4 2 Juno 如果我查看旧项目中的布局或样式 Eclipse 只会向我显示其适当的基于控件的编辑器 我想编辑语法突出显示的 xml 文本 我没有找到将插件的编辑器切换到此模式的
  • Twitter 登录说明

    我想在 Android 中创建一个 Twitter 应用程序 为此 我想创建一个登录页面并登录到 Twitter 为此 我们需要消费者密钥和消费者密钥 这是什么意思 要创建此登录页面 除了 Twitter 帐户之外 我们还需要其他任何东西吗
  • Service 和 IntentService,运行从服务器轮询数据库值的服务哪个更好?

    我读过很多关于Service and IntentService 然而 当做出决定时 我没有足够的信心选择使用哪种类型来创建一个后台服务 该服务将在一定时间间隔内从数据库轮询数据 并在获得所需数据时停止它 因为数据代表请求的状态 例如 订购
  • Android 如何更改 OnTouchListener 上的按钮背景

    你好 我在 xml 中有一个按钮 我正在使用OnTouchListener在我的活动中获得button按下并释放 但问题是 当我按下按钮时背景颜色没有改变 当我延长可能的活动时OnClickListener背景正在改变 任何人都可以告诉我的
  • 播放 SoundCloud 曲目

    我可以在 Android 应用程序中播放 SoundCloud 中的曲目吗 我正在尝试这段代码 但它不起作用 String res https api soundcloud com tracks 84973999 stream client
  • 如何为发布而不是调试创建密钥库?扑

    我按照使用此网站部署 flutter 的步骤进行操作https flutter io android release https flutter io android release 当我运行 flutter build apk 时出现此错
  • AudioTrack、SoundPool 或 MediaPlayer,我应该使用哪个?

    如果我需要能够 播放多个音频文件 具有不同的持续时间 例如 5 到 30 秒 独立设置右 左声道的音量 应用声音效果 如混响 失真 那么 我应该使用哪个 API 另外 我在 AudioTrack API 上找不到太多文档 有谁知道在哪里可以
  • 放置在 NavigationDrawer 顶部的片段

    我正在尝试添加一个PreferenceFragment在我的应用程序中 问题是 它自动放置在我的顶部NavigationDrawer public class SetPreferenceActivity extends Activity O
  • 菜单在片段的 onCreateOptionsMenu 处多次膨胀调用

    我使用 Fragments 当我切换到嵌套 Fragment 时 它实现了public void onCreateOptionsMenu Menu menu MenuInflater inflater 当我到达该嵌套片段时 我的菜单会多次膨
  • 使用 PhoneGap 使 Android 应用程序易于访问(对于残障人士)

    有人有过使用 PhoneGap 使 Android 应用程序可访问的经验吗 至少我们需要使我们的应用程序符合第 508 条规定 我尝试实现一些标准的辅助功能 文本框标签 向 div 添加标题属性等 但是 当在 Android 中使用 Tal
  • Android:滚动 Horizo​​ntalScrollView 时如何禁用 ScrollView 的垂直滚动?

    我正在开发一个带有带有 ScrollView 的 Activity 的 Android 应用程序 其中包含 Horizo ntalScrollView 等内容 当我触摸 Horizo ntalScrollView 时 我想禁用外部 Scro
  • 在 React Native 中调试应用程序崩溃

    我是 React Native 新手 我正在尝试安装 React Native Facebook SDK 以便我可以使用我的应用程序进行 Facebook 登录 我按照此处列出的步骤操作 https tylermcginnis com in
  • 在 Android 中调整可绘制对象的大小

    我正在为进度对话框设置一个可绘制对象 pbarDialog 但我的问题是我想每次调整可绘制的大小 但不知道如何调整 这是一些代码 Handler progressHandler new Handler public void handleM
  • 如何在 Viewpager 中禁用预加载下一页? [复制]

    这个问题在这里已经有答案了 如何在 Viewpager 中禁用页面预加载 I tried viewPager setOffscreenPageLimit 0 但它不起作用 用这个viewPager setOffscreenPageLimit
  • Android:监听状态栏通知

    有没有办法在状态栏被下拉时监听通知 1 用于检测状态栏变化 您可以注册一个监听器来获取系统UI可见性变化的通知 因此 要在您的活动中注册侦听器 Detecting if the user swipe from the top down to
  • Android 中循环事件的星期几和时间选择器

    我想创建一个控件 允许用户在我的 Android 活动中选择一周中的某一天 星期一 和一天中的某个时间 下午 1 00 找不到任何关于此的好帖子 好吧 我想我已经明白了 我只是不喜欢这个解决方案 因为我在一周中的某一天使用的微调器与时间选择
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 获取其他指针的MotionEvent.getRawX/getRawY

    我可以获取其他指针的MotionEvent getRawX getRawY 值吗 MotionEvent getRawX API 参考 http developer android com reference android view Mo

随机推荐