How to get results like Application.dataPath in Unity Split Binary Build - android

I am using Unity 5.6.
Until now, the Android used a way to inspect the classes.dex file inside the APK to prevent app tampering
For a typical build, I had no problem importing the classes.dex file.
However, using the 'Split Binary Build' option to use the .obb file, I could not import the classes.dex file properly.
I used to import classes.dex file in the following way
string urlScheme = #"jar:file://";
string apkPath = Application.dataPath;
string separator = #"!/";
string entry = #"classes.dex";
string url = urlScheme + apkPath + separator + entry;
If you use the Split Binay Option in Unity, the path to Application.dataPath will be 'android / data / obb /.../ myobb.obb'
s there a way to get the same result as the existing Application.dataPath using the Split Binary Build option?

I solved it.
It was impossible to solve within Unity.
You can get the same results if you use the values ​​imported from Java in Unity.
PackageManager m = getPackageManager();
String s = getPackageName();
PackageInfo p = m.getPackageInfo(s, 0);
s = p.applicationInfo.sourceDir;
Reference : Get Application Directory

Related

File hierarchy with Android native AAssetManager

Issue
I wonder how to make file hierarchy of assets folder in Android from native code. I'm using AAssetManager_openDir but AAssetDir_getNextFileName doesn't return any directory names so basically I have no way to dive deeper into hierarchy because I can't obtain names of subfolders. Is there any way to resolve this issue with AAssetManager or should I implement this in Java?
Example
Assets looks like
a/
file1
file2
b/
file3
c/
file4
C++ code
AAssetDir* assetDir = AAssetManager_openDir(env, "");
// filename is NULL since there is only folders at the root folder
const char* filename = AAssetDir_getNextFileName(assetDir);
AAssetDir_close(assetDir);
AAssetDir* assetDir = AAssetManager_openDir(env, "a");
// filename is "file1"
const char* filename = AAssetDir_getNextFileName(assetDir);
// filename is "file2"
filename = AAssetDir_getNextFileName(assetDir);
AAssetDir_close(assetDir);
EDIT:
I found out that AAssetDir_getNextFileName implementation literally filters directories from output.
Link to source code
You can achieve your goal in three steps, each requires some programming. The bottom line is, your assets all live in the APK file, and your app can find and read the APK file, and its format is a ZIP archive.
Find your APK file name.
Open this file for read as zip archive.
Iterate the zip contents for assets/<whatever>.
For 1), you can use Java or if you must stay in c++, filter /proc/self/fd. You may find some system APK files (framework), but your APK will be the only one that is not system.
For 2), see use zlib to list directory structure of apk file in android. Note that zlib is part of public NDK libraries.

image file path in DCIM is returned as false

I see the image file in DDMS file explorer as /mnt/shell/emulated/0/DCIM/myPicsFolder/, if I write
final String uploadFilePath = "/mnt/shell/emulated/0/DCIM/myPicsFolder/";
final String uploadFileName = "mypic.jpg";
String sourceFileUri = uploadFilePath + uploadFileName;
File sourceFile = new File(sourceFileUri);
if (sourceFile.isFile()) {/*Upload Image*/}
but the if statemente returns false :-/ , what's wrong? I'm testing code in Samsung Core 2 with Android 4.4. I've checked and rechecked if the path is correctly written and it's ok.
what's wrong?
Root paths in adb shell are not the same as root paths for your app. Never hardcode root paths in your app. Always use methods on Environment or Context to get at root paths.
In this case, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) will give you a File pointing to the DCIM directory that you are trying to work with. So, use something like:
File dcim=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File sourceFile=new File(new File(dcim, "myPicsFolder"), "mypic.jpg");

Python - String appending Issue

I'm working on a python script which takes the output from a previous terminal window command and inputs again. Here is the code
pathCmd = './adb shell pm path com.example.deliveryupdater'
pathData = os.popen(pathCmd,"r")
for line in pathData:
path = line
print line
if line.startswith("package:"):
apkPath = line[8:]
print apkPath
pullCmd = './adb pull ' + apkPath
pullData = os.popen(pullCmd,"r")
The output is as follows:
/data/app/com.example.deliveryupdater-1.apk
' does not exist/data/app/com.example.deliveryupdater-1.apk
It says the path doesn't exist.
When I hardcoded the path as
pullCmd = './adb pull /data/app/com.example.deliveryupdater-1.apk'
pullData = os.popen(pullCmd,"r")
The .apk data gets pulled.
3886 KB/s (2565508 bytes in 0.644s)
Is there a way I can pass as the string as a variable? Am I doing anything wrong here?
Please help
The error message is telling you what's wrong: that path, /data/app/com.example.deliveryupdater-1.apk(newline), does not exist. Probably there is not a filename ending with a newline in the directory. I assume you are iterating over lines from a file or something of that sort, which would explain why you have the newline. Why not just slice [8:-1] instead of [8:], or perhaps, just .rstrip() on the line (this will work even if the line doesn't have a newline, as the last line in the file might not)?
if line.startswith("package:"):
apkPath = line[8:].rstrip()
print apkPath
pullCmd = './adb pull ' + apkPath
pullData = os.popen(pullCmd,"r")

Android: How to get installer file name programmatically?

it is possible to get installer file name which is stored on /sdcard/
download/ ? I want to get from app, apk file name which installed it.
There is a easy way to do it especially with non-market app?
The better way is definitely to include the version string in the manifest. This is really the only reliable (and professional) method. Android doesn't store the name of the file containing the APK anywhere, so there isn't a way that you can get it.
Theoretically you could probably build something using a FileObserver, that watched file creation in certain directories and every time a file was created with the extension .apk you could open the file, extract the manifest, find the package name of the APK and then store this along with the filename in some persistent storage. Then, when you need get the version information, you can look in the persisten storage to get the file name matching the package name you need.
Of course, this would only work if your app was installed on the device before the other APK files were downloaded/installed. This wouldn't work to find out the filename of your own application.
Hmm, I am not sure what you mean by sdcard or download folder, but you could get apk path in system /data directory:
command line:
$ adb shell pm list packages | grep mk.trelloapp
package:mk.trelloapp
$ adb shell pm path mk.trelloapp
package:/data/app/mk.trelloapp-1/base.apk
or from you android application code: (simply run process)
Process exec = Runtime.getRuntime().exec("pm path mk.trelloapp");
exec.waitFor();
InputStream inputStream = exec.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line = null;
while( ( line = br.readLine()) != null ) {
builder.append(line);
}
String commandOutput = builder.toString();
Code above should simply give you String containing "package:/data/app/mk.trelloapp-1/base.apk"
When you acquire path in /data directory, you might try to search for same (similar) file in other directories (assuming it was not deleted), since android package is copied to /data directory while instalation.

Reading android MANIFEST.MF file

Is there a way to read META-INF\MANIFEST.MF file of the currently running application using Android API?
I want to read SHA1 for classes.dex file and use it as an encrpytion key to one of my assets.
I cannot use the signature for .apk file because everytime I create a new apk I need to re-encrpyte my asset and put in to apk file which requires re-signing the .apk and it becomes a chicken and egg problem.
I have found a way to do it. I opne the .apk file as a JarFile and then I can access individual files inside .apk. I believe this will only work for the .apk file that is running this code.
Here it is:
// Get Package Name
String packageName = ctx.getPackageName();
// Get classes.dex file signature
ApplicationInfo ai = ctx.getApplicationInfo();
String source = ai.sourceDir;
JarFile jar = new JarFile(source);
Manifest mf = jar.getManifest();
Map<String, Attributes> map = mf.getEntries();
Attributes a = map.get("classes.dex");
String sha1 = (String)a.getValue("SHA1-Digest");
Use following way to detect External Jar/SDK MANIFEST.MF Info. We could use this info for detecting Jar version etc. Use http://docs.oracle.com/javase/6/docs/api/java/util/jar/Manifest.html
public void getSDKInfo() {
Package package = Manifest.class.getPackage();
String specTitle = package.getSpecificationTitle();
String vendor = package.getSpecificationVendor();
String virsion = package.getSpecificationVersion();
}

Categories

Resources