DEV Community

Cover image for Geotags on Images in Android Studio (GeoTagImage)
Ashish Dangi
Ashish Dangi

Posted on

Geotags on Images in Android Studio (GeoTagImage)

Hello everyone,

In this blog I am going to guide you to how to add Geo tags or GPS location on the images clicked by the device camera. This is an android library to import in the android studio project and then just do some basic code. So here is the GeoTagImage Library for android app project.

So First of all I am pointing out the key features of this library.

Key Features :

  • Request camera & location permission callback by itself.
  • Show location and address.
  • Show Lat Longs.
  • Show author name.
  • Show app name.
  • Show Google map snapshot.
  • Set Image Quality.

Handle Visibilities :

  • Show/hide app name — showAppName()
  • Show/hide author name — showAuthoraName()
  • Show/hide google map — showGoogleMap()
  • Show/hide Lat Longs — showLatLng()

So lets start, the brief summary of these points :

  • Request Camera & Location permission — The library can ask the permission by itself by using permission callback listener. Only the result need to handle in the activity or the fragment by using OnRequestPermissionResult().

  • Show Location & Address — The library can draw device’s current
    location such as sub-admin area, locality and country name along with complete address.

  • Show Lat Longs — The library can also draw device’s current
    coordinates such as latitude and longitude.

  • Show Author Name — The library can draw author (clicked by) name
    on the image. You need to add method setAuthorName(“name”) and showAuthorName(true) as by default the author name visibility is INVISIBLE.

  • Show App Name — The library can draw app name also in which this
    library has been imported. You need to set visibility of this by using showAppName(true).

  • Show Google Map — The library can show google map snapshot of
    device’s current location along with marker. It depends on your project is linked with google map SDK or not. If not then the visibility of google map snapshot will be invisible by default.
    Set Image Quality — The library has a feature to set image quality. By default the image quality will be STANDARD size and LOW & HIGH qualities are optional which can be use by setImageQuality() method.

Start Implementation of the library :
Gradle
Add repository in your build.gradle (project-level) file :

allprojects {
      repositories {
 ...
 maven { url 'https://jitpack.io' }
 }
}
Enter fullscreen mode Exit fullscreen mode

OR
in your settings.gradle

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}
Enter fullscreen mode Exit fullscreen mode

Add dependency :
Add dependency in your build.gradle (module-level) file :

dependencies{
    implementation 'com.github.dangiashish:GeoTagImage:1.0.7'
}
Enter fullscreen mode Exit fullscreen mode

Add file provider in AndroidManifest.xml :

<provider
      android:name="androidx.core.content.FileProvider"
      android:authorities="${applicationId}.provider"
      android:exported="false"
      android:grantUriPermissions="true">
       <meta-data
          android:name="android.support.FILE_PROVIDER_PATHS"
          android:resource="@xml/provider_paths" 
</provider>
Enter fullscreen mode Exit fullscreen mode

*Create an xml file for path provider @xml/provider_path.xml :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>
Enter fullscreen mode Exit fullscreen mode

Java : MainActivity.java :

public class MainActivity extends AppCompatActivity implements PermissionCallback {
    private ImageView ivCamera, ivImage, ivClose;
    private static String imageStoragePath;
    public static final String IMAGE_EXTENSION = ".jpg";
    private Uri fileUri;
    private static final int CAMERA_IMAGE_REQUEST_CODE = 2000;
    private static final int PERMISSION_REQUEST_CODE = 100;

    static FragmentActivity mContext;
    private GeoTagImage geoTagImage;
    private PermissionCallback permissionCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // initialize the context
        mContext = MainActivity.this;
        // initialize the permission callback listener
        permissionCallback = this;

        // initialize the GeoTagImage class object with context and callback
        // use try/catch block to handle exceptions.
        try {
            geoTagImage = new GeoTagImage(mContext, permissionCallback);
        } catch (GTIException e) {
            throw new RuntimeException(e);
        }

        // initialize the xml buttons.
        ivCamera = findViewById(R.id.ivCamera);
        ivImage = findViewById(R.id.ivImage);
        ivClose = findViewById(R.id.ivClose);

        // setOnClickListener on camera button.
        ivCamera.setOnClickListener(click -> {
            // first check permission for camera and location by using GTIPermission class.
            if (GTIPermissions.checkCameraLocationPermission(mContext)) {

                // if permissions are granted, than open camera.
                openCamera();

            } else {
                // otherwise request for the permissions by using GTIPermission class.
                GTIPermissions.requestCameraLocationPermission(mContext, PERMISSION_REQUEST_CODE);
            }
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

openCamera()

 // if permissions are granted for camera and location.
    private void openCamera() {
        // call Intent for ACTION_IMAGE_CAPTURE which will redirect to device camera.
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        // create a file object
        File file;

        // before adding GeoTags, generate or create an original image file
        // TODO-Note : we need to create an original image to add geotags by copying this file.
        file = GTIUtility.generateOriginalFile(mContext, IMAGE_EXTENSION);
        if (file != null) {
            // if file has been created, then will catch its path for future reference.
            imageStoragePath = file.getPath();
        }

        // now get Uri from this created image file by using GTIUtility.getFileUri() function.
        fileUri = GTIUtility.getFileUri(mContext, file);

        // pass this uri file into intent filters while opening camera.
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        // call startActivityForResult method by passing the intent filter with a request code.
        startActivityForResult(intent, CAMERA_IMAGE_REQUEST_CODE);
        }
Enter fullscreen mode Exit fullscreen mode

Handle request permission result:

   @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                geoTagImage.handlePermissionGrantResult();
                Toast.makeText(mContext, "Permission Granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(mContext, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
        }
    }
Enter fullscreen mode Exit fullscreen mode

Handle onActivityResult method

// override the onActivityResult method
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // check the request code for the result
        if (requestCode == CAMERA_IMAGE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                // if result is OK then preview the original created image file.
                previewCapturedImage();

                try {
                    // now call the function createImage() and pass the uri object (line no. 90-100)
                    geoTagImage.createImage(fileUri);

                    // set all the customizations for geotagging as per your requirements.
                    geoTagImage.setTextSize(25f);
                    geoTagImage.setBackgroundRadius(5f);
                    geoTagImage.setBackgroundColor(Color.parseColor("#66000000"));
                    geoTagImage.setTextColor(getColor(android.R.color.white));
                    geoTagImage.setAuthorName("Ashish");
                    geoTagImage.showAuthorName(true);
                    geoTagImage.showAppName(true);

                    // after the geotagged photo is created, get the new image path by using getImagePath() method
                    imageStoragePath = geoTagImage.getImagePath();


                } catch (GTIException e) {
                    throw new RuntimeException(e);
                }


                // handle the error or cancel events
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(mContext, "Cancelled image capture", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(mContext, "Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
            }
        }
    }
Enter fullscreen mode Exit fullscreen mode

Preview the original image

     // preview of the original image
    private void previewCapturedImage() {
        try {
            ivCamera.setVisibility(View.GONE);
            Bitmap bitmap = GTIUtility.optimizeBitmap(imageStoragePath);
            ivImage.setImageBitmap(bitmap);

            if (ivImage.getDrawable() != null) {
                ivClose.setVisibility(View.VISIBLE);
            }
            ivClose.setOnClickListener(v -> {
                ivImage.setImageBitmap(null);
                ivCamera.setVisibility(View.VISIBLE);
                ivClose.setVisibility(View.GONE);
                ivImage.setImageDrawable(null);

            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Enter fullscreen mode Exit fullscreen mode

Handle callback listener methods

@Override
public void onPermissionGranted() {
   openCamera();
}
@Override
public void onPermissionDenied() {
  GTIPermissions.requestCameraLocationPermission(mContext, PERMISSION_REQUEST_CODE);
}
Enter fullscreen mode Exit fullscreen mode

I hope you like it, Kindly Like ❤️ this post and give star to this repo on Github. if you have any query or suggestion kindly ping me. Your feedbacks are appreciated.

Follow on : Github, LinkedIn, Instagram
Subscribe on youtube : CodeByAshish
Project Link : GeoTagImage@github

Top comments (0)