In my iOS project i kept a binary file and used NSBundle class to access that file.
How do i do that same thing in Android since recently i have started working on Android platform, i wanted to know how do i package and read a binary file in Android app.
I started doing it via native call, created a java wrapper and called a function in cpp file and in that function i am trying to read the binary file.
File *f = fopen("absolute file path on my laptop", "r")
Here f is always null whereas in iOS using NSBunle i am able to access the file in my iOS app
I passed and assetmanager object from java to NDK end.
then called on AAssetManager_fromJava and fetched AAssetManager object on jni layer and used that final object to read the asset.
Put the file at design time in assets directory.
At run time open an InputStream for the file in assets and read() its bytes.
You can all do in Java. Easy.
Related
I wrote a script that allows you to read and write to a json file. As long as I tried the script in unity editor, I didn't have any problems. But when I switched to installing the application on an Android device, I can't find my json file.
The json file is called "playerData.json" and has been placed in a folder called "playerData.json".
This is the code for the path of the json file (working on unity but not working on android)
path = Application.streamingAssetsPath + "/playerData.json";
I tried using this string of code to get the code to work on android as well, but there is no way to get it to work.
path = System.IO.Path.Combine(Application.streamingAssetsPath, "/playerData.json");
I only wrote the line concerning the path as my android device cannot find the JSON file. Thanks everyone for the help!
Application.streamingAssetsPath does not work on Android and WebGL
It is not possible to access the StreamingAssets folder on WebGL and Android platforms. No file access is available on WebGL. Android uses a compressed .apk file. These platforms return a URL. Use the UnityWebRequest class to access the Assets.
There is a workaround though as mentioned using UnityWebRequest, can find an example in this Unity Answer
I'm developing an android application that uses OpenCV C++ dll(.so file) in Unity.
The C++ dll accesses a cascade file to use OpenCV functions.
*C++ DLL side code
cv::String face_cascade_name = "haarcascade_frontalface_alt.xml";
if (!face_cascade.load(face_cascade_name)) {
printf("--(!)Error loading face cascade, please change face_cascade_name in source code.\n");
return -1;
};
However If I build an android application in Unity and install the app on Android device, it fails to load the xml file.
How can I access the cascade xml in C++ DLL in Android apk?
*If I put the xml to assets/StreamingAssets in Unity, the xml file exists in myapp.apk/assets folder.
Android is a special case since the StreamingAssets folder is compressed and unusable by the OpenCV file reader. You have to 1) copy the file from your StreamingAssets folder to the persistent data path (there's documentation on how to copy and write files in the unity manual), 2) fetch the name of that file using Application.persistantDataPath, like:
string cascadeFileName = (Application.persistentDataPath + "/" + fileName);
I can't run my python program on my android device using qpython3.
The first step in he program is to create a text file to save data to it. But I get an I/O error (file system read only)
This is the function used to create / or be sure that the file exists easily.
def filecreate(file): # creates the text file
f = open(file, 'a')
print('file created successfully\n')
print()
f.close()
How to overcome this problem in android ?
QPython by default runs your programs from the root directory which is not writable by non-root users. If you check the ftp utility (under About menu) you will find the name of the directory that is writable by QPython. On my HTC it is:
/storage/emulated/0/com.hipipal.qpyplus
So you need to do something along the lines of:
RootPath='/storage/emulated/0/com.hipipal.qpyplus'
...
import os
f = open(file, os.path.join(RootPath,'a'))
...
Example of a similar problem with QPython and SQLite3
Just create the file with QPython before use in your script.
You can create an txt file with QPython.
In My case I create the file whith name "pontoText.txt"
Inside folder "MyPythonScripts" (Im create that folder to put my python files)
so the file is in the same folder of the script and are created in QPython
Now an example code im make ton test:
import time
import os
a = input("1 to save date on file or 2 too see records on file. ")
folder= '/storage/emulated/0/MyPythonScripts'
if(a == "1"):
pontoTxt=open(os.path.join(folder,'pontoText.txt'),'w')
pontoTxt.write(time.strftime("%I %M %p on %A, %B %e, %Y"))
if(a == "2"):
pontoTxt=open(os.path.join(folder,'pontoText.txt'),'r')
exibe = pontoTxt.read()
print(exibe)
Your app may not have required permission to manage that file. Check your manifest, specify Android version and file path. Check documentation: http://developer.android.com/training/basics/data-storage/files.html
You have to actually find the file path, as it doesn't infer the directory that the file is in as the destination directory, unlike in Python on the PC.
Use what they're changed.
The file you have is inside /accounts/mastercard root and the file you're inside is /accounts/main.py you only need to use is this
/mastercard/xxxxx like my code
from django.shortcuts import render
from django.http import HttpResponse
from . import models
# Create your views here.
def index(request):
return render(request,"mastercard/Templates/mastercard/Base.html")
def about(request):
return render(request,"mastercard/Templates/mastercard/index.html")
This code works in the simulator but not on my Android device:
local path = system.pathForFile("chinese_rules.db")
print("PATH:: " .. tostring( path ) )
When I run this code on my Galaxy S4 path returns nil.
My first thought was that it was some typo (case sensitivity) but I can't find any typo:
http://i59.tinypic.com/wlpu14.png
I can't find any reason why it should receive nil. This causes a problem as I can't load my database.
I have also tried this with the same result:
local path = system.pathForFile("chinese_rules.db", system.ResourceDirectory)
I have been able to load a path and load databases like this before.
Corona Build: 2013.2100 (2013.12.7)
Further reading the documentation I don't see that .db is a restricted file type:
Corona allows direct loading of images and audio files using the
appropriate APIs, but it has limited access to resource files on
Android using the file I/O APIs. Specifically, the following types can
not be read from the resources directory: .html, .htm., .3gp, .m4v,
.mp4,.png, .jpg, and .ttf.
http://docs.coronalabs.com/api/library/system/pathForFile.html
I found out the reason for the problem:
We are two that are working on this project and he had setup to use expansion files so two files was created (the main APK and the OBB expansion file) which I didn't notice and I only loaded the main APK file and I guess the database is in the OBB file. After setting not to use an expansion file the app works.
usesExpansionFile = false
Need to use a shared lib for android from 3rd party, the lib's soname and file name are same, in format libxx.so.1.2.3, which is common on linux. I rename the lib file to libxx.so, and link libxx.so in libmyjni.so using ndk-build. In my java code, before calling the functions in libmyjni.so, I load them like this:
System.load("/data/local/tmp/libxx.so.1.2.3");
System.loadLibrary("myjni");
I have to manually copy libxx.so.1.2.3 to /data/local/tmp/. It works well in this way, after above loading, I can call functions in libmyjni.so.
In code "System.loadLibrary("myjni");", system always trying to get libxx.so.1.2.3 from somewhere. I want to know, in the real world, how could I copy libxx.so.1.2.3 to a specific location on android device during installation? so that I can System.load() it.
Or android has official way to install self made lib to /system/lib/?
If libxx.so.1.2.3 is in format libxx.so then I can use System.loadLibrary("xx") to load it.
Here is finally what I did, keep the libxx.so.1.2.3 untouched and do all stuff in Java:
Put libxx.so.1.2.3 in android assets.
In MainApp.OnCreate(), copy the file to private file folder and load it from there:
AssetManager am = applicationContext.getAssets();
in = am.open(OPENSSL_SO_LIB_NAME); // source instream
File privateStorageDir = applicationContext.getFilesDir();
String libPath = privateStorageDir.getAbsolutePath(); // copy the lib to here ...
System.load(libPath + "/" + SO_LIB_NAME);