implemented a basic share sheet (see #36)
This commit is contained in:
parent
3c5be28ded
commit
9f8e932b5a
6 changed files with 120 additions and 29 deletions
|
@ -51,6 +51,17 @@
|
|||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<!-- EXPORT HELPER (FILE PROVIDER) -->
|
||||
<provider
|
||||
android:name=".helpers.ExportHelper"
|
||||
android:authorities="org.y20k.trackbook.exporthelper.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths"/>
|
||||
</provider>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -205,8 +205,10 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
|||
mDropdown = (Spinner) mRootView.findViewById(R.id.track_selector);
|
||||
|
||||
// attach listeners to export and delete buttons
|
||||
ImageButton shareButton = (ImageButton) mRootView.findViewById(R.id.share_button);
|
||||
ImageButton exportButton = (ImageButton) mRootView.findViewById(R.id.export_button);
|
||||
ImageButton deleteButton = (ImageButton) mRootView.findViewById(R.id.delete_button);
|
||||
shareButton.setOnClickListener(getShareButtonListener());
|
||||
exportButton.setOnClickListener(getExportButtonListener());
|
||||
deleteButton.setOnClickListener(getDeleteButtonListener());
|
||||
|
||||
|
@ -343,7 +345,7 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
|||
break;
|
||||
case RESULT_EXPORT_DIALOG:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
// User chose EXPORT
|
||||
// user chose EXPORT
|
||||
ExportHelper.exportToGpx(mActivity, mTrack);
|
||||
} else if (resultCode == Activity.RESULT_CANCELED){
|
||||
// User chose CANCEL
|
||||
|
@ -525,23 +527,21 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
|||
}
|
||||
|
||||
|
||||
/* Creates OnClickListener for the delete button - needed in onCreateView */
|
||||
private View.OnClickListener getDeleteButtonListener() {
|
||||
/* Creates OnClickListener for the export button - needed in onCreateView */
|
||||
private View.OnClickListener getShareButtonListener() {
|
||||
return new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// get text elements for delete dialog
|
||||
int dialogTitle = R.string.dialog_delete_title;
|
||||
int dialogPositiveButton = R.string.dialog_delete_action_delete;
|
||||
int dialogNegativeButton = R.string.dialog_default_action_cancel;
|
||||
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
|
||||
String recordingStartDate = df.format(mTrack.getRecordingStart());
|
||||
String dialogMessage = getString(R.string.dialog_delete_content) + " " + recordingStartDate + " | " + LengthUnitHelper.convertDistanceToString(mTrack.getTrackDistance());
|
||||
|
||||
// show delete dialog - results are handles by onActivityResult
|
||||
DialogFragment dialogFragment = DialogHelper.newInstance(dialogTitle, dialogMessage, dialogPositiveButton, dialogNegativeButton);
|
||||
dialogFragment.setTargetFragment(MainActivityTrackFragment.this, RESULT_DELETE_DIALOG);
|
||||
dialogFragment.show(mActivity.getSupportFragmentManager(), "DeleteDialog");
|
||||
Intent intent = ExportHelper.getGpxFileIntent(mActivity, mTrack);
|
||||
// create intent to show chooser
|
||||
String title = "Share GPX file with"; // todo replace with Resource
|
||||
// String title = getResources().getString(R.string.chooser_title);
|
||||
Intent chooser = Intent.createChooser(intent, title);
|
||||
if (intent.resolveActivity(mActivity.getPackageManager()) != null) {
|
||||
startActivity(chooser);
|
||||
} else {
|
||||
// todo TOAST
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -584,6 +584,28 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O
|
|||
}
|
||||
|
||||
|
||||
/* Creates OnClickListener for the delete button - needed in onCreateView */
|
||||
private View.OnClickListener getDeleteButtonListener() {
|
||||
return new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// get text elements for delete dialog
|
||||
int dialogTitle = R.string.dialog_delete_title;
|
||||
int dialogPositiveButton = R.string.dialog_delete_action_delete;
|
||||
int dialogNegativeButton = R.string.dialog_default_action_cancel;
|
||||
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
|
||||
String recordingStartDate = df.format(mTrack.getRecordingStart());
|
||||
String dialogMessage = getString(R.string.dialog_delete_content) + " " + recordingStartDate + " | " + LengthUnitHelper.convertDistanceToString(mTrack.getTrackDistance());
|
||||
|
||||
// show delete dialog - results are handles by onActivityResult
|
||||
DialogFragment dialogFragment = DialogHelper.newInstance(dialogTitle, dialogMessage, dialogPositiveButton, dialogNegativeButton);
|
||||
dialogFragment.setTargetFragment(MainActivityTrackFragment.this, RESULT_DELETE_DIALOG);
|
||||
dialogFragment.show(mActivity.getSupportFragmentManager(), "DeleteDialog");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/* Add tap listener to elevation data views */
|
||||
private void attachTapListenerToElevationViews() {
|
||||
int referencedIds[] = mElevationDataViews.getReferencedIds();
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
package org.y20k.trackbook.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.y20k.trackbook.R;
|
||||
|
@ -38,7 +40,7 @@ import java.util.TimeZone;
|
|||
/**
|
||||
* ExportHelper class
|
||||
*/
|
||||
public final class ExportHelper implements TrackbookKeys {
|
||||
public final class ExportHelper extends FileProvider implements TrackbookKeys {
|
||||
|
||||
/* Define log tag */
|
||||
private static final String LOG_TAG = ExportHelper.class.getSimpleName();
|
||||
|
@ -53,17 +55,8 @@ public final class ExportHelper implements TrackbookKeys {
|
|||
|
||||
/* Exports given track to GPX */
|
||||
public static boolean exportToGpx(Context context, Track track) {
|
||||
// get "Download" folder
|
||||
File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||
|
||||
// create "Download" folder if necessary
|
||||
if (folder != null && !folder.exists()) {
|
||||
LogHelper.v(LOG_TAG, "Creating new folder: " + folder.toString());
|
||||
folder.mkdirs();
|
||||
}
|
||||
|
||||
// get file for given track
|
||||
File gpxFile = createFile(track, folder);
|
||||
File gpxFile = createFile(track, getDownloadFolder());
|
||||
|
||||
// get GPX string representation for given track
|
||||
String gpxString = createGpxString(track);
|
||||
|
@ -81,6 +74,46 @@ public final class ExportHelper implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
/* Creates Intent used to bring up an Android share sheet */
|
||||
public static Intent getGpxFileIntent(Context context, Track track) {
|
||||
|
||||
// get file for given track
|
||||
File gpxFile = createFile(track, getDownloadFolder()); // todo use cache folder
|
||||
|
||||
// get GPX string representation for given track
|
||||
String gpxString = createGpxString(track);
|
||||
|
||||
// write GPX file
|
||||
if (writeGpxToFile(gpxString, gpxFile)) {
|
||||
String toastMessage = context.getResources().getString(R.string.toast_message_export_success) + " " + gpxFile.toString();
|
||||
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
String toastMessage = context.getResources().getString(R.string.toast_message_export_fail) + " " + gpxFile.toString();
|
||||
Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
// create intent
|
||||
String authority = "org.y20k.trackbook.exporthelper.provider";
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
intent.setType("application/gpx+xml");
|
||||
intent.setData(FileProvider.getUriForFile(context, authority, gpxFile));
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
|
||||
/* Get "Download" folder */
|
||||
private static File getDownloadFolder() {
|
||||
File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||
if (folder != null && !folder.exists()) {
|
||||
LogHelper.v(LOG_TAG, "Creating new folder: " + folder.toString());
|
||||
folder.mkdirs();
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
|
||||
/* Return a GPX filepath for a given track */
|
||||
private static File createFile(Track track, File folder) {
|
||||
Date recordingStart = track.getRecordingStart();
|
||||
|
|
9
app/src/main/res/drawable/ic_share_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_share_24dp.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"
|
||||
android:fillColor="@color/track_management_icons" />
|
||||
</vector>
|
|
@ -17,10 +17,21 @@
|
|||
android:layout_marginTop="4dp"
|
||||
android:contentDescription="@string/descr_track_selector"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/export_button"
|
||||
app:layout_constraintEnd_toStartOf="@+id/share_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/share_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:backgroundTint="@color/trackbook_transparent"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/track_selector"
|
||||
app:layout_constraintEnd_toStartOf="@+id/export_button"
|
||||
app:layout_constraintTop_toTopOf="@+id/track_selector"
|
||||
app:srcCompat="@drawable/ic_share_24dp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/export_button"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -28,9 +39,9 @@
|
|||
android:layout_marginEnd="8dp"
|
||||
android:backgroundTint="@color/trackbook_transparent"
|
||||
android:contentDescription="@string/descr_export_button"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/track_selector"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/share_button"
|
||||
app:layout_constraintEnd_toStartOf="@+id/delete_button"
|
||||
app:layout_constraintTop_toTopOf="@+id/track_selector"
|
||||
app:layout_constraintTop_toTopOf="@+id/share_button"
|
||||
app:srcCompat="@drawable/ic_file_download_24dp" />
|
||||
|
||||
<ImageButton
|
||||
|
@ -45,4 +56,5 @@
|
|||
app:layout_constraintTop_toTopOf="@+id/export_button"
|
||||
app:srcCompat="@drawable/ic_delete_forever_24dp" />
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
4
app/src/main/res/xml/provider_paths.xml
Normal file
4
app/src/main/res/xml/provider_paths.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<external-path name="external_files" path="Download/"/>
|
||||
</paths>
|
Loading…
Reference in a new issue