0

问题:我正在使用允许用户选择照片的意图。当他们从设备上的图像中选择照片时,我可以使用 ExifInterface 获取纬度和经度。但是,当他们从 Google Photos 中选择照片时,我无法从返回的 uri 中获取地理位置。

详细信息:我使用的意图如下所示:

Intent intent = new Intent();
    // Show only images, no videos or anything else
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    // Always show the chooser (if there are multiple options available)
    startActivityForResult(Intent.createChooser(intent, "Select Pictures"), PICK_IMAGES_REQUEST);

当用户从 Google 相册中选择一张未存储在设备上的照片时,Google 相册首先会下载该照片并返回一个不包含设备位置的 URI。我正在使用它将流写入本地文件以获取照片。然后我尝试使用 ContentResolver 从流中获取拍摄日期、纬度和经度,如下所示:

Cursor cursor = context.getContentResolver().query(uri,
            new String[] {
                    MediaStore.Images.ImageColumns.DATE_TAKEN,
                    MediaStore.Images.ImageColumns.LATITUDE,
                    MediaStore.Images.ImageColumns.LONGITUDE
            }, null, null, null);

    if (null != cursor) {
        if (cursor.moveToFirst()) {
            int dateColumn = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN);
            photoItem.date = new Date(cursor.getLong(dateColumn));

            int latitudeColumn = cursor.getColumnIndex(MediaStore.Images.ImageColumns.LATITUDE);
            double latitude = cursor.getDouble(latitudeColumn);

            int longitudeColumn = cursor.getColumnIndex(MediaStore.Images.ImageColumns.LONGITUDE);
            double longitude = cursor.getDouble(longitudeColumn);
            photoItem.photoGeoPoint = new LatLng(latitude, longitude);
        }
        cursor.close();
    }

这适用于拍摄日期。但是纬度和经度始终为0。我已经验证我正在尝试使用的照片在exif中嵌入了地理位置。有任何想法吗?

--编辑--

因此,使用@CommonsWare 的建议,我更新了代码以直接从流写入文件,而无需先将其转换为位图。代码如下所示(其中来自 Google Photos contentResolver 的 InputStream):

try {
        File outputDir = AppState.getInstance().getCacheDir();
        File outputFile = File.createTempFile("tempImageFile", ".jpg", outputDir);
        OutputStream out = new FileOutputStream(outputFile);
        byte[] buf = new byte[1024];
        int len;
        while((len=in.read(buf))>0){
            out.write(buf,0,len);
        }
        out.close();
        in.close();
        ExifInterface exif = new ExifInterface(outputFile.getPath());
        Logger.d(LOG_TAG, "lat is: " + exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
        Logger.d(LOG_TAG, "lon is: " + exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
    } catch (Exception e) {
        e.printStackTrace();
    }

但是纬度和经度仍然为空(再次,我已经验证照片中存在位置数据)。ExifInterface 中的唯一值是 LightSource = 0、Orientation = 1、ImageLength = 3264、MeteringMode = -1 和 ImageWidth = 2448。

4

1 回答 1

0

我正在使用它将流写入本地文件以获取照片。

天哪,多么糟糕的代码。

如果要制作内容的本地文件副本:

  1. 调用openInputStream()一个ContentResolver,传入Uri你从谷歌照片或任何地方得到的

  2. 让自己OutputStream知道你想把文件放在哪里

  3. 使用普通 Java I/OInputStreamOutputStream

这不仅速度更快,内存占用更少,而且为了您的目的,它保留了 EXIF 标头。然后,您可以使用ExifInterface来访问这些。

于 2016-05-11T23:21:41.093 回答