mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-19 06:15:26 +00:00
Android: add java code to share files
Android's sandbox makes us jump through hoops in order to share files with other apps. We need to declare a file provider and use specific paths where the files are located. Then we have java code (I couldn't make it work as JNI) that takes the filenames and creates content:// URIs for them and then hands those off to a sharing activity that is provided by Android. This can then be used to create attachments for support emails, or to share the log files with other apps - both of which will solve the annoying maximum log file length that we have with using the binder to add the log file text to the message body. This also finally replaces the 'compile' directive in build.gradle with 'implementation' - removing a warning that we've had for ages. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
3b42aada18
commit
aa41fbbf79
4 changed files with 85 additions and 1 deletions
|
@ -77,6 +77,15 @@
|
|||
<meta-data android:name="android.max_aspect" android:value="3" />
|
||||
|
||||
</activity>
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="org.subsurfacedivelog.mobile.fileprovider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="21"
|
||||
|
|
|
@ -27,8 +27,9 @@ allprojects {
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.github.mik3y:usb-serial-for-android:v3.4.3'
|
||||
implementation 'com.android.support:support-v4:25.3.1'
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
4
android-mobile/res/xml/filepaths.xml
Normal file
4
android-mobile/res/xml/filepaths.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<files-path path="./" name="logfiles" />
|
||||
</paths>
|
|
@ -20,10 +20,80 @@ import android.content.Intent;
|
|||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.util.Log;
|
||||
import java.io.File;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.app.ShareCompat;
|
||||
import android.content.pm.PackageManager;
|
||||
import java.util.List;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
// this is the main class that will be run at start
|
||||
public class SubsurfaceMobileActivity extends QtActivity
|
||||
{
|
||||
// FileProvider declares an 'authority' in AndroidManifest.xml
|
||||
private static String fileProviderAuthority="org.subsurfacedivelog.mobile.fileprovider";
|
||||
|
||||
// you can share one file (for future use, I'm thinking divelist XML), or two files
|
||||
// which is assumed to be a support request - maybe that shouldn't be implicit?
|
||||
public boolean shareFiles(String path1, String path2) {
|
||||
// better save than sorry
|
||||
if (QtNative.activity() == null)
|
||||
return false;
|
||||
|
||||
Log.d(TAG + " shareFile - trying to share: ", path1 + " and " + path2);
|
||||
|
||||
// Can't get this to work building my own intent, so let's use the IntentBuilder
|
||||
Intent shareFileIntent = ShareCompat.IntentBuilder.from(QtNative.activity()).getIntent();
|
||||
shareFileIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
|
||||
|
||||
// now figure out the URI we need to share the first file
|
||||
File fileToShare = new File(path1);
|
||||
Uri uri;
|
||||
try {
|
||||
uri = FileProvider.getUriForFile(QtNative.activity(), fileProviderAuthority, fileToShare);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(TAG + " shareFile - cannot get URI for ", path1);
|
||||
return false;
|
||||
}
|
||||
Log.d(TAG + " shareFile - URI for file: ", uri.toString());
|
||||
|
||||
// because we allow up to two attachments, we use ACTION_SEND_MULTIPLE and so the attachments
|
||||
// need to be an ArrayList - even if we only add one attachment this still works
|
||||
ArrayList<Uri> attachments = new ArrayList<Uri>();
|
||||
attachments.add(uri);
|
||||
|
||||
// if there is a second file name (that's for support emails) add it and set this up as support email as well
|
||||
if (path2 != "") {
|
||||
fileToShare = new File(path2);
|
||||
try {
|
||||
uri = FileProvider.getUriForFile(QtNative.activity(), fileProviderAuthority, fileToShare);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(TAG + " shareFile - cannot get URI for ", path2);
|
||||
return false;
|
||||
}
|
||||
Log.d(TAG + " shareFile - URI for file: ", uri.toString());
|
||||
attachments.add(uri);
|
||||
// recipients are also always an array, even if there's only one
|
||||
shareFileIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { "in-app-support@subsurface-divelog.org" });
|
||||
shareFileIntent.putExtra(Intent.EXTRA_SUBJECT, "Subsurface-mobile support request");
|
||||
shareFileIntent.putExtra(Intent.EXTRA_TEXT, "Please describe your issue here and keep the attached logs.\n\n\n\n");
|
||||
}
|
||||
shareFileIntent.setType("text/plain");
|
||||
shareFileIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments);
|
||||
shareFileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
shareFileIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
Log.d(TAG + " sendFile ", " create activity for the Intent");
|
||||
// this actually allows sharing with any app that will take "text/plain" files, including Dropbox, etc
|
||||
// in order for the recipient / subject to work, the user needs to be clever enough to share with an email app
|
||||
QtNative.activity().startActivity(shareFileIntent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isIntentPending;
|
||||
public static boolean isInitialized;
|
||||
private static final String TAG = "subsurfacedivelog.mobile";
|
||||
|
|
Loading…
Add table
Reference in a new issue