Fixed android30

This commit is contained in:
matlabbe
2022-01-05 21:39:27 -05:00
parent 528b640a18
commit ab50ba0b6c
4 changed files with 228 additions and 86 deletions

View File

@@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
@@ -18,6 +19,11 @@
<!-- This is the platform API where depth16 support in android was introduced. --> <!-- This is the platform API where depth16 support in android was introduced. -->
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" /> <uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
<queries>
<package android:name="com.google.ar.core" />
<package android:name="com.huawei.ar.engine" />
</queries>
<!-- This .apk has no Java code itself, so set hasCode to false. --> <!-- This .apk has no Java code itself, so set hasCode to false. -->
<application <application
android:label="@string/app_name" android:label="@string/app_name"
@@ -42,7 +48,16 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\.db" />
</intent-filter>
</activity> </activity>
<activity android:name="SettingsActivity" android:label="@string/settings" android:screenOrientation="fullSensor"/> <activity android:name="SettingsActivity" android:label="@string/settings" android:screenOrientation="fullSensor"/>

View File

@@ -19,7 +19,7 @@
<string name="light_off">Lighting</string> <string name="light_off">Lighting</string>
<string name="wireframe">Wireframe</string> <string name="wireframe">Wireframe</string>
<string name="close_visualization">Close Visualization</string> <string name="close_visualization">Close Visualization</string>
<string name="save_to_file">Export to File&#8230;</string> <string name="save_to_file">Export OBJ/PLY&#8230;</string>
<string name="share_to_sketchfab">Share to Sketchfab&#8230;</string> <string name="share_to_sketchfab">Share to Sketchfab&#8230;</string>
<string name="start">Start</string> <string name="start">Start</string>
<string name="nodes">"Nodes (WM): "</string> <string name="nodes">"Nodes (WM): "</string>
@@ -80,7 +80,7 @@
<string name="pref_default_fisheye">false</string> <string name="pref_default_fisheye">false</string>
<string name="pref_key_camera_driver">pref_key_camera_driver</string> <string name="pref_key_camera_driver">pref_key_camera_driver</string>
<string name="pref_default_camera_driver">3</string> <string name="pref_default_camera_driver">-1</string>
<string name="pref_key_depth_from_motion">pref_key_depth_from_motion</string> <string name="pref_key_depth_from_motion">pref_key_depth_from_motion</string>
<string name="pref_default_depth_from_motion">false</string> <string name="pref_default_depth_from_motion">false</string>
<string name="pref_key_arcore_localization_filtering_speed">pref_key_arcore_localization_filtering_speed</string> <string name="pref_key_arcore_localization_filtering_speed">pref_key_arcore_localization_filtering_speed</string>
@@ -381,12 +381,14 @@
<string name="pref_summary_db_in_memory">The database is kept in RAM for fast access. Set to false to reduce RAM used at the cost of slower access. This parameter is applied on reset or when a database is opened.</string> <string name="pref_summary_db_in_memory">The database is kept in RAM for fast access. Set to false to reduce RAM used at the cost of slower access. This parameter is applied on reset or when a database is opened.</string>
<string-array name="pref_camera_driver_keys"> <string-array name="pref_camera_driver_keys">
<item>"Auto"</item>
<item>"Google Tango NDK"</item> <item>"Google Tango NDK"</item>
<item>"ARCore NDK"</item> <item>"ARCore NDK"</item>
<item>"AREngine NDK"</item> <item>"AREngine NDK"</item>
<item>"ARCore Java"</item> <item>"ARCore Java"</item>
</string-array> </string-array>
<string-array name="pref_camera_driver_values"> <string-array name="pref_camera_driver_values">
<item>"-1"</item>
<item>"0"</item> <item>"0"</item>
<item>"1"</item> <item>"1"</item>
<item>"2"</item> <item>"2"</item>

View File

@@ -688,7 +688,7 @@ public class ARCoreSharedCamera {
if(mToast!=null && previousAnchorPose != null) if(mToast!=null && previousAnchorPose != null)
{ {
String msg = "Tracking lost! If you are mapping, you will need to relocalize before continuing."; String msg = "Tracking lost! If you are mapping, you will need to relocalize before continuing.";
if(!mToast.getView().isShown()) if(mToast.getView() == null || !mToast.getView().isShown())
{ {
mToast.makeText(mActivity.getApplicationContext(), mToast.makeText(mActivity.getApplicationContext(),
msg, Toast.LENGTH_LONG).show(); msg, Toast.LENGTH_LONG).show();
@@ -736,7 +736,7 @@ public class ARCoreSharedCamera {
+ "because of high speed detected (%f m/s) causing a jump! You can change " + "because of high speed detected (%f m/s) causing a jump! You can change "
+ "ARCore localization filtering speed in Settings->Mapping if you are " + "ARCore localization filtering speed in Settings->Mapping if you are "
+ "indeed moving as fast.", speed); + "indeed moving as fast.", speed);
if(!mToast.getView().isShown()) if(mToast.getView() == null || !mToast.getView().isShown())
{ {
mToast.makeText(mActivity.getApplicationContext(), msg, Toast.LENGTH_LONG).show(); mToast.makeText(mActivity.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
} }

View File

@@ -2,6 +2,7 @@ package com.introlab.rtabmap;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -25,6 +26,8 @@ import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener; import android.content.DialogInterface.OnShowListener;
@@ -35,6 +38,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.hardware.Camera; import android.hardware.Camera;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
@@ -46,6 +50,7 @@ import android.hardware.display.DisplayManager;
import android.location.Location; import android.location.Location;
import android.location.LocationListener; import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.media.MediaScannerConnection;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiInfo; import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
@@ -56,6 +61,8 @@ import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.content.FileProvider; import android.support.v4.content.FileProvider;
import android.text.InputType; import android.text.InputType;
@@ -257,6 +264,8 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
ARCoreSharedCamera mArCoreCamera = null; ARCoreSharedCamera mArCoreCamera = null;
int mCameraDriver = 0; int mCameraDriver = 0;
private String mIntentDbToOpen = null;
//Tango Service connection. //Tango Service connection.
boolean mCameraServiceConnectionUsed = false; boolean mCameraServiceConnectionUsed = false;
ServiceConnection mCameraServiceConnection = new ServiceConnection() { ServiceConnection mCameraServiceConnection = new ServiceConnection() {
@@ -294,7 +303,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
} }
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
// Handle this if you need to gracefully shutdown/retry // Handle this if you need to gracefully shutsaveDatabasedown/retry
// in the event that Tango itself crashes/gets upgraded while running. // in the event that Tango itself crashes/gets upgraded while running.
mToast.makeText(getApplicationContext(), mToast.makeText(getApplicationContext(),
String.format("Tango disconnected!"), mToast.LENGTH_LONG).show(); String.format("Tango disconnected!"), mToast.LENGTH_LONG).show();
@@ -495,9 +504,10 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mTotalLoopClosures = 0; mTotalLoopClosures = 0;
mLastFastMovementNotificationStamp = System.currentTimeMillis()/1000; mLastFastMovementNotificationStamp = System.currentTimeMillis()/1000;
if(Environment.getExternalStorageState().compareTo(Environment.MEDIA_MOUNTED)==0) if(Environment.getExternalStorageState().compareTo(Environment.MEDIA_MOUNTED)==0 &&
getActivity().getExternalFilesDirs(null).length >=1)
{ {
File extStore = Environment.getExternalStorageDirectory(); File extStore = getActivity().getExternalFilesDirs(null)[0];
mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/"; mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
extStore = new File(mWorkingDirectory); extStore = new File(mWorkingDirectory);
extStore.mkdirs(); extStore.mkdirs();
@@ -507,7 +517,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{ {
// show warning that data cannot be saved! // show warning that data cannot be saved!
mToast.makeText(getApplicationContext(), mToast.makeText(getApplicationContext(),
String.format("Failed to get external storage path (SD-CARD, state=%s). Saving disabled.", String.format("Failed to get external storage path (state=%s). Saving disabled.",
Environment.getExternalStorageState()), mToast.LENGTH_LONG).show(); Environment.getExternalStorageState()), mToast.LENGTH_LONG).show();
} }
@@ -574,22 +584,136 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
DISABLE_LOG = !( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) ); DISABLE_LOG = !( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
if (!PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
PermissionHelper.requestPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
else
{
postCreate();
}
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver)); String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver));
mCameraDriver = Integer.parseInt(cameraDriverStr); mCameraDriver = Integer.parseInt(cameraDriverStr);
isArCoreAvailable(); isArCoreAvailable();
isArEngineAvailable(); isArEngineAvailable();
if (!PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
PermissionHelper.requestPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
else
{
// Get intent, action and MIME type
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("application/octet-stream".equals(type)) {
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
String fileName = getFileName(imageUri);
Log.i(TAG, "Intent received: " + imageUri.getPath() + " Name:" + fileName);
if(fileName.endsWith(".db"))
{
File file = new File(mWorkingDirectory+fileName);
if(file.exists())
{
mToast.makeText(this, fileName + " already exists in RTAB-Map's library! Cannot be copied.", mToast.LENGTH_LONG).show();
}
else
{
copy(imageUri, file);
mIntentDbToOpen = fileName;
}
}
}
}
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
if (type.startsWith("application/")) {
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (imageUris != null) {
boolean added = false;
for(Uri imageUri: imageUris)
{
String fileName = getFileName(imageUri);
Log.i(TAG, "Intent received: " + imageUri.getPath() + " Name:" + fileName);
if(fileName.endsWith(".db"))
{
File file = new File(mWorkingDirectory+"/"+getFileName(imageUri));
if(!file.exists())
{
copy(imageUri, file);
added = true;
}
else
{
Log.e(TAG, fileName + " already exists in RTAB-Map's library! Cannot be copied.");
}
}
}
if(added)
{
openDatabase();
}
}
}
}
postCreate();
}
} }
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
public void copy(Uri uri, File file)
{
InputStream in;
try {
in = getApplicationContext().getContentResolver().openInputStream(uri);
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
// Should be called only if read/write permissions are granted! // Should be called only if read/write permissions are granted!
private void postCreate() private void postCreate()
{ {
@@ -610,6 +734,12 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver)); String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver));
mCameraDriver = Integer.parseInt(cameraDriverStr); mCameraDriver = Integer.parseInt(cameraDriverStr);
if(mCameraDriver == -1)
{
// Prioritize tango if available
mCameraDriver = 0;
}
if(mCameraDriver == 0 && (!CheckTangoCoreVersion(MIN_TANGO_CORE_VERSION) || !RTABMapLib.isBuiltWith(nativeApplication, 0))) if(mCameraDriver == 0 && (!CheckTangoCoreVersion(MIN_TANGO_CORE_VERSION) || !RTABMapLib.isBuiltWith(nativeApplication, 0)))
{ {
if(mIsAREngineAvailable && RTABMapLib.isBuiltWith(nativeApplication, 2)) if(mIsAREngineAvailable && RTABMapLib.isBuiltWith(nativeApplication, 2))
@@ -2139,7 +2269,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mButtonCloseVisualization.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE); mButtonCloseVisualization.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
mButtonCloseVisualization.setEnabled(true); mButtonCloseVisualization.setEnabled(true);
mButtonSaveOnDevice.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE); mButtonSaveOnDevice.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
mButtonShareOnSketchfab.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE); //mButtonShareOnSketchfab.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
mButtonLibrary.setVisibility(View.INVISIBLE); mButtonLibrary.setVisibility(View.INVISIBLE);
mButtonNewScan.setVisibility(View.INVISIBLE); mButtonNewScan.setVisibility(View.INVISIBLE);
mItemSave.setEnabled(mState != State.STATE_VISUALIZING_CAMERA); mItemSave.setEnabled(mState != State.STATE_VISUALIZING_CAMERA);
@@ -2212,6 +2342,12 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{ {
mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
} }
if(mState == State.STATE_WELCOME && mIntentDbToOpen != null)
{
openDatabase(mIntentDbToOpen, false);
mIntentDbToOpen = null;
}
} }
private void startMapping() { private void startMapping() {
@@ -3304,7 +3440,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
context.sendBroadcast(mediaScanIntent); context.sendBroadcast(mediaScanIntent);
} }
private void saveDatabase(String fileName) private void saveDatabase(final String fileName)
{ {
final String newDatabasePath = mWorkingDirectory + fileName + ".db"; final String newDatabasePath = mWorkingDirectory + fileName + ".db";
final String newDatabasePathHuman = mWorkingDirectoryHuman + fileName + ".db"; final String newDatabasePathHuman = mWorkingDirectoryHuman + fileName + ".db";
@@ -3423,30 +3559,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
dialog.dismiss(); dialog.dismiss();
if(!fileName.isEmpty()) if(!fileName.isEmpty())
{ {
File newFile = new File(mWorkingDirectory + RTABMAP_EXPORT_DIR + fileName + ".zip"); writeExportedFiles(fileName);
if(newFile.exists())
{
AlertDialog ad = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("File Already Exists")
.setMessage("Do you want to overwrite the existing file?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
writeExportedFiles(fileName);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
saveOnDevice();
}
}).create();
ad.setCanceledOnTouchOutside(false);
ad.show();
}
else
{
writeExportedFiles(fileName);
}
} }
} }
}); });
@@ -3487,7 +3600,22 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
File exportDir = new File(mWorkingDirectory + RTABMAP_EXPORT_DIR); File exportDir = new File(mWorkingDirectory + RTABMAP_EXPORT_DIR);
exportDir.mkdirs(); exportDir.mkdirs();
final String pathHuman = mWorkingDirectoryHuman + RTABMAP_EXPORT_DIR + fileName + ".zip"; // cleanup old zip
fileNames = Util.loadFileList(mWorkingDirectory + RTABMAP_EXPORT_DIR, false);
if(!DISABLE_LOG) Log.i(TAG, String.format("Deleting %d files in \"%s\"", fileNames.length, mWorkingDirectory + RTABMAP_EXPORT_DIR));
for(int i=0; i<fileNames.length; ++i)
{
File f = new File(mWorkingDirectory + RTABMAP_EXPORT_DIR + "/" + fileNames[i]);
if(f.delete())
{
if(!DISABLE_LOG) Log.i(TAG, String.format("Deleted \"%s\"", f.getPath()));
}
else
{
if(!DISABLE_LOG) Log.i(TAG, String.format("Failed deleting \"%s\"", f.getPath()));
}
}
final String zipOutput = mWorkingDirectory+RTABMAP_EXPORT_DIR+fileName+".zip"; final String zipOutput = mWorkingDirectory+RTABMAP_EXPORT_DIR+fileName+".zip";
if(RTABMapLib.writeExportedMesh(nativeApplication, mWorkingDirectory + RTABMAP_TMP_DIR, RTABMAP_TMP_FILENAME)) if(RTABMapLib.writeExportedMesh(nativeApplication, mWorkingDirectory + RTABMAP_TMP_DIR, RTABMAP_TMP_FILENAME))
{ {
@@ -3513,7 +3641,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
final String msg = e.getMessage(); final String msg = e.getMessage();
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! Error=%s", pathHuman, msg), mToast.LENGTH_LONG).show(); mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! Error=%s", fileName, msg), mToast.LENGTH_LONG).show();
} }
}); });
} }
@@ -3529,30 +3657,41 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
final File f = new File(zipOutput); final File f = new File(zipOutput);
final int fileSizeMB = (int)f.length()/(1024 * 1024); final int fileSizeMB = (int)f.length()/(1024 * 1024);
AlertDialog d = new AlertDialog.Builder(getActivity()) // Save to public Documents/RTAB-Map folder
.setCancelable(false) /*ContentValues values = new ContentValues();
.setTitle("Mesh Saved!") values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName); //file name
.setMessage(String.format("Mesh \"%s\" (%d MB) successfully exported! Share it?", pathHuman, fileSizeMB)) values.put(MediaStore.MediaColumns.MIME_TYPE, "application/zip"); //file extension, will automatically add to file
.setPositiveButton("Yes", new DialogInterface.OnClickListener() { values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS + "/RTAB-Map"); //end "/" is not mandatory
public void onClick(DialogInterface dialog, int which) { Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"),values);
// Send to... if (uri != null) {
Intent shareIntent = new Intent(); OutputStream out;
shareIntent.setAction(Intent.ACTION_SEND); try {
shareIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".provider", f)); out = getApplicationContext().getContentResolver().openOutputStream(uri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("application/zip");
startActivity(Intent.createChooser(shareIntent, "Sharing..."));
resetNoTouchTimer(true); InputStream in = new FileInputStream(zipOutput);
} byte[] buf = new byte[1024];
}) int len;
.setNegativeButton("No", new DialogInterface.OnClickListener() { while ((len = in.read(buf)) > 0) {
public void onClick(DialogInterface dialog, int which) { out.write(buf, 0, len);
resetNoTouchTimer(true); }
} in.close();
}).create(); out.close();
d.setCanceledOnTouchOutside(false);
d.show(); f.delete(); // remove private file
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
} */
// Send to...
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".provider", f));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("application/zip");
startActivity(Intent.createChooser(shareIntent, "Sharing..."));
resetNoTouchTimer(true);
} }
}); });
} }
@@ -3561,7 +3700,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
mProgressDialog.dismiss(); mProgressDialog.dismiss();
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", pathHuman), mToast.LENGTH_LONG).show(); mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", fileName), mToast.LENGTH_LONG).show();
resetNoTouchTimer(true); resetNoTouchTimer(true);
} }
}); });
@@ -3667,20 +3806,6 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
openThread.start(); openThread.start();
} }
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
private void shareToSketchfab() private void shareToSketchfab()
{ {
if (!PermissionHelper.hasPermission(this, Manifest.permission.INTERNET)) { if (!PermissionHelper.hasPermission(this, Manifest.permission.INTERNET)) {