diff --git a/myTracks/src/main/AndroidManifest.xml b/myTracks/src/main/AndroidManifest.xml
index 8d50a6e4f..1329c6ed4 100644
--- a/myTracks/src/main/AndroidManifest.xml
+++ b/myTracks/src/main/AndroidManifest.xml
@@ -253,5 +253,15 @@ limitations under the License.
android:authorities="com.google.android.maps.mytracks.search"
android:exported="false"
android:name="com.google.android.apps.mytracks.content.SearchEngineProvider" />
+
+
+
+
diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/AbstractSendToGoogleActivity.java b/myTracks/src/main/java/com/google/android/apps/mytracks/AbstractSendToGoogleActivity.java
index cb301155c..7aa2a024f 100644
--- a/myTracks/src/main/java/com/google/android/apps/mytracks/AbstractSendToGoogleActivity.java
+++ b/myTracks/src/main/java/com/google/android/apps/mytracks/AbstractSendToGoogleActivity.java
@@ -53,7 +53,6 @@ public abstract class AbstractSendToGoogleActivity extends AbstractMyTracksActiv
private static final int DELETE_REQUEST_CODE = 3;
protected static final int GOOGLE_PLAY_SERVICES_REQUEST_CODE = 4;
- protected static final int CAMERA_REQUEST_CODE = 5;
protected static final int GPS_REQUEST_CODE = 6;
@Override
diff --git a/myTracks/src/main/java/com/google/android/apps/mytracks/TrackDetailActivity.java b/myTracks/src/main/java/com/google/android/apps/mytracks/TrackDetailActivity.java
index c2f61c51a..dfe9ee07e 100644
--- a/myTracks/src/main/java/com/google/android/apps/mytracks/TrackDetailActivity.java
+++ b/myTracks/src/main/java/com/google/android/apps/mytracks/TrackDetailActivity.java
@@ -38,6 +38,7 @@ import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtil
import com.google.android.apps.mytracks.util.TrackUtils;
import com.google.android.maps.mytracks.R;
+import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -46,8 +47,14 @@ import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
import androidx.core.app.TaskStackBuilder;
+import androidx.core.content.FileProvider;
import androidx.viewpager.widget.ViewPager;
+
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
@@ -70,6 +77,8 @@ import java.util.Date;
public class TrackDetailActivity extends AbstractSendToGoogleActivity
implements ChooseActivityTypeCaller, ConfirmDeleteDialogFragment.ConfirmDeleteCaller {
+ private static final String TAG = TrackDetailActivity.class.getSimpleName();
+
public static final String EXTRA_TRACK_ID = "track_id";
public static final String EXTRA_MARKER_ID = "marker_id";
@@ -77,7 +86,10 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
private static final String PHOTO_URI_KEY = "photo_uri_key";
private static final String HAS_PHOTO_KEY = "has_photo_key";
private static final String JPEG_EXTENSION = "jpeg";
-
+
+ private static final int CAMERA_REQUEST_CODE = 5;
+ private static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 6;
+
// The following are set in onCreate
private boolean hasCamera;
private Uri photoUri;
@@ -289,11 +301,19 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
if (requestCode == CAMERA_REQUEST_CODE) {
if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, R.string.marker_add_canceled, Toast.LENGTH_LONG).show();
+ return;
}
hasPhoto = resultCode == RESULT_OK;
- } else {
- super.onActivityResult(requestCode, resultCode, data);
+
+ if (hasPhoto) {
+ //Register photo in media scanner
+ Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+ mediaScanIntent.setData(photoUri);
+ this.sendBroadcast(mediaScanIntent);
+ return;
+ }
}
+ super.onActivityResult(requestCode, resultCode, data);
}
@Override
@@ -331,6 +351,7 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
insertMarkerMenuItem = menu.findItem(R.id.track_detail_insert_marker);
insertPhotoMenuItem = menu.findItem(R.id.track_detail_insert_photo);
+ insertPhotoMenuItem.setVisible(new Intent(MediaStore.ACTION_IMAGE_CAPTURE).resolveActivity(getPackageManager()) != null);
shareMenuItem = menu.findItem(R.id.track_detail_share);
shareMenuItem.setEnabled(!isSharedWithMe);
@@ -353,26 +374,18 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
Intent intent;
switch (item.getItemId()) {
case R.id.track_detail_insert_marker:
- intent = IntentUtils.newIntent(this, MarkerEditActivity.class)
- .putExtra(MarkerEditActivity.EXTRA_TRACK_ID, trackId);
+ intent = IntentUtils
+ .newIntent(this, MarkerEditActivity.class)
+ .putExtra(MarkerEditActivity.EXTRA_TRACK_ID, trackId);
startActivity(intent);
return true;
case R.id.track_detail_insert_photo:
- if (!FileUtils.isExternalStorageWriteable()) {
- Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show();
+ if (!FileUtils.isExternalStorageWriteable() || ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
return false;
}
- File dir = FileUtils.getPhotoDir(trackId);
- FileUtils.ensureDirectoryExists(dir);
-
- String fileName = SimpleDateFormat.getDateTimeInstance().format(new Date());
- File file = new File(dir, FileUtils.buildUniqueFileName(dir, fileName, JPEG_EXTENSION));
-
- photoUri = Uri.fromFile(file);
- intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE).putExtra(
- MediaStore.EXTRA_OUTPUT, photoUri);
- startActivityForResult(intent, CAMERA_REQUEST_CODE);
+ takePicture();
return true;
case R.id.track_detail_markers:
intent = IntentUtils.newIntent(this, MarkerListActivity.class)
@@ -380,13 +393,11 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
startActivity(intent);
return true;
case R.id.track_detail_voice_frequency:
- FrequencyDialogFragment.newInstance(R.string.voice_frequency_key,
- PreferencesUtils.VOICE_FREQUENCY_DEFAULT, R.string.menu_voice_frequency)
+ FrequencyDialogFragment.newInstance(R.string.voice_frequency_key, PreferencesUtils.VOICE_FREQUENCY_DEFAULT, R.string.menu_voice_frequency)
.show(getSupportFragmentManager(), FrequencyDialogFragment.FREQUENCY_DIALOG_TAG);
return true;
case R.id.track_detail_split_frequency:
- FrequencyDialogFragment.newInstance(R.string.split_frequency_key,
- PreferencesUtils.SPLIT_FREQUENCY_DEFAULT, R.string.menu_split_frequency)
+ FrequencyDialogFragment.newInstance(R.string.split_frequency_key, PreferencesUtils.SPLIT_FREQUENCY_DEFAULT, R.string.menu_split_frequency)
.show(getSupportFragmentManager(), FrequencyDialogFragment.FREQUENCY_DIALOG_TAG);
return true;
case R.id.track_detail_edit:
@@ -410,6 +421,36 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
}
}
+ private void takePicture() {
+ Intent intent;
+ File dir = FileUtils.getPhotoDir(trackId);
+ FileUtils.ensureDirectoryExists(dir);
+
+ String fileName = SimpleDateFormat.getDateTimeInstance().format(new Date());
+ File file = new File(dir, FileUtils.buildUniqueFileName(dir, fileName, JPEG_EXTENSION));
+
+ if (file != null) {
+ photoUri = FileProvider.getUriForFile(this, "com.google.android.apps.mytracks.fileprovider", file);
+ Log.d(TAG, "Taking photo to URI: " + photoUri);
+ intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
+ .putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
+ startActivityForResult(intent, CAMERA_REQUEST_CODE);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
+ Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show();
+ } else {
+ this.takePicture();
+ }
+ return;
+ }
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
@Override
public boolean onTrackballEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
diff --git a/myTracks/src/main/res/xml/file_paths.xml b/myTracks/src/main/res/xml/file_paths.xml
new file mode 100644
index 000000000..65aa363eb
--- /dev/null
+++ b/myTracks/src/main/res/xml/file_paths.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/myTracksLib/src/main/java/com/google/android/apps/mytracks/util/FileUtils.java b/myTracksLib/src/main/java/com/google/android/apps/mytracks/util/FileUtils.java
index 023c88ce6..0f218c4b5 100644
--- a/myTracksLib/src/main/java/com/google/android/apps/mytracks/util/FileUtils.java
+++ b/myTracksLib/src/main/java/com/google/android/apps/mytracks/util/FileUtils.java
@@ -31,11 +31,6 @@ public class FileUtils {
private FileUtils() {}
- /**
- * The backups directory under the My Tracks external storage directory.
- */
- public static final String BACKUPS_DIR = "backups";
-
/**
* The My Tracks external storage directory.
*/
@@ -52,11 +47,6 @@ public class FileUtils {
*/
public static final String PLAY_TRACKS_DIR = "temp";
- /**
- * The temp files directory under the My Tracks cache directory.
- */
- public static final String TEMP_FILES_DIR = "temp_files";
-
/**
* The pictures directory under the My Tracks external storage directory.
*/