Android. ERROR_COULD_NOT_MOUNT while mounting complex ciphered obb file - android

I develop Android app, which uses ciphered obb file. This obb file consists of 3 files (I created it with jobb tool). On the most devices all is ok, but on the three devices there is ERROR_COULD_NOT_MOUNT. And I don't understand how to fix it. I want to distribute app without any errors :) Please, help me to do it! :)
That I have tryed:
1) Unmount and mount obb file;
2) Create obb file from the folder without "read-only" attribute.
But all of it won't work.
Steps to reproduce the problem (including sample code if appropriate).
1) Create folder, put into it 3 different files.
2) Create obb file from the folder from step 1.
3) Try to mount this file from the app (sample code below).
final File mainFile = new File(Environment.getExternalStorageDirectory() + "/Android/obb/" + packageName + "/"
+ "main." + versionCode + "." + packageName + ".obb");
OnObbStateChangeListener listener = new OnObbStateChangeListener() {
#Override
public void onObbStateChange(String path, int state) {
super.onObbStateChange(path, state);
if (state == OnObbStateChangeListener.MOUNTED) {
doNextSteps();
} else if (state == OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT) {
Toast.makeText(getApplicationContext(), "ERROR_COULD_NOT_MOUNT", Toast.LENGTH_LONG).show();
}
}
};
if (!storageManager.isObbMounted(mainFile.getAbsolutePath())) {
storageManager.unmountObb(mainFile.getAbsolutePath(), true, listener);
storageManager.mountObb(mainFile.getAbsolutePath(), "password_string", listener);
} else {
doNextSteps();
}
What happened.
I have "ERROR_COULD_NOT_MOUNT" error on the following devices:
1) HTC PJ401 One S;
2) Samsung GT-I9505 Galaxy S IV;
3) Samsung SM-N9005 Galaxy Note 3.
But on Samsung SM-N900T Galaxy Note 3 and Samsung GT-I9500 Galaxy S IV all is ok.

So, after all my investigations I can say. All I can to do is workaround. And I have created one file from the these 3 files by
copy /B file1+file2+file3 result_file.obb
And then I use this file as non-ciphered obb. After all this manipulations all works well.

I find the reason for some obb file could not be mounted. There a random solt when make obb file, an hashkey generated by PBKDF2WithHmacSHA1. the hashkey from bytes convert to hex string has a bug. I submit a patch to project : platform/framwork/base.
https://android-review.googlesource.com/#/c/230280/
I modified the jobb tool. Add check the hashkey to skip the wrong key generated. Before the Android merge the patch, you can use this patch. This patch also fix the dump files bug.
https://android-review.googlesource.com/#/c/231431/

Related

Cannot find files created using QStandardPath on android device

I'm developing an app on android using Qt 5.15.0. My app creates a database and some other files using QStandardPaths::AppDataLocation. everything works fine from the code side: debug output makes me think the files are there and that the app is using them. The problem is that when I search from the PC inside the smartphone folders I cannot find the files created. So this makes me think I am not writing to the folder I'm expecting to.
This is my code:
appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
QDir directory;
if (!directory.exists(appDataPath + QStringLiteral("/DATABASE")))
directory.mkpath(appDataPath + QStringLiteral("/DATABASE"));
if (!directory.exists(appDataPath + QStringLiteral("/DATA")))
directory.mkpath(appDataPath + QStringLiteral("/DATA"));
qDebug() << "Percorso: " << appDataPath << " dir exists:" << directory.exists(appDataPath + QStringLiteral("/DATABASE"));
QFile f( appDataPath + "/DATABASE/Prova.txt" );
if( f.open( QIODevice::WriteOnly ) )
{
f.write( "Ciao" );
f.close();
}
if( f.error() != QFileDevice::NoError )
qDebug() << QString("Error writing file '%1':").arg(appDataPath + "/DATABASE/Prova.txt") << f.errorString();
I also write a file that I read at startup and I can read from it so I assume the file is present and is not saved as temporary.
The output is:
D/MyApp(17849): Percorso: "/data/data/org.qtproject.example/files" dir exists: true
Now I suppose I can find my files in this directory inside the phone in this folder:
Questo PC\Samsung Galaxy J3 (2016)\Phone\Android\data\org.qtproject.example\files
But there are no directories or files inside. I bet I am missing some trivial things.
I am giving the app these permission:
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
Can someone help me?
Thanks in advance!
It seems that
QStandardPaths::AppLocalDataLocation, QStandardPaths::AppDataLocation
don't give the correct path to the app's file folder. I encountered the same issue with Qt 5.14.1. While QStandardPaths gave me
/data/user/0/com.mycompany.myapp/files
a call via a QAndroidJniObject to the java side gave me
/storage/emulated/0/Android/data/com.mycompany.myapp/files
Using the latter all directories and files were created correctly. I suggest to either try my work-around with
QtNative.activity().getExternalFilesDir(null).getAbsolutePath();
in an added java class and call it through a QAndroidJniObject or report this as a bug to Qt.
Nevertheless, there might be another solution to the problem I'm not aware of.

Still failing to mount APK expansion file?

I have a largely native Android game on my hands which has to employ APK expansion files for the usual reasons. The project targets API level 21, and is 64-bit only.
Downloading the APK expansion works.
Mounting does not work: for an unencrypted obb, I get an error state 20 (AOBB_STATE_ERROR_INTERNAL). For an encrypted one I get a 21 (AOBB_STATE_ERROR_COULD_NOT_MOUNT).
The APK expansion is created with the jobb tool.
The versionCode is matching the one in my AndroidManifest.xml.
The key (when used), is correct.
The obb file obviously exists, and I'm getting the obb mount path by the way of
String packageName = getPackageName(); // we're in the activity
PackageManager pm = getPackageManager();
return Environment.getExternalStorageDirectory().getAbsolutePath() +
EXP_PATH + packageName + "/main." +
pm.getPackageInfo(packageName, 0).versionCode + "." + packageName +
".obb";`.
The result I get is the same both with an NDK implementation and with a Java implementation.
I understand that this was broken for years, but it has been fixed. Is it really? What am I doing wrong?
After hours and hours of digging, and nearly abandoning hope all, I've found success. And it's ridiculous. But it works.
Make sure that the path you're feeding to storageManager.mountObb() (or AStorageManager_mountObb()) has any leading slashes removed. I.e.
if (obbPath != null && obbPath.startsWith('/'))
{
obbPath = obbPath.substring(1);
}
The one that you get from Environment.getExternalStorageDirectory() will have one.
Hope this helps save someone time.

Can't mount .obb file (state = 21) on Meizu m3 note

I've met with another strange issue with APK Expansion files (.obb-files). My expansion file mounts fine on all my test devices:
Sony Xperia Z1 Compact (API 22)
Sony Xperia Z1 Ultra (API 22)
LG Nexus 5X (API 23)
LG Nexus 4 (API 17)
I've created encrypted .obb file with jobb-utilite:
jobb -o obb-filename -d files-dir -k password -pn applicationId -pv versionCode
In my app I read .obb file with following code:
public void initialize(final Context context) {
final StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
final File mainObbFile = getMainObbFile();
final OnObbStateChangeListener listener = new OnObbStateChangeListener() {
#Override
public void onObbStateChange(String path, int state) {
super.onObbStateChange(path, state);
if (state == OnObbStateChangeListener.MOUNTED) {
// work with obb file
} else {
throw new RuntimeException("OnObbStateChangeListener::onObbStateChange - can't mount .obb file (state = " + state + ").");
}
}
};
final String key = BuildConfig.MAIN_XAPK_KEY;
if (storageManager.isObbMounted(mainObbFile.getAbsolutePath())) {
// work with obb file
} else if (!storageManager.mountObb(mainObbFile.getAbsolutePath(), key, listener)) {
throw new RuntimeException("Can't create listener for mounting .obb file.");
}
}
And everything works fine. But on Meizu m3 note (API 22) we got strange error: "OnObbStateChangeListener::onObbStateChange - can't mount .obb file (state = 21)".
Previously, I have met with this problem and it was solved with another generation of .obb-file. But in this case it did not help.
Also, I've tried to generate .obb file with fixed jobb tool (https://github.com/monkey0506/jobbifier.git), and it doesn't work.
May be anyone knows, what's wrong, why sometimes .obb files doesn't work on some devices?..
UPDATE
Also, I've checked mounting of non-encrypted .obb file on Meizu. It works.
Thanks in advance.
I had the same problem, and i figured out that many times Error 21 is
caused by Linux Files Permissions over the obb, and the problem is
that Android cannot have access to it so the StorageManager launches
Error 21. When you create the .obb file, change permissions and user
group to the file, something like:
$chmod 664 <obb-filename>.obb
$chown user:group <obb-filename>.obb
Then try again, worked for me.
I got same problem with Error code 21 i removed the -k password from:
jobb -o obb-filename -d files-dir -pn applicationId -pv versionCode
and passed null in mountObb method instead password
storageManager.mountObb(mainObbFile.getAbsolutePath(), null, listener)
I don't know why jobb not work with password, if someone know please share.

Python automated script file transferring

I am looking for a solution for copying all the files from a specific directory on the hard drive, to a specific or non specific directory on my android phone, once this device is connected.
I would like these files to be automatically moved (or at least copied) to my phone once I connect it to the computer and run the .py file.
I have windows 7 and python 2.7
I was trying this from another answer but I can't understand because there is few explanation, therefore I cannot get it to work.
edit: I have figured out how to transfer files between to folders but I want to my phone. So how can I fix the error of my system not finding the path of my phone, that'll fix my problem I believe. The code works fine the problem is the path.
Here is my code:
import os
import shutil
sourcePath = r'C:\Users\...\What_to_copy_to_phone'
destPath = r'Computer\XT1032\Internal storage'
for root, dirs, files in os.walk(sourcePath):
#figure out where we're going
dest = destPath + root.replace(sourcePath, '')
#if we're in a directory that doesn't exist in the destination folder
#then create a new folder
if not os.path.isdir(dest):
os.mkdir(dest)
print 'Directory created at: ' + dest
#loop through all files in the directory
for f in files:
#compute current (old) & new file locations
oldLoc = root + '\\' + f
newLoc = dest + '\\' + f
if not os.path.isfile(newLoc):
try:
shutil.copy2(oldLoc, newLoc)
print 'File ' + f + ' copied.'
except IOError:
print 'file "' + f + '" already exists'
I am sorry I am being handful but I thought I had solved it.
In theory, there is no way to access your phone's internal memmory with a drive letter, because, Android connects as an MTP device, and not as a Mass Storage device. But, there are some weird solutions:
Root the phone and get a application which enables "Mass Storage" .
If you can not root and if(only if) both the computer are on the same network, run FTP server in you phone, and you get access for file copy by ftp.
But for you case I recommend adb- adb push C:\src /phone_destination is the best solution.You can google and easily find out way to do this in python.
Google offers adb-sync, which is also available in python. This allows backup/synchronization of files on android device to PC.
The following github repo provides instructions on how to setup the process ie: enable USB Debugging, etc... however I suggest installing 15 second adb installer as opposed to downloading/installing the massive Android SDK just to get adb.
adb-sync: https://github.com/google/adb-sync
15 Sec ADB installer: https://forum.xda-developers.com/showthread.php?t=2588979
A little late to answer, but I use SSH certs and crontab to run a ping command against my local IP and pipe that to an scp recursive copy. It will copy any changes over. No issue yet, and it's been running 4 years straight. I can't for the life of me find the command line that's running.

File created from Android app is not visible until renamed

everybody!
I create a file in my android app with this code, run in UI thread:
final File dir = Environment.getExternalStorageDirectory();
final File file = new File(dir, "file" + System.currentTimeMillis()); //$NON-NLS-1$
try
{
file.createNewFile())
}
catch (Exception e)
{
...
}
and I can't see it on my Win7 PC, until I rename the file on the phone with the file browser. I run the program on Samsung Galaxy Nexus, OS ver 4.0.2. What might be wrong?
Thanks.
At last!
The solution is to use MediaScannerConnection.scanFile(context, new String[] {path}, null, null);, but path must include THE NAME OF THE FILE, not only the path. No extension is necessary.
At least, it worked in my case :) .
Huge thanks to Chris Stratton.
The only solution I have found yet, is install SSHDroid on the device and WinSCP on Win7.

Categories

Resources