From a230504925317899e0dcf15abe66354952f4747f Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sat, 28 Dec 2019 19:56:37 +0100 Subject: [PATCH] Export & import via Storage Access Framework. --- .../content/DescriptionGeneratorTest.java | 2 +- src/main/AndroidManifest.xml | 3 - .../content/ContentProviderUtils.java | 1 + .../io/file/exporter/ExportActivity.java | 58 ++++---- .../io/file/exporter/ExportAsyncTask.java | 20 +-- .../io/file/importer/ImportActivity.java | 75 +++++------ .../io/file/importer/ImportAsyncTask.java | 124 +++++++++--------- .../dennisguse/opentracks/util/FileUtils.java | 16 +-- src/main/res/values/strings.xml | 3 +- 9 files changed, 136 insertions(+), 166 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java index 16be2066a..8208463c5 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/DescriptionGeneratorTest.java @@ -69,7 +69,7 @@ public class DescriptionGeneratorTest { track.setTripStatistics(stats); track.setCategory("hiking"); String expected = //"Created by" - "OpenTracks

" + "OpenTracks

" + "Name: -
" + "Activity type: hiking
" + "Description: -
" diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index c58c5a226..154037b3f 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -25,7 +25,6 @@ limitations under the License. android:hardwareAccelerated="true" android:icon="@drawable/ic_logo_color_24dp" android:label="@string/app_name" - android:requestLegacyExternalStorage="true" android:theme="@style/ThemeCustom"> @@ -152,6 +151,4 @@ limitations under the License. - - diff --git a/src/main/java/de/dennisguse/opentracks/content/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/content/ContentProviderUtils.java index 9bf3306b2..bca07ba71 100644 --- a/src/main/java/de/dennisguse/opentracks/content/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/content/ContentProviderUtils.java @@ -228,6 +228,7 @@ public class ContentProviderUtils { * @param dir the directory */ private void deleteDirectoryRecurse(Context context, File dir) { + // TODO Does not work with if (FileUtils.isDirectory(dir)) { for (File child : dir.listFiles()) { deleteDirectoryRecurse(context, child); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java index 366b5c581..34dca1519 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportActivity.java @@ -16,21 +16,20 @@ package de.dennisguse.opentracks.io.file.exporter; -import android.Manifest; +import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; -import android.content.pm.PackageManager; +import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.core.app.ActivityCompat; +import androidx.annotation.Nullable; +import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.FragmentActivity; -import java.io.File; - import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.fragments.FileTypeDialogFragment; import de.dennisguse.opentracks.io.file.TrackFileFormat; @@ -39,7 +38,6 @@ import de.dennisguse.opentracks.util.FileUtils; /** * An activity for saving tracks to the external storage. - * If saving a specific track, option to save it to a temp directory and play the track afterward. * * @author Rodrigo Damazio */ @@ -53,34 +51,39 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr private String directoryDisplayName; private ExportAsyncTask exportAsyncTask; - private ProgressDialog progressDialog; private int processedTrackCount; private int totalTrackCount; + private Uri directoryUri; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - 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); - } else { - fileTypeDialogStart(); - } + startActivityForResult(intent, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE); } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent resultData) { + super.onActivityResult(requestCode, resultCode, resultData); 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 { + if (resultCode == Activity.RESULT_OK) { +// final int takeFlags = resultData.getFlags() +// & (Intent.FLAG_GRANT_READ_URI_PERMISSION +// | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); +//// Check for the freshest data. +// getContentResolver().takePersistableUriPermission(uri, takeFlags); + directoryUri = resultData.getData(); fileTypeDialogStart(); + } else { + Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show(); + finish(); } - return; } - super.onRequestPermissionsResult(requestCode, permissions, grantResults); } private void fileTypeDialogStart() { @@ -89,21 +92,14 @@ public class ExportActivity extends FragmentActivity implements FileTypeDialogFr @Override public void onFileTypeDone(TrackFileFormat trackFileFormat) { - if (!FileUtils.isExternalStorageWriteable()) { - Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show(); - finish(); - return; - } - - File directory = new File(FileUtils.getPath(trackFileFormat.getExtension())); - if (!FileUtils.ensureDirectoryExists(directory)) { - Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show(); - finish(); - return; + DocumentFile pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri); + DocumentFile exportDirectory = pickedDirectory.findFile(FileUtils.SDCARD_TOP_DIR); + if (exportDirectory == null) { + exportDirectory = pickedDirectory.createDirectory(FileUtils.SDCARD_TOP_DIR); } directoryDisplayName = FileUtils.getPathDisplayName(trackFileFormat.getExtension()); - exportAsyncTask = new ExportAsyncTask(this, trackFileFormat, directory); + exportAsyncTask = new ExportAsyncTask(this, trackFileFormat, exportDirectory); exportAsyncTask.execute(); } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportAsyncTask.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportAsyncTask.java index 3645ae0b9..69b1a291e 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportAsyncTask.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/ExportAsyncTask.java @@ -22,16 +22,16 @@ import android.os.AsyncTask; import android.os.PowerManager.WakeLock; import android.util.Log; -import java.io.File; +import androidx.documentfile.provider.DocumentFile; + import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import de.dennisguse.opentracks.content.ContentProviderUtils; import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.TracksColumns; import de.dennisguse.opentracks.io.file.TrackFileFormat; -import de.dennisguse.opentracks.util.FileUtils; import de.dennisguse.opentracks.util.PreferencesUtils; import de.dennisguse.opentracks.util.SystemUtils; @@ -45,7 +45,7 @@ public class ExportAsyncTask extends AsyncTask { private static final String TAG = ExportAsyncTask.class.getSimpleName(); private final TrackFileFormat trackFileFormat; - private final File directory; + private final DocumentFile directory; private final Context context; private final ContentProviderUtils contentProviderUtils; private ExportActivity exportActivity; @@ -63,7 +63,7 @@ public class ExportAsyncTask extends AsyncTask { * @param trackFileFormat the track file format * @param directory the directory to write the file */ - public ExportAsyncTask(ExportActivity exportActivity, TrackFileFormat trackFileFormat, File directory) { + public ExportAsyncTask(ExportActivity exportActivity, TrackFileFormat trackFileFormat, DocumentFile directory) { this.exportActivity = exportActivity; this.trackFileFormat = trackFileFormat; this.directory = directory; @@ -156,13 +156,13 @@ public class ExportAsyncTask extends AsyncTask { }; TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, tracks, trackExporterListener); - Track track = tracks[0]; - String fileName = FileUtils.buildUniqueFileName(directory, track.getName(), trackFileFormat.getExtension()); - File file = new File(directory, fileName); - try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { - if (trackExporter.writeTrack(context, fileOutputStream)) { + String fileName = track.getId() + "." + trackFileFormat.getExtension(); + DocumentFile file = directory.createFile(trackFileFormat.getMimeType(), fileName); + + try (OutputStream outputStream = context.getContentResolver().openOutputStream(file.getUri())) { + if (trackExporter.writeTrack(context, outputStream)) { return true; } else { if (!file.delete()) { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java index fc2352102..4282b2b21 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportActivity.java @@ -16,21 +16,20 @@ package de.dennisguse.opentracks.io.file.importer; -import android.Manifest; +import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; -import android.content.pm.PackageManager; +import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.core.app.ActivityCompat; +import androidx.annotation.Nullable; +import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.FragmentActivity; -import java.io.File; - import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.fragments.FileTypeDialogFragment; import de.dennisguse.opentracks.io.file.TrackFileFormat; @@ -38,8 +37,7 @@ import de.dennisguse.opentracks.util.DialogUtils; import de.dennisguse.opentracks.util.FileUtils; /** - * An activity to import files from the external storage. Optionally to import - * one specific file. + * An activity to import files from the external storage. * * @author Rodrigo Damazio */ @@ -50,70 +48,58 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr private static final int DIALOG_PROGRESS_ID = 0; private static final int DIALOG_RESULT_ID = 1; + private String directoryDisplayName; + private ImportAsyncTask importAsyncTask; private ProgressDialog progressDialog; - // the path on the external storage to import - private String directoryDisplayName; - private int importedTrackCount; - private int totalTrackCount; + private Uri directoryUri; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (!FileUtils.isExternalStorageWriteable() || ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE); - } else { - fileTypeDialogStart(); - } + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + startActivityForResult(intent, EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE); } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent resultData) { + super.onActivityResult(requestCode, resultCode, resultData); if (requestCode == EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) { - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { - Toast.makeText(this, R.string.external_storage_not_readable, Toast.LENGTH_LONG).show(); - } else { + if (resultCode == Activity.RESULT_OK) { +// final int takeFlags = resultData.getFlags() +// & (Intent.FLAG_GRANT_READ_URI_PERMISSION +// | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); +//// Check for the freshest data. +// getContentResolver().takePersistableUriPermission(uri, takeFlags); + directoryUri = resultData.getData(); fileTypeDialogStart(); + } else { + Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show(); + finish(); } - return; } - super.onRequestPermissionsResult(requestCode, permissions, grantResults); } + private void fileTypeDialogStart() { FileTypeDialogFragment.showDialog(getSupportFragmentManager(), R.string.import_selection_title, R.string.import_selection_option); } @Override public void onFileTypeDone(TrackFileFormat trackFileFormat) { - if (!FileUtils.isExternalStorageAvailable()) { - Toast.makeText(this, R.string.external_storage_not_available, Toast.LENGTH_LONG).show(); - finish(); - return; - } + DocumentFile pickedDirectory = DocumentFile.fromTreeUri(this, directoryUri); directoryDisplayName = FileUtils.getPathDisplayName(trackFileFormat.getExtension()); - String directoryPath = FileUtils.getPath(trackFileFormat.getExtension()); - if (!FileUtils.isDirectory(new File(directoryPath))) { - Toast.makeText(this, getString(R.string.import_no_directory, directoryDisplayName), Toast.LENGTH_LONG) - .show(); - finish(); - return; - } - //TODO (still needed?): getLastNonConfiguration instance returned ExportAsyncTask before -// Object retained = getLastNonConfigurationInstance(); -// if (retained instanceof ImportAsyncTask) { -// importAsyncTask = (ImportAsyncTask) retained; -// importAsyncTask.setActivity(this); -// } else { - importAsyncTask = new ImportAsyncTask(this, trackFileFormat, directoryPath); + importAsyncTask = new ImportAsyncTask(this, trackFileFormat, pickedDirectory); importAsyncTask.execute(); -// } } @Override @@ -154,8 +140,7 @@ public class ImportActivity extends FragmentActivity implements FileTypeDialogFr } else { iconId = R.drawable.ic_dialog_error_24dp; titleId = R.string.generic_error_title; - message = getString( - R.string.import_error, importedTrackCount, totalFiles, directoryDisplayName); + message = getString(R.string.import_error, importedTrackCount, totalFiles, directoryDisplayName); } return new AlertDialog.Builder(this).setCancelable(true).setIcon(iconId) .setMessage(message).setOnCancelListener(new DialogInterface.OnCancelListener() { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportAsyncTask.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportAsyncTask.java index 1b20a195f..648a80fc5 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportAsyncTask.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/ImportAsyncTask.java @@ -22,9 +22,10 @@ import android.os.AsyncTask; import android.os.PowerManager.WakeLock; import android.util.Log; -import java.io.File; -import java.io.FileInputStream; +import androidx.documentfile.provider.DocumentFile; + import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -44,7 +45,7 @@ public class ImportAsyncTask extends AsyncTask { private static final String TAG = ImportAsyncTask.class.getSimpleName(); private final TrackFileFormat trackFileFormat; - private final String path; + private final DocumentFile directory; // TODO Can be removed, or? private Context context; // TODO Use weak reference @@ -66,12 +67,12 @@ public class ImportAsyncTask extends AsyncTask { * * @param importActivity the activity currently associated with this AsyncTask * @param trackFileFormat the track file format - * @param path path to import GPX files + * @param directory path to import GPX files */ - public ImportAsyncTask(ImportActivity importActivity, TrackFileFormat trackFileFormat, String path) { + public ImportAsyncTask(ImportActivity importActivity, TrackFileFormat trackFileFormat, DocumentFile directory) { this.importActivity = importActivity; this.trackFileFormat = trackFileFormat; - this.path = path; + this.directory = directory; context = importActivity.getApplicationContext(); completed = false; @@ -99,39 +100,26 @@ public class ImportAsyncTask extends AsyncTask { } } - @Override - protected Boolean doInBackground(Void... params) { - try { - Thread.currentThread().setPriority(Thread.MAX_PRIORITY); // TODO Should be set to previous level at the end of this method. - // Get the wake lock if not recording or paused - boolean isRecording = PreferencesUtils.isRecording(importActivity); - boolean isPaused = PreferencesUtils.isRecordingTrackPaused(importActivity); - if (!isRecording || isPaused) { - wakeLock = SystemUtils.acquireWakeLock(importActivity, wakeLock); - } + /** + * Gets a list of files. + * If importAll is true, returns a list of the files under the path directory. + * If importAll is false, returns a list containing just the path file. + */ + private static List getFiles(DocumentFile file, TrackFileFormat trackFileFormat) { + List files = new ArrayList<>(); - List files = getFiles(); - totalTrackCount = files.size(); - if (totalTrackCount == 0) { - return true; - } - - for (int i = 0; i < totalTrackCount; i++) { - if (isCancelled()) { - // If cancelled, return true to show the number of files imported - return true; + for (DocumentFile candidate : file.listFiles()) { + if (!candidate.isDirectory()) { + String extension = FileUtils.getExtension(candidate.getName()); + if (trackFileFormat.getExtension().equals(extension)) { + files.add(candidate); } - if (importFile(files.get(i))) { - importTrackCount++; - } - publishProgress(i + 1, totalTrackCount); - } - return true; - } finally { - if (wakeLock != null && wakeLock.isHeld()) { - wakeLock.release(); + } else { + files.addAll(getFiles(candidate, trackFileFormat)); } } + + return files; } @Override @@ -159,16 +147,49 @@ public class ImportAsyncTask extends AsyncTask { } } + @Override + protected Boolean doInBackground(Void... params) { + try { + Thread.currentThread().setPriority(Thread.MAX_PRIORITY); // TODO Should be set to previous level at the end of this method. + // Get the wake lock if not recording or paused + boolean isRecording = PreferencesUtils.isRecording(importActivity); + boolean isPaused = PreferencesUtils.isRecordingTrackPaused(importActivity); + if (!isRecording || isPaused) { + wakeLock = SystemUtils.acquireWakeLock(importActivity, wakeLock); + } + + List files = getFiles(directory, trackFileFormat); + totalTrackCount = files.size(); + + for (int i = 0; i < totalTrackCount; i++) { + if (isCancelled()) { + // If cancelled, return true to show the number of files imported + return true; + } + if (importFile(files.get(i))) { + importTrackCount++; + } + publishProgress(i + 1, totalTrackCount); + } + return true; + } finally { + if (wakeLock != null && wakeLock.isHeld()) { + wakeLock.release(); + } + } + } + /** * Imports a file. * * @param file the file */ - private boolean importFile(final File file) { + private boolean importFile(final DocumentFile file) { TrackImporter trackImporter; if (trackFileFormat == TrackFileFormat.GPX) { trackImporter = new GpxFileTrackImporter(importActivity); - } else { //KML or KMZ + } else { + //KML or KMZ String extension = FileUtils.getExtension(file.getName()); if (TrackFileFormat.KML_ONLY_TRACK.getExtension().equals(extension)) { trackImporter = new KmlFileTrackImporter(importActivity, -1L); @@ -181,37 +202,12 @@ public class ImportAsyncTask extends AsyncTask { } } - try (FileInputStream fileInputStream = new FileInputStream(file)) { - trackId = trackImporter.importFile(fileInputStream); + try (InputStream inputStream = context.getContentResolver().openInputStream(file.getUri())) { + trackId = trackImporter.importFile(inputStream); return trackId != -1L; } catch (IOException e) { Log.e(TAG, "Unable to import file", e); return false; } } - - /** - * Gets a list of files. - * If importAll is true, returns a list of the files under the path directory. - * If importAll is false, returns a list containing just the path file. - */ - private List getFiles() { - List files = new ArrayList<>(); - File file = new File(path); - - File[] candidates = file.listFiles(); - if (candidates == null) { - return files; - } - for (File candidate : candidates) { - if (!FileUtils.isDirectory(candidate)) { - String extension = FileUtils.getExtension(candidate.getName()); - if (trackFileFormat.getExtension().equals(extension)) { - files.add(candidate); - } - } - } - - return files; - } } diff --git a/src/main/java/de/dennisguse/opentracks/util/FileUtils.java b/src/main/java/de/dennisguse/opentracks/util/FileUtils.java index dc4a61462..003b970e1 100644 --- a/src/main/java/de/dennisguse/opentracks/util/FileUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/FileUtils.java @@ -39,7 +39,7 @@ public class FileUtils { /** * Our external storage directory. */ - static final String SDCARD_TOP_DIR = "OpenTracks"; + public static final String SDCARD_TOP_DIR = "OpenTracks"; // TODO RENAME private static final String TRACK_PREFIX = "OpenTracks"; /** * The maximum FAT32 path length. See the FAT32 spec at @@ -54,15 +54,6 @@ public class FileUtils { private FileUtils() { } - /** - * Returns true if the external storage is available. - */ - public static boolean isExternalStorageAvailable() { - String state = Environment.getExternalStorageState(); - return Environment.MEDIA_MOUNTED.equals(state) - || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state); - } - /** * Returns true if the external storage is writable. */ @@ -76,6 +67,7 @@ public class FileUtils { * * @param dir the directory */ + @Deprecated // TODO REMOVE" rewrite all locations this was used. public static boolean isDirectory(File dir) { return dir.exists() && dir.isDirectory(); } @@ -86,6 +78,7 @@ public class FileUtils { * @return whether the directory exists (either already existed or was * successfully created) */ + @Deprecated // TODO REMOVE" rewrite all locations this was used. public static boolean ensureDirectoryExists(File dir) { if (isDirectory(dir)) { return true; @@ -93,10 +86,12 @@ public class FileUtils { return dir.mkdirs(); } + @Deprecated // TODO REMOVE" rewrite all locations this was used. public static File getPhotoDir() { return new File(getPath(PICTURES_DIR)); } + @Deprecated // TODO REMOVE" rewrite all locations this was used. public static File getPhotoDir(long trackId) { return new File(getPath(PICTURES_DIR, TRACK_PREFIX + trackId)); } @@ -122,6 +117,7 @@ public class FileUtils { * * @param components the components */ + @Deprecated // TODO REMOVE" rewrite all locations this was used. public static String getPath(String... components) { return Environment.getExternalStorageDirectory() + getPathDisplayName(components); } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 3b3a06d89..7c8035469 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -805,8 +805,7 @@ limitations under the License. dialog when there is no files to import. %1$s the directory. E.g., '/kml'."> - There were no files to import. Connect your device to your computer and place the files to - import in %1$s. + There were no files to import. Connect your device to your computer and place the files to import in %1$s.