Can I install the app on my phone but store the .mmpk files on the external storage card? If so how do I point to this new location?
OK I added the code below to try and get the path....downloaded to my phone and the results are below.
Note the results are printed 2 times via the For Loop
RESULTS ON PHONE:
pathTV is: /storage/self /storage/self
fsTV is: tmpfstmpfs
devTV is: tmpfstmpfs
urlTV is: /storage/selffile:///storage/self
fileFTV is: /storage/selfundefined
STILL DOES not work.....ANY THOUGHTS????
import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtGraphicalEffects 1.0
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import Esri.ArcGISRuntime 100.2
App {
property var pathTV: "path"
property var fsTV: "fstv"
property var devTV: "devtv"
property var urlTV: "urltv"
property var fileFTV: "fileFTV"
id: app
width: 400
height: 640
Text {
anchors {
top:parent.top
horizontalCenter: parent.horizontalCenter
margins: 20
}
text:"StorageInfo Details"
font.pointSize: 25
}
Text {
id:content2
anchors.fill: parent
text: "pathTV is: " + pathTV +
"\n fsTV is: " + fsTV +
"\n devTV is: "+ devTV +
"\n urlTV is: "+ urlTV +
"\n fileFTV is: "+ fileFTV
font.pointSize: 16
color: "green"
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
anchors.margins: 10
}
StorageInfo {
id:storageInfo
}
Component.onCompleted: {
var pathT, fsT, devT, urlT, fileFT;
var path, fs, dev, url, fileF;
var mountedVols = storageInfo.mountedVolumes;
for (var i = 0; i < mountedVols.length; i++) {
fs = mountedVols[i].fileSystemType;
fsT = fs + mountedVols[i].fileSystemType;
dev = mountedVols[i].device
devT = dev + mountedVols[i].device
path = mountedVols[i].path;
pathT = path + mountedVols[i].path;
url = mountedVols[i].url;
urlT = path + mountedVols[i].url;
fileF = mountedVols[i].folder.FileFolder.folderName;
fileFT = path + mountedVols[i].folder.FileFolder.path;
}
pathTV = String(pathT);
fsTV = String(fsT);
devTV = String(devT);
urlTV = String(urlT);
fileFTV = String(fileFT);
}
}
From this I tried to specify the path in the MmpkManager as follows...
Top of the MmpkManager.qml
FileFolder{
id: fileFolder
// readonly property url storageBasePath: AppFramework.userHomeFolder.fileUrl("ArcGIS/AppStudio/Data")
readonly property url storageBasePath: "/storage/self/ArcGIS/AppStudio/Data"
property url storagePath: subFolder && subFolder>"" ? storageBasePath + "/" + subFolder : storageBasePath
url: storagePath
Component.onCompleted: {
if(!fileFolder.exists){
fileFolder.makeFolder(storagePath);
}
if(!fileFolder.fileExists(".nomedia") && Qt.platform.os === "android"){
fileFolder.writeFile(".nomedia", "");
}
}
}
Bottom of the MmpkManager.qml
Component{
id: typeNetworkRequestComponent
NetworkRequest{
id: typeNetworkRequest
property var callback
method: "GET"
ignoreSslErrors: true
onReadyStateChanged: {
if (readyState === NetworkRequest.DONE ){
if(errorCode != 0){
loadStatus = 2;
} else {
var root = JSON.parse(responseText);
if(root.type == "Mobile Map Package"){
loadStatus = 1;
var component = networkRequestComponent;
var networkRequest = component.createObject(parent);
var url = rootUrl+itemId+"/data";
var fileslocation = "/storage/self/ArcGIS/AppStudio/Data/QuickReport"
var path = [fileslocation, "~"+itemName].join("/");
networkRequest.downloadFile("~"+itemName, url, path, typeNetworkRequest.callback);
} else {
loadStatus = 2;
}
}
}
}
function checkType(url, callback){
typeNetworkRequest.url = url;
typeNetworkRequest.callback = callback;
typeNetworkRequest.send();
loadStatus = 1;
}
}
}
This is weird. The path seems good, what is the make and model of the phone you are testing? OS version?
Im going nuts here....Its going to be something so small....
Samsung Galaxy J7 V
Model Number: SM-J727V
Hardware Version: J727V.02
Android Version: 8.1.0
Kernal Version 3.18.71
Build Number: M1AJQ.J727VVRS3BSD1
Thanks for your input it is greatly appreciated.
I didn't set : String[] reqPermission = new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE };
Because I think that setting is already set in the Properties of the Quick Report Template.
Im lost here.
I changed my code for a few examples and can write to the Internal Storage like this:
The BELOW examples allow me to write to the internal storage....
BUT I still CANNOT write to the storage card.....uggggggg
Although.....the below shows that the code is working I just cannot get the SC Card Path correct.
Top of the mmpkmanager.qml
readonly property url storageBasePath: "file:///storage/emulated/0/ArcGIS/AppStudio/Data"
// OR
readonly property url storageBasePath: "file:///storage/self/primary/ArcGIS/AppStudio/Data"
Bottom of the mmpkManager.qml
var fileslocation = "/storage/emulated/0/ArcGIS/AppStudio/Data/QuickReport"
// OR
var fileslocation = "/storage/self/primary/ArcGIS/AppStudio/Data/QuickReport"
I found another possible “way” to find the path to the external storage of the Android device. It is by using the DocumentDialog plugin sample code posted below. Using this sample if you click on the button, it will open a “document dialog”, please navigate to the SD card, and then choose any file in the SD card. It will print that path to the file in the SD card, and let's see what that path says on your phone.
I tried this on SM-G960U1 running Android 9. The path returns something like this, "/data/user/0/....."
import QtQuick 2.7
import QtQuick.Controls 2.1
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Platform 1.0
App {
id: app
width: 400
height: 640
Text {
id: fileProperties
anchors.centerIn: parent
text: "Default"
font.pointSize: 12
}
Button {
text: "document"
anchors.top: dbgText.bottom
onClicked: {
console.log("supported ", doc.supported)
if (doc.supported)
{
doc.open()
}
else
{
dbgText.text = "Not Supported"
}
}
}
Component.onCompleted: {
dbgText.text = app.info.title
}
DocumentDialog {
id: doc
onAccepted: {
console.log("***FILE SELECTED***", filePath)
file.path = filePath
fileInfo.filePath = filePath
process()
}
onRejected: {
console.log("Cancelled by user")
}
}
FileInfo {
id: fileInfo
}
File {
id: file
}
function process() {
var fileDetails = {
exists : {
FILE : file.exists,
FILEINFO : {
isFile : fileInfo.isFile,
path : fileInfo.filePath,
url : fileInfo.url,
lastModified : fileInfo.lastModified,
isReadable : fileInfo.isReadable,
isWritable: fileInfo.isWritable,
size: fileInfo.size + " bytes"
}
}
}
fileProperties.text = JSON.stringify(fileDetails, undefined, 2)
}
}
OK going to have to look at this a bit...I ran the code and saw the button in the top left hand corner. I clicked it and a new page appeared that allowed me to navigate to the SD card. I then went into the DCIM folder and clicked on a jpg image. The screen moved to the side and was left with nothing but a Black screen.....tried this a few times with the same result...I will dive into the code a bit to see if I can modify something.
It works fine when I run it through AppStudio on my desktop but black screen appears on the phone...
Update:
I tried to make the text green to see if that would show up on the black background that I am seeing on the phone....
Not working...
Text {
id: fileProperties
anchors.centerIn: parent
text: "Default"
font.pointSize: 12
color: "Green"
}
Jay, the text does not matter, it can printed in the console log. The idea is to show the path when we select a file that is inside the SD card and see the path given.
where do I access the Console.log on my phone? Maybe I am not following sorry
console log message can be accessed using the AppStudio Console window if you are running the app inside the AppStudio Player. This is just an example, my point is we just want to see the path of the file inside the SD card.
This is weird that it is not showing on your end, I tested this on my end using the AppStudio Player and it is working, and it is showing the path of the file inside the SD card.