0

問題: ユーザーが写真を選択できるようにするインテントを使用しています。デバイス上の画像から写真を選択すると、ExifInterface を使用して緯度と経度を取得できます。ただし、Google フォトから写真を選択すると、返された 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のアドバイスを使用して、コードを更新して、最初にビットマップに変換せずにストリームからファイルに直接書き込むようにしました。コードは次のようになります ( inは Google フォトの 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();
    }

ただし、緯度と経度はまだ null です (ここでも、写真に位置データが存在することを確認しました)。ExifInterface の唯一の値は、LightSource = 0、Orientation = 1、ImageLength = 3264、MeteringMode = -1、および ImageWidth = 2448 です。

4

1 に答える 1

0

これを使用して、ストリームをローカルファイルに書き込んで写真を取得しています。

なんとひどいコードでしょう。

コンテンツのローカル ファイル コピーを作成する場合:

  1. を呼び出しopenInputStream()て、Google フォトなどから取得しContentResolverた を渡しますUri

  2. ファイルを置きたい場所に自分自身OutputStreamを置きます

  3. 通常の Java I/O を使用して から にコピーしますInputStreamOutputStream

これははるかに高速でメモリの消費が少ないだけでなく、目的のために EXIF ヘッダーを保持します。その後、 を使用ExifInterfaceしてそれらにアクセスできます。

于 2016-05-11T23:21:41.093 に答える