I need to download huge file ( 160GB ) using my Cordova application. As file-transfer plugin was deprecated and suggested XMLHTTPRequest usage fails for huge failes, I downloaded cordova-plugin-background-download from https://github.com/sgrebnov/cordova-plugin-background-download. It works great for any iOS device, but it always fails on Android 13 with error
Unsupported path /storage/emulated/0/ ......
The error is when a temporary file is being crated. I assume, the problem is with this code:
this.setTempFileUri(Uri.fromFile(new File(android.os.Environment.getExternalStorageDirectory().getPath(),
Uri.parse(targetFileUri).getLastPathSegment() + "." + System.currentTimeMillis())).toString());
where
android.os.Environment.getExternalStorageDirectory().getPath()
returns invalid path.
Is there a workaround, how to make the plugin working on Android 13? I use the sample code from the plugin homepage on Github.
Line 114 of the src/android/BackgroundDownload.java file needs to be modified for proper functionality from
this.setTempFileUri(Uri.fromFile(new File(android.os.Environment.getExternalStorageDirectory().getPath(),
Uri.parse(targetFileUri).getLastPathSegment() + "." + System.currentTimeMillis())).toString());
to
this.setTempFileUri(Uri.fromFile(new File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS),
Uri.parse(targetFileUri).getLastPathSegment() + "." + System.currentTimeMillis())).toString());
Related
I looked for solutions from many places (Test programmatically if in Android 10+ the legacy external storage access is disabled, https://developer.android.com/google/play/expansion-files.html#Downloading, etc.), but don't know the exact cause of the error.
If app is downloaded from Google Play only in case for android 10 devices, it gives this error:
Caused by: java.lang.IllegalArgumentException: Couldn't get OBB info for /storage/emulated/0/Android/obb/packageName/main.package_version.packageName.obb
The program can find the obb file (even on android 10 devices)
File mainFile = new File(Environment.getExternalStorageDirectory() + "/Android/obb/" + packageName + "/" + "main." + packageVersion + "." + packageName + ".obb")
mainFile.getAbsolutpath()
gets the file path too. However, when Storage Manager is used for app that is downloaded from Google Play store
sm.mountObb(mainFile.getAbsolutePath(), null, mainObbStateChangeListener );
it cannot reach obb expansion file and terminates app with above error.
App can be downloaded from Google Play, but works only for android 9 or below devices. If I create apk and install it on android 10 device, the app can reach obb file without any problem.
What do I miss to be able run app on android 10 devices when it is downloaded from Google Play store? Help would be appreciated.
Update:
I found the cause of the error on Android 10 device, though I still don't know the answer:
If the apk version code (the version code in app gradle) matches to the version code in the obb file name (which it should be if I understood well (https://developer.android.com/google/play/expansion-files), then in the obbexpansionmanager class, the line
sm.mountObb(mainFile.getAbsolutePath(), null, mainObbStateChangeListener );
throws this error:
Caused by: java.lang.IllegalArgumentException: Couldn't get OBB info for /storage/emulated/0/Android/obb/packageName/main.package_version.packageName.obb.
If I change the downloaded app's obb file to a different version code (tested with version code 8, 1, 10 when apk's version code was 9) then app starts and above error does not come up. However, I cannot use different version code in the obb file's name other than the apk's version code to be able to download apk with obb from Google Play store. Furthermore, the media files cannot be reached from obb file unless it matches version codes.
If the device is under Android 10 then app works with same version code in apk and in obb expansion file.
A substitute method can be used instead of Environment.getExternalStorageDirectory() which is Context.getObbDir() which will return the full path of the OBB directory meant for the running application, i.e.: /storage/emulated/0/Android/obb/packageName.
This can replace the code part Environment.getExternalStorageDirectory() + "/Android/obb/" + packageName. More details of this method can be found here.
I'm trying to copy a default initialized database packaged in the assets folder to an permanent location in an android device. For this I hav the following code:
QString db_file = "/my_db";
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
QFile assets_path("assets:" + db_file);
assets_path.copy(path + db_file);
QFile::setPermissions(path + db_file, QFileDevice::ReadUser |
QFileDevice::WriteUser);
And then I would go on to open the database in this new path, the thing is I'm getting the following error after the copy.
Copy error "Cannot create /data/user/0/org.qtproject.Demo/files/my_db for output"
What am I doing wrong?. Is also this the correct/proper way to do this?
Thanks.
Well aparently is a bug in Qt 5.10 prebuilt version, rolled back to Qt 5.9 and it works. Its a shame since I needed the QML translation functions.
https://bugreports.qt.io/browse/QTBUG-64103
I'm developing a crossplatform application in HTML5/CSS/JS using Phonegap 5.1.1. I'm struggling to find a solution to integrate the official phonegap-plugin-barcodescanner, following the instructions which the official page on GitHub refers to. In detail, after building through Phonegap Build, I can't get rid of the Help page which appears as soon as I start the app on Android (see the ). This way I cannot test if everything's working fine.
Furthermore, I've found out there are loads of ways to initialize the plugin and I'd like to know whether I'm doing anything wrong. Here's the code in my page:
var scanner = cordova.require("cordova/plugin/BarcodeScanner");
scanner.scan(
function (result) {
alert("We got a barcode\n" +
"Result: " + result.text + "\n" +
"Format: " + result.format + "\n" +
"Cancelled: " + result.cancelled);
},
function (error) {
alert("Scanning failed: " + error);
});
Finally, I've modified my config.xml as to include:
<gap:plugin name="BarcodeScanner"/>
Any suggestions?
Thanks in advance.
please add bellow permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
I found the solution myself. In case anyone is looking for a ready-to-use way to start, here's the way to go.
If you're using Phonegap Build online service, you need not add any plugin via
phonegap plugin add <plugin_name> (or cordova plugin add). It'll be sufficient to simply mimic the behavior of the official Phonegap BarcodeScanner Demo, particularly as regards the files:
<appname>/config.xml (referencing the plugin com.phonegap.plugins.barcodescanner);
<appname>/index.html (which includes the line <script src="barcodescanner.js" />);
<appname>/js/index.js (which contains the scan and encode methods, as well as their initialization).
As soon as the app is built, Phonegap Build will inject the official plugin by itself within the package.
When I compile APK using Crosswalk (ionic browser add crosswalk; ionic build android), the size is too big (~20 MB). I think using crosswalk lite will reduce the size of compiled APK. But I have no idea to hack ionic-cli to use crosswalk lite.
My question is:
1. Will this support crosswalk lite?
2. Is there any hack (or temporary solution) to use crosswalk lite?
Thanks.
This is experimentary , but it will work , cant guarantee there will be no bugs when you build your app though , please read this well before you proceed.
Procedure : ( all steps are done from a machine running MS-Windows 8.1)
First of all, I have searched for available crosswalk-lite everywhere to download the version from , it appears that there are only 3 available versions to download found here , and as you can see the latest is 10.39.234.1 i tried later versions like 12.xx , 13.xx , and 14.xx but in vain , could not find any repo for later versions.
Navigate to your npm node-modules folder : default in windows is
C:\Users\#YOUR_USER_NAME\AppData\Roaming\npm\node_modules
find the ionic module folder , and then , and start editing browser.js file , file can be found inside:
node_modules\ionic\lib\ionic\browser.js
In your code editor find the line #169 :
IonicTask.prototype.downloadCrosswalkWebview = function downloadCrosswalkWebview(architecture, version, releaseStatus) {
.....
}
this function is responsible for downloading the crosswalk version you want , and it takes the following parameters :
architecture , version and releaseStatus.
We will be adding our lite version manually , so we can download it later.
We will be changing some value temporarily for downloading lite version , but remmeber to turn it back to its original value later :
in line#178 :
change
var downloadUrl = 'https://download.01.org/crosswalk/releases/crosswalk/android/' + releaseStatus + '/' +
version + '/' + architecture + '/crosswalk-webview-' + version + '-' + architecture + '.zip';
to be :
var downloadUrl = 'https://download.01.org/crosswalk/releases/crosswalk-lite/android/' + releaseStatus + '/' +
version + '/' + architecture + '/crosswalk-webview-' + version + '-' + architecture + '.zip';
in line#39 there is an array of objects crosswalkVersions , add this object to it :
{
version: '10.39.234.1',
publish_date: '2015-03-06 03:06',
canary: true
}
You can test that object is added successfully running this command in your CLI :
ionic browser list
and as you can see it got listed in available versions:
Final step is to download your crosswalk-lite project into your project folder via CLI Command :
ionic browser add crosswalk#10.39.234.1
That is all you are done.
P.S:
I have never tried ionic in building my hybrid projects.
Forget about Ionic-cli crosswalk-lite, it relies on cordova-plugin-crosswalk-webview, but cordova-plugin-crosswalk-webview does not support crosswalk-lite for now. If you wanna use crosswalk-lite, you will have to use cordova-android 3.0 way with CordovaLib provided with crosswalk-lite-cordova (https://download.01.org/crosswalk/releases/crosswalk-lite/android/canary/10.39.237.1/arm/crosswalk-cordova-10.39.237.1-arm.zip), because latest crosswalk-lite is 10.0. Good news is the team is working on rebasing lite to 14.0. Hopefully it comes out ASSP.
Ionic-cli now has an option for lite:
ionic browser list
ionic browser add crosswalk-lite
although, you may want to see this post
I'm new to phonegap and I need to know where to put files in a local folder and how to access them. I tried to build my app in my computer with eclipse and so on, but there is too much stuff to install, user variables, command lines ... I tried but it doesn't work and I don't know where is the problem, then I tried to build my app from build.phonegap.com and it worked perfectly. The problem I have is that I need to read an audio file, I tried the Audio object, and the Media object, but they don't work.
I looked for the solution and I found that you have to put your local files in assets/ or android_assets/ and you need to access them, I don't know how
/assets/file.wav
file:///android_assets/file.wav
so I started adding folders like assets/, android_assets/, audios/, whatever/ but nothing works.
can you please tell me where to put my files and how to access them. no command lines, no eclipse... just manually before building the app from build.phonegap.com
Here is a useful link, that maybe helps: link
Have you installed the file plugin? Because this is necessary for it. If not, first of all you need to install it, type in the command line in the project's folder this command (it isn't hard):
cordova plugin add org.apache.cordova.file
According to the file plugin documentation, the best place is to store files is the following path:
file:///data/data/{app-id}/files/files/{your folder}/{your files}
For example: file:///data/data/com.phonegap.myapp/files/files/audio/file.wav
This is persistent, readable/writable, the os doesn't clear it and private.
"Persistent and private data storage within the application's sandbox using internal memory"
Within your program you can refer it this way: cordova.file.dataDirectory
For example here is a code from my app that download an image from a URL and put it to HTML in an image tag:
window.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) {
var imageURL = "http://example.com/image.jpeg";
var ext = imageURL.substr(imageURL.lastIndexOf('.') + 1); //extension of the image
var relativeFilePath = "images/myimage" + "." + ext;
var ft = new FileTransfer();
ft.download(imageURL, fileSystem.root.toURL() + relativeFilePath, function(entry) {
var myImage= "<img src=" + fileSystem.root.toURL() + relativeFilePath + "' id=" + "imageID" + ">";
alert(fileSystem.root.toURL() + relativeFilePath); //kép
$('#imgdiv').html(myImage);
}, function(err) { alert("Download failure: " + JSON.stringify(err)); });
}, function(err) { alert("requestFileSystem failure: " + JSON.stringify(err)); });
In this code the fileSystem.root.toURL() refers to file:///data/data/com.phonegap.myapp/files/files/
and relativeFilePath is created by me, refers to images/myimage.jpeg
(for the download you need the file-transfer plugin, you can install with the
cordova plugin add org.apache.cordova.file-transfer command).
I hope this helps.
#Khalid You must create project manually:
project_folder
|___index.html
|___audio_folder
|___any resources or folder
Please check document from Phonegap Build
Edit 1: To play media file by Media object
// Get path 'www' in Android
function getPathApp(){
return location.href.slice(0,-10);
}
var media = new Media(getPathApp() + 'audio/file.wav');
// In IOS only need path from audio folder
var media = new Media('audio/file.wav');
media.play();