Quick reference on what I have read
http://thedevelopersinfo.com/2009/11/17/using-assets-in-android/
http://www.wiseandroid.com/post/2010/06/14/Android-Beginners-Intro-to-Resources-and-Assets.aspx
There are more but as a newb can only post 2.
In my app there is a button the will a reboot into the bootloader if the user decides to do so on rooted devices. I have a reboot binary called "reboot" that will allow the commmand to run and it is in /assets/. Using the methods above I can not seem to get "reboot" to move or even create the directory "files" in /data/data/ of my apk. My question is, is there a better guide to school me in the subject or are these the best and I am just to thick headed to understand it. Or if you have some other sample codes I can read through and try and understand would be perfect. Thank you.
Added sample of what I am doing
$ public static String moveReboot = "/data/data/com.DPE.MuchSuck/Files";
public static String reboot = "file:///android_asset/reboot";
public static Context myContext;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
moveFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
$ public void moveFile() throws IOException {
AssetManager assetManager = getAssets();
InputStream myInput = assetManager.open(reboot);
String outFileName = moveReboot + reboot;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte [1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
Upon running the apk nothing shows up in the "Files" nor does "Files even show up.
doug,
it looks like your "outFileName" won't contain a good filename.
Try using getExternalFilesDir() to obtain a path to SDRAM.
see: http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir%28java.lang.String%29
EDIT...
doug, this is my implementation
private void copyAssetToSDRAM(String strFilename)
{
try
{
//complete path to target file
File fileTarget = new File(Environment.getExternalStorageDirectory(), strFilename);
//data source stream
AssetManager assetManager = ApplicationContext.getContext().getAssets();
InputStream istr = assetManager.open(strFilename);
//data destination stream
//NOTE: at this point you'll get an exception if you don't have permission to access SDRAM ! (see manifest)
OutputStream ostr = new FileOutputStream(fileTarget);
byte[] buffer = new byte[1024];
int length;
while ((length = istr.read(buffer))>0)
{
ostr.write(buffer, 0, length);
}
ostr.flush();
ostr.close();
istr.close();
}
catch(Exception e)
{
Toast.makeText(ApplicationContext.getContext(), "File-Copy Error: "+strFilename, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
to use it, do this:
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
{
copyAssetToSDRAM("myfile.png");
}
else
{
Toast.makeText(ApplicationContext.getContext(), "Unable to copy images. NO SDRAM", Toast.LENGTH_LONG).show();
}
Related
I am developing an app where time-cost of an algorithm matters a lot.
In the algorithm, I need to get path string to a file in assets folder. And I got answer from this question.
The file is a configuration file, which is ~400 bytes in size. The library I used requires path, but not some Java string.
My code is like:
public static File getCacheFile(String path, Context context) throws IOException {
File cacheFile = new File(context.getCacheDir(), path);
try {
InputStream inputStream = context.getAssets().open(path);
try {
FileOutputStream outputStream = new FileOutputStream(cacheFile);
try {
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
} finally {
outputStream.close();
}
} finally {
inputStream.close();
}
} catch (IOException e) {
throw new IOException("Could not open file", e);
}
return cacheFile;
}
If I run the algorithm for the first time since I start my app, it will cost ~900ms.
If I run the algorithm again without restarting the app, it will cost ~400ms.
So I guess the time difference is that this function attempts to load the file into cache and read path from the cache? Maybe the file is already in the cache and that is why it is faster.
Is there any way to make it faster? E.g. preload this file to cache in onCreate(), maybe?
Edit: I tried to preload this file in onCreate() and it does not work.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
getCacheFile("a.properties", getApplicationContext());
} catch (IOException e) {
e.printStackTrace();
}
}
Edit2: Not sure whether it matters, but my algorithm is posted here.
Is there a way to copy sqlite database from external storage to assets at run time and then use it ? or is there a way to copy the ready sqlite from external storage to below path at run time and then read it in app? context.getDatabasepath. I have problem with the copying process, please help me because I got this error :
can't open file
My question may look like a duplicate but I couldn't find the answer.
public void copyDataBase() throws IOException
{
try
{
String inputDB = Environment.getExternalStorageDirectory().getPath() + "/test.sqlite" ;
File input = new File(inputDB);
InputStream myInput = new FileInputStream(input);
String outputFileName = databasePath + DATABASE_NAME ;
OutputStream myoutput = new FileOutputStream(outputFileName) ;
byte[] buffer = new byte[1024];
int length;
while((length = myInput.read(buffer))>0)
{
myoutput.write(buffer,0,length);
}
myoutput.flush();
myoutput.close();
myInput.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
I think the file should be opened first then we give it to the input stream because error was like : can't open the file. Please help me.
I've been looking at this site for the past 3 or so hours. How to copy files from 'assets' folder to sdcard?
This is the best I could come up with because I'm only trying to copy one file at a time.
InputStream in = null;
OutputStream out = null;
public void copyAssets() {
try {
in = getAssets().open("aabbccdd.mp3");
File outFile = new File(root.getAbsolutePath() + "/testf0lder");
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: ", e);
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
I've figured out how to create a file and save a text file. http://eagle.phys.utk.edu/guidry/android/writeSD.html
I would rather save an mp3 file to the sdcard rather than a text file.
When I use this code I provided, I get a text document that same size as the aabbccdd.mp3 file. It does not create a folder and save an .mp3 file. It saves a text document in the root folder. When you open it, I see a whole bunch of chinese letters, but at the top in English I can see the words WireTap. WireTap Pro was the program I used to record the sound so I know the .mp3 is passing through. It's just not creating a folder and then saving a file like the above .edu example.
What should I do?
I think you should do something like that -[Note: this i used for some other formats not mp3 but its works on my app for multiple format so i hope it will work for u too.]
InputStream in = this.getAssets().open("tmp.mp3"); //give path as per ur app
byte[] data = getByteData(in);
Make sure u have the folder already exists on path, if folder is not there it will not save content correctly.
byteArrayToFile(data , "testfolder/tmp.mp3"); //as per ur sdcard path, modify it.
Now the methods ::
1) getByteData from inputstream -
private byte[] getByteData(InputStream is)
{
byte[] buffer= new byte[1024]; /* or some other number */
int numRead;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try{
while((numRead = is.read(buffer)) > 0) {
bytes.write(buffer, 0, numRead);
}
return bytes.toByteArray();
}
catch(Exception e)
{ e.printStackTrace(); }
return new byte[0];
}
2) byteArrayToFile
public void byteArrayToFile(byte[] byteArray, String outFilePath){
FileOutputStream fos;
try {
fos = new FileOutputStream(outFilePath);
fos.write(byteArray);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I want to send the database file of my app via email. This makes my it easier to help in a error case. For that I need to retrieve the installation folder of my app. How can I achieve this so that i can send my db which is place here APP-FOLDER\databases\mydb.db
Thanks
Hope, you are asking about the strategy or where to start to do so.
There are several approaches you can follow,
1) Save your db file to the sdcard then it will be available to you for your mailing function. You can achieve this by using SQLiteDatabase.openOrCreateDatabase(String, SQLiteDatabase.CursorFactory) and simply pass "/sdcard/yrdatabase.db" as the first parameter .
2) If you aren't saving it to the sdcard, then simply move your db file to the sdcard. You can achieve this by using following code. (i.e. bind the below function to your button or anyhow call it from your app)
public void copyDBToSDCard() {
try {
InputStream myInput = new FileInputStream("/data/data/com.yrproject/databases/"+DATABASE_NAME);
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/"+DATABASE_NAME);
if (!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
Log.i("TAG","File creation failed for " + file);
}
}
OutputStream myOutput = new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
Log.i("TAG","copied");
} catch (Exception e) {
Log.i("TAG","exception="+e);
}
}
Once you are done with the accessing db file, you can use mail functions to use it further.
I am trying to create a folder and several subdirectory within it on the SD Card... I then want to transfer files that I have stored in /res/raw to that folder... I addition, I want this to only happen once, the first time the program is ever run. I realize that this is ridiculously open-ended, and that I am asking a lot... but any help would be greatly appreciated.
This will copy all files in the "clipart" subfolder of the .apk assets folder to the "clipart" subfolder of your app's folder on the SD card:
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
String basepath = extStorageDirectory + "/name of your app folder on the SD card";
//...
// in onCreate
File clipartdir = new File(basepath + "/clipart/");
if (!clipartdir.exists()) {
clipartdir.mkdirs();
copyClipart();
}
private void copyClipart() {
AssetManager assetManager = getResources().getAssets();
String[] files = null;
try {
files = assetManager.list("clipart");
} catch (Exception e) {
Log.e("read clipart ERROR", e.toString());
e.printStackTrace();
}
for(int i=0; i<files.length; i++) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open("clipart/" + files[i]);
out = new FileOutputStream(basepath + "/clipart/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("copy clipart ERROR", e.toString());
e.printStackTrace();
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
I experienced a similar problem when using mkdirs(), however because running the command:
mkdir one/two
fails on Linux, then the method http://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#mkdirs() subsequently fails too. I guess this means there is no way to use mkdirs on Android? My (probably rather hacky) work-around was to create each necessary directory separately:
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
new File(extStorageDirectory + "/one/").mkdirs();
new File(extStorageDirectory + "/one/two/).mkdirs();