Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39c283e9 authored by Julian Mancini's avatar Julian Mancini
Browse files

Display nearest address for Geotagged files

Bug: 64298047
Test: MediaViewTest.java
Change-Id: I114b5fb57d86cfc2c5992c6f248437e0f2c4db1b
parent 74eeb846
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@
    <string name="metadata_composer">Composer</string>
    <!--The album the file is in, Note this is probably MP3 ID3 tags-->
    <string name="metadata_album">Album</string>
    <!-- The address nearest to where a photo was taken -->
    <string name="metadata_address">Location</string>

    <!-- String label for developer/debug file details, specifying which stream types are available. -->
    <string name="debug_stream_types">Stream types</string>
+63 −7
Original line number Diff line number Diff line
@@ -17,8 +17,11 @@ package com.android.documentsui.inspector;

import android.content.Context;
import android.content.res.Resources;
import android.location.Address;
import android.location.Geocoder;
import android.media.ExifInterface;
import android.media.MediaMetadata;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.support.annotation.VisibleForTesting;
@@ -31,6 +34,9 @@ import com.android.documentsui.base.Shared;
import com.android.documentsui.inspector.InspectorController.MediaDisplay;
import com.android.documentsui.inspector.InspectorController.TableDisplay;

import java.io.IOException;
import java.util.function.Consumer;

import javax.annotation.Nullable;

/**
@@ -41,6 +47,7 @@ import javax.annotation.Nullable;
public class MediaView extends TableView implements MediaDisplay {

    private final Resources mResources;
    private final Context mContext;

    public MediaView(Context context) {
        this(context, null);
@@ -52,6 +59,7 @@ public class MediaView extends TableView implements MediaDisplay {

    public MediaView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        mResources = context.getResources();
    }

@@ -61,7 +69,7 @@ public class MediaView extends TableView implements MediaDisplay {

        Bundle exif = metadata.getBundle(DocumentsContract.METADATA_EXIF);
        if (exif != null) {
            showExifData(this, mResources, doc, exif, geoClickListener);
            showExifData(this, mResources, doc, exif, geoClickListener, this::getAddress);
        }

        Bundle video = metadata.getBundle(Shared.METADATA_KEY_VIDEO);
@@ -126,7 +134,8 @@ public class MediaView extends TableView implements MediaDisplay {
            Resources resources,
            DocumentInfo doc,
            Bundle tags,
            @Nullable Runnable geoClickListener) {
            @Nullable Runnable geoClickListener,
            Consumer<float[]> geoAddressFetcher) {

        addDimensionsRow(table, resources, tags);

@@ -135,11 +144,6 @@ public class MediaView extends TableView implements MediaDisplay {
            table.put(R.string.metadata_date_time, date);
        }

        if (MetadataUtils.hasExifGpsFields(tags)) {
            float[] coords = MetadataUtils.getExifGpsCoords(tags);
            showCoordiantes(table, resources, coords, geoClickListener);
        }

        if (tags.containsKey(ExifInterface.TAG_GPS_ALTITUDE)) {
            double altitude = tags.getDouble(ExifInterface.TAG_GPS_ALTITUDE);
            table.put(R.string.metadata_altitude, String.valueOf(altitude));
@@ -178,6 +182,11 @@ public class MediaView extends TableView implements MediaDisplay {
                    String.format(resources.getString(R.string.metadata_iso_format), iso));
        }

        if (MetadataUtils.hasExifGpsFields(tags)) {
            float[] coords = MetadataUtils.getExifGpsCoords(tags);
            showCoordiantes(table, resources, coords, geoClickListener);
            geoAddressFetcher.accept(coords);
        }
    }

    private static void showCoordiantes(
@@ -201,6 +210,53 @@ public class MediaView extends TableView implements MediaDisplay {
        }
    }

    /**
     * Attempts to retrieve an approximate address and displays the address if it can find one.
     * @param coords the coordinates that gets an address.
     */
    private void getAddress(float[] coords) {
        new AsyncTask<Float, Void, Address>() {
            @Override
            protected Address doInBackground(Float... coords) {
                assert (coords.length == 2);
                Geocoder geocoder = new Geocoder(mContext);
                try {
                    Address address = geocoder.getFromLocation(coords[0], // latitude
                            coords[1], // longitude
                            1 // amount of results returned
                    ).get(0);
                    return address;
                } catch (IOException e) {
                    return null;
                }
            }
            @Override
            protected void onPostExecute(@Nullable Address address) {
                if (address != null) {
                    TableDisplay table = MediaView.this;
                    if (address.getMaxAddressLineIndex() >= 0) {
                        String formattedAddress;
                        StringBuilder addressBuilder = new StringBuilder("");
                        addressBuilder.append(address.getAddressLine(0));
                        for (int i = 1; i < address.getMaxAddressLineIndex(); i++) {
                            addressBuilder.append("\n");
                            addressBuilder.append(address.getAddressLine(i));
                        }
                        formattedAddress = addressBuilder.toString();
                        table.put(R.string.metadata_address, formattedAddress);
                    } else if (address.getLocality() != null) {
                        table.put(R.string.metadata_address, address.getLocality());
                    } else if (address.getSubAdminArea() != null) {
                        table.put(R.string.metadata_address, address.getSubAdminArea());
                    } else if (address.getAdminArea() != null) {
                        table.put(R.string.metadata_address, address.getAdminArea());
                    } else if (address.getCountryName() != null) {
                        table.put(R.string.metadata_address, address.getCountryName());
                    }                }
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, coords[0], coords[1]);
    }

    /**
     * @param speed a value n, where shutter speed equals 1/(2^n)
     * @return a String containing either a fraction that displays 1 over a positive integer, or a
+3 −2
Original line number Diff line number Diff line
@@ -83,15 +83,16 @@ public class TableView extends LinearLayout implements TableDisplay {
    }

    /**
     * Puts or updates an value in the table view.
     * Puts or updates a value in the table view.
     */
    @Override
    public void put(@StringRes int keyId, CharSequence value) {
        put(mRes.getString(keyId), value);
    }


    /**
     * Puts or updates an value in the table view.
     * Puts or updates a value in the table view.
     */
    protected KeyValueRow put(CharSequence key, CharSequence value) {
        KeyValueRow row = mRows.get(key);
+24 −3
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.function.Consumer;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class MediaViewTest {
@@ -38,6 +40,10 @@ public class MediaViewTest {
    private TestResources mResources;
    private TestTable mTable;
    private Bundle mMetadata;
    private Consumer<float[]> mGeo = (float[] coords) -> {
        mTable.put(R.string.metadata_address, "1234 Street Street\n"
                + "City, State, 56789");
    };

    @Before
    public void setUp() {
@@ -63,7 +69,7 @@ public class MediaViewTest {
        mResources.strings.put(R.string.metadata_focal_format, "%.2f mm");
        mResources.strings.put(R.string.metadata_iso_format, "ISO %d");
        Bundle exif = mMetadata.getBundle(DocumentsContract.METADATA_EXIF);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, exif, null);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, exif, null, mGeo);

        mTable.assertHasRow(R.string.metadata_dimensions, "3840 x 2160, 8.3MP");
        mTable.assertHasRow(R.string.metadata_date_time, "Jan 01, 1970, 12:16 AM");
@@ -74,6 +80,8 @@ public class MediaViewTest {
        mTable.assertHasRow(R.string.metadata_aperture, "f/2.0");
        mTable.assertHasRow(R.string.metadata_iso_speed_ratings, "ISO 120");
        mTable.assertHasRow(R.string.metadata_focal_length, "4.27 mm");
        mTable.assertHasRow(R.string.metadata_address, "1234 Street Street\n"
                + "City, State, 56789");
    }

    /**
@@ -87,7 +95,7 @@ public class MediaViewTest {
        data.putDouble(ExifInterface.TAG_GPS_LATITUDE, 37.7749);

        mMetadata.putBundle(DocumentsContract.METADATA_EXIF, data);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null, mGeo);
        mTable.assertEmpty();
    }

@@ -102,7 +110,7 @@ public class MediaViewTest {
        data.putInt(ExifInterface.TAG_IMAGE_WIDTH, 3840);

        mMetadata.putBundle(DocumentsContract.METADATA_EXIF, data);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null, mGeo);
        mTable.assertEmpty();
    }

@@ -142,4 +150,17 @@ public class MediaViewTest {

        mTable.assertHasRow(R.string.metadata_duration, "6:01:00");
    }

    @Test
    public void testGetAddress() throws Exception {
        Consumer<float[]> badAddress = (float[] coords) -> {
        };
        Bundle data = new Bundle();
        data.putInt(ExifInterface.TAG_IMAGE_WIDTH, 3840);
        data.putInt(ExifInterface.TAG_IMAGE_LENGTH, 2160);

        mMetadata.getBundle(DocumentsContract.METADATA_EXIF);
        MediaView.showExifData(mTable, mResources, TestEnv.FILE_JPG, mMetadata, null, badAddress);
        mTable.assertNotInTable(R.string.metadata_address);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.documentsui.inspector;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;

import android.view.View.OnClickListener;
@@ -42,6 +43,10 @@ class TestTable implements TableDisplay {
        assertEquals(expected, mRows.get(keyId));
    }

    public void assertNotInTable (int keyId) {
        assertNull(mRows.get(keyId));
    }

    @Override
    public void put(int keyId, CharSequence value) {
        mRows.put(keyId, value);