代码之家  ›  专栏  ›  技术社区  ›  Gauthier

android q:通过mediastore获取画廊的位置信息

  •  0
  • Gauthier  · 技术社区  · 6 年前

    查看android q中引入的存储访问更改 here ,默认情况下,位置信息现在被编辑。

    谷歌让我们打电话 setRequireOriginal() 以媒体的uri作为参数的“mediastore”对象。当您一个接一个地获取媒体时,这是可行的,但是当我们查询整个库的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 是否在清单中添加了权限?

    0 回复  |  直到 6 年前
        1
  •  3
  •   Nicole Borrelli dudi    6 年前

    不幸的是,mediastore.images.media.latitude和mediastore.images.media.longitude是 deprecated in Android Q .

    The work around 因为这是用来 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 许可。