Qgroundcontrol Android file sharing

In qgroundcontrol Android I don’t see a way to share (import/export) files with other locations such as an email attachment.
Is this the expected behavior?
If so, does anyone have suggestions for implementing this on Android?

Background

Currently the Android app can upload and download files like .params and .plan to a connected aircraft.
Also the user can add waypoints and save them as a .plan file.

In Plan view / Plan Tools / File / Plan File / Open opens a window in the horizontal center of the screen.
Choosing directory Desktop navigates to 0/org/mavlink.qgroundcontrol/files and it contains a subdirectory QGCMapCache300.
Tapping the up arrow twice shows full path is /data/user/0/org/mavlink.qgroundcontrol/files.
However the path fills most of the line, making it difficult to select the end and append /my_plan.plan

Proposed file sharing

I read Ekke’s blog posts, and in a private branch implemented part of it (for more info see References and Appendix).

In AndroidManifest.xml register as a FileProvider.
In PlanMasterController.cc if the app is first launch it calls Ekke’s checkPermission() method to prompt the user for file permissions.
If the user taps “Allow”, and manually stops and restarts the app it changes the application data file path.
After that, the plan view file chooser appears on the right and the style is prettier, colors and font more consistent with the rest of qgroundcontrol.
At this point the user can use the Android Files app to access qgroundcontrol files in app subdirectories like Missions and Parameters.

I tried programmatically restarting the Android app- it quits but doesn’t automatically come back to the foreground.

References

qgroundcontrol git branch master, commit 4509f4b12c55266afe75c32df4d455dfdcaaf15e 2018-12-07


Appendix

applicationui.cpp similar to ekkesSHAREexample

#include "applicationui.hpp"

#include <QDebug>
#include <QtAndroid>
#include <qapplication.h>


#if defined(Q_OS_ANDROID)
/// The key under which the Android settings are saved
const char* ANDROID_SETTINGS_GROUP = "QGC_ANDROID";
QString IS_NOT_FIRST_LAUNCH_KEY = "IS_NOT_FIRST_LAUNCH";
#endif

ApplicationUI::ApplicationUI(QObject *parent) : QObject(parent)
{
}

#if defined(Q_OS_ANDROID)

// we don't need permissions if we only share files to other apps using FileProvider
// but we need permissions if other apps share their files with out app and we must access those files
bool ApplicationUI::checkPermission()

{
QtAndroid::PermissionResult r = QtAndroid::checkPermission(“android.permission.WRITE_EXTERNAL_STORAGE”);
if(r == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync( QStringList() << “android.permission.WRITE_EXTERNAL_STORAGE” );
r = QtAndroid::checkPermission(“android.permission.WRITE_EXTERNAL_STORAGE”);
if(r == QtAndroid::PermissionResult::Denied) {
qDebug() << “Permission denied”;
// emit noDocumentsWorkLocation();
return false;
}
}
qDebug() << “YEP: Permission OK”;
return true;
}

/// restarts app, e.g. so file write external storage permissions will take effect
void ApplicationUI::restartApp()
{
qDebug() << “ApplicationUI::restartApp()”;

saveSettingsIsNotFirstLaunch();

// https://richardstechnotes.com/2014/06/28/restarting-a-qt-app-programmatically/
// https://forum.qt.io/topic/9102/solved-which-method-of-the-main-widget-returns-the-qapplication-instance/4

// QStringList args = QApplication::arguments();
// args.removeFirst();
// QProcess::startDetached(QApplication::applicationFilePath(), args);
// QCoreApplication::quit();

// https://stackoverflow.com/questions/5129788/how-to-restart-my-own-qt-application

// qApp->quit();
// QProcess::startDetached(qApp->arguments()[0], qApp->arguments());

// https://stackoverflow.com/questions/10068983/why-does-calling-quit-before-exec-not-quit-the-application

// QTimer::singleShot(0, qApp, &QCoreApplication::quit);

// QStringList args = QApplication::arguments();
// args.removeFirst();
// QProcess::startDetached(QApplication::applicationFilePath(), args);
// QTimer::singleShot(0, qApp, SLOT(quit()));

QStringList args = QApplication::arguments();
args.removeFirst();
QProcess::startDetached(QApplication::applicationFilePath(), args);
QTimer::singleShot(0, qApp, &QCoreApplication::quit);

}

/// Use “negative” condition to avoid potential confusion about key-value pair never set
void ApplicationUI::saveSettingsIsNotFirstLaunch()
{
QSettings settings;
settings.beginGroup(ANDROID_SETTINGS_GROUP);
settings.setValue(IS_NOT_FIRST_LAUNCH_KEY, true);
settings.endGroup();
}

bool ApplicationUI::isNotFirstLaunch()
{
QSettings settings;
settings.beginGroup(ANDROID_SETTINGS_GROUP);
bool isNotFirst = settings.value(IS_NOT_FIRST_LAUNCH_KEY).toBool();
settings.endGroup();
return isNotFirst;
}

#endif

Plan files by default should be stored in the QGroundControl/Mission directory on the device. You should be able to acces this from My Files and move things in and out of there as you like. You don’t need a different build.

Are you using the latest Stable 3.5 version of QGC. It sounds like you are getting a regular filer picker somehow. But I’m not sure. A screenshot would be helpful. On mobile builds you should get a simplified file chooser as a right dialog.

Thanks. I’ve been working on doing something similar to this and hadn’t seen you already did much of it!
After your reply I downloaded release 3.5.0 from Google play store.
Also I found your commit 2019-01-20 “Fix write storage permission problem”

In Android if the user allows file permissions it seems they don’t take effect until the app is stopped (not just paused) and restarted.
On first launch, the file dialog appears in the center. The user can save files:

After stopping and restarting the app, the root file path changes.
I think any files saved during the app’s first launch are unreachable.
The file dialog appears on the right:

On second launch files are available for sharing in the Files app.

That’s why I was trying to programmatically stop and restart the app immediately after the user allows file permission.

Are you sure the version you started which gave you the file picker was the new 3.5? An not an older version which was already running in the background on the device?

Hello, I’m having the same issue. I am using qgroundcontrol 4.1.1 on Android 10 and only get the following interface when trying to save or open files. I’ve tried force stop or creating various file paths but to no avail. I’ve checked app permissions and those are wide open. I’ve saved files in these directories to test, but they are not discoverable outside of qgroundcontrol.

Update: After exploring the forum I found this link: https://qgroundcontrol.s3-us-west-2.amazonaws.com/builds/Stable_V4.0/QGroundControl32.apk which works. It gives me the proper file management window that opens on the right of the screen. Out of curiosity I uninstalled this older version (and also noted that the file structure for saving missions remained) then installed the most recent stable version. Now the file window does appears to the right like it should, however it doesn’t show the files (although when I tried saving with the same name it prompted if I wanted to overwrite, so it knows it’s there) that I saved in there while using v4.0 and when I try to save it says I don’t have permission to save in /storage/emulated/0/QGroundControl/Missions/. So when it sees I have the right file structure it allows the right file mgmt window, but won’t let me save…?

Noticed a difference between 4.0 and 4.1.1 during first launch of app and requesting permissions. 4.1.1 doesn’t request permission to access files. Problem?

4.0

4.1.1

I am having the same problem using qgc 4.1.1 on Android 10. I can’t access your link that fixed it for you. When I try, I see this:

Can you repost the link, or direct me where to find it? Thanks!

Hmm, it appears we’ve lost access since last week. I get the same message, even though it worked before.

@DonLakeFlyer Do you by chance know where we can get the APK for a version that fixes the Save/open Plan feature On Android 10?

qgc 4.1.1 from google play, currently looks like this when trying to Open or Save a mission plan:
image

and to @newfolder9 's point: he pointed out a difference between version 4.0 and 4.1.1 that when asking permissions it no longer asks for permission to access files.

I noticed that this may be a problem specifically with android 10. I installed qgc 4.1.1 on an older android (running android 7 nougat) and it asked for permission to access files, and I was able to save and open mission plans with no problems.

So it may be a combination of 4.1.1 with android 10’s new permission management system that is causing the bug.

I figured out a workaround to get 4.1.1 to allow file sharing.

The file sharing problems only happen if 4.1.1 is the first version you’re installing on Android. When I install an older version (4.0 that properly allows photo, media AND file sharing) and then update the app, it will bring forward the permissions and work.

This may be why more people haven’t brought this issue up, if they’ve updated from a version that worked.

This doesn’t work because 4.0 created the save file structure as I’ve seen suggested elsewhere. I’ve deleted 4.0, kept the save file structure, then installed 4.1.1. Didn’t work. It only works when I update the 4.0 to 4.1.1.

Hey, that worked! Good call. Thank you!

Can someone create a GitHub Issue with the details for all of this and then I can take a look.

Done!