I am currently trying to figure out a way to write a media file to internal/external storage (primary storage). The file to be saved could be any size from a few MBs to 50MBs. I have logic that works on my Droid X 2.3.3 Razr 2.3.5 (I believe) but does not work on my Galaxy Nexus (has no removable storage but a built in 16Gig card with v4.0.2). I have looked around and haven't found any code/samples that work with v4.0. Maybe I am approaching this all wrong since it doesn't have an actual sd card? maybe it is something new in v4.0? Currently when I run my application on the Galaxy Nexus I get this: System.err(19520): java.io.FileNotFoundException:
UPDATED
InputStream inputStream = urlConnection.getInputStream();
File PATH = Environment.getExternalStorageDirectory();
File FILE = new File(Environment.getExternalStorageDirectory()+ "/" + FILENAME);
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// buffer int bufferSize = 1024; int bufferLength = 0; byte[] buffer = new byte[bufferSize];
while ((bufferLength = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, bufferLength);
}
byte[] temp = byteBuffer.toByteArray();
FileOutputStream fos = new FileOutputStream(FILE);
fos.write(temp);
fos.close();
Are you putting this file in a specific directory on your sdcard?external storage?
I assume your permissions in your manifest are good because the 'permission denied is not raised' so maybe if you put the file in a specific folder, which is not created you should call the mkdirs() function on your file!
First, don't convert it to a string, just use getExternalStorageDirectory() as a File:
File sd = Environment.getExternalStorageDirectory();
File file = new File(sd, FILENAME);
I don't know if that will correct it or not, but it wouldn't hurt to try that. And you do not need to call file.createNewFile() before writing to the file with a FileOutputStream. The docs about FileOutputStream say:
An output stream that writes bytes to a file. If the output file
exists, it can be replaced or appended to. If it does not exist, a new
file will be created.
And which line of code is the FileNotFoundException happening on?
Related
Hi i have an xml file that contains the data I'm going to use to populate my app. i need to be able to read/write this file which i believe is not possible as it becomes a static resource in the assets folder. Is there a way on launch to copy this file to a location where i can use it in this way? or what is the best way to read and write a xml from a local resource?
Try this..
Yes you can not write file in the assets folder at run time. For info link1, link2
You can use below code copy from assets to sdcard then you can write it.
AssetManager assetManager = this.getAssets();
InputStream in = assetManager.open("yourxmlfile.xml");
File SDCardRoot = new File(Environment.getExternalStorageDirectory().toString()+"/Folder");
SDCardRoot.mkdirs();
File file = new File(SDCardRoot,"hello.xml");
FileOutputStream fileOutput = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bufferLength = 0;
while((bufferLength = in.read(buffer)) > 0)
{
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
And also don't forget to add read/write permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
I'm writing a process that downloads/ copies a file attached to Gmail on to the SD card that my application can then read.
When a user clicks on the attachment my activity is fired and I use the following code to save to local storage;
InputStream in = getContentResolver().openInputStream( intent.getData() );
String ext = intent.getType().equals("text/xml") ? ".xml" : ".gpkg";
localFile = new File( TILE_DIRECTORY, "tmp/"+intent.getDataString().hashCode()+ext);
// If we haven't already cached the file, go get it..
if (!localFile.exists()) {
localFile.getParentFile().mkdirs();
FileIO.streamCopy(in, new BufferedOutputStream(new FileOutputStream(localFile)) );
}
The FileIO.streamCopy is simply;
public static void streamCopy(InputStream in, OutputStream out) throws IOException{
byte[] b = new byte[BUFFER];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
out.close();
in.close();
}
This all works fine on a small file, but with a 6Mb attachment only 12Kb is ever getting written. I'm not even getting an error, the process just runs through very quickly and i'm left with a corrupt file.
This process is run in its own thread and is part of a larger app with a lot of fileIO, so there is no issue with permissions/ directories etc.
Is there something different I should be doing with the stream?
Incidentally, intent.getData() is
content://gmail-ls/mexxx#gmail.com/messages/6847/attachments/0.1/BEST/false
and intent.getType() is
application/octet-stream
Thanks
All work's fine with this code
InputStream in = new BufferedInputStream(
getContentResolver().openInputStream(intent.getData()) );
File dir = getExternalCacheDir();
File file = new File(dir, Utils.md5(uri.getPath()));
OutputStream out = new BufferedOutputStream( new FileOutputStream(file) );
streamCopy(in, out);
I am using PDF Viewer Library to view PDF inside an Android app. I've browsed through a lot of tutorials, one of which is Dipak's tutorial. I want to access a PDF file stored in my assets folder instead of accessing the external storage. My problem is, I can't get the "path" right. It always return file not found.
I've tried the following, still yields the same result:
this.getAssets()
file:///android_assets/file_name.pdf
file:///android_asset/file_name.pdf
You can't get path from asset, have to right in sd or internal memory to get the path.
For SD Card
First Take Permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
then write it in card
File f = new File(Environment.getExternalStorageDirectory() + "file.pdf");
if (!f.exists()) try {
InputStream is = getAssets().open("file.pdf");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
FileOutputStream fos = new FileOutputStream(f);
fos.write(buffer);
fos.close();
} catch (Exception e) { throw new RuntimeException(e); }
Staring path = f.getPath();
I'm reading files from a ZIP file that's located in my Android assets folder using ZipInputStream: it works, but it's really slow, as it has to read it sequentially using getNextEntry(), and there are quite a lot of files.
If I copy the ZIP file onto the SD card, reading is really fast when using ZipFile.getEntry, but I didn't find a way to use ZipFile with the asset file!
Is there any way to access the ZIP in the asset folder in a speedy way? Or do I really have to copy the ZIP to the SD card?
(BTW, in case anybody wonders why I'm doing this: the app is larger than 50 MB, so in order to get it in the Play Store I have to use Expansion APKs; however, as this app should also be put into the Amazon App Store, I have to use another version for this, as Amazon doesn't support Expansion APKs, naturally... I thought that accessing a ZIP file at two different locations would be an easy way to handle this, but alas...)
This works for me:
private void loadzip(String folder, InputStream inputStream) throws IOException
{
ZipInputStream zipIs = new ZipInputStream(inputStream);
ZipEntry ze = null;
while ((ze = zipIs.getNextEntry()) != null) {
FileOutputStream fout = new FileOutputStream(folder +"/"+ ze.getName());
byte[] buffer = new byte[1024];
int length = 0;
while ((length = zipIs.read(buffer))>0) {
fout.write(buffer, 0, length);
}
zipIs.closeEntry();
fout.close();
}
zipIs.close();
}
You can store the uncompressed files directly in assets (i.e. unpack the zip into assets/ folder). This way, you can access the files directly and they will be compressed anyway when you build the APK.
You can create a ZipInputStream in the following way :
ZipInputStream zipIs = new ZipInputStream(context.getResources().openRawResource(your.package.com.R.raw.filename));
ZipEntry ze = null;
while ((ze = zipIs.getNextEntry()) != null) {
FileOutputStream fout = new FileOutputStream(FOLDER_NAME +"/"+ ze.getName());
byte[] buffer = new byte[1024];
int length = 0;
while ((length = zipIs.read(buffer))>0) {
fout.write(buffer, 0, length);
}
zipIs .closeEntry();
fout.close();
}
zipIs .close();
What i want to do: delete an image file from the private internal storage in my app. I save images in internal storage so they are deleted on app uninstall.
I have successfully created and saved:
String imageName = System.currentTimeMillis() + ".jpeg";
FileOutputStream fos = openFileOutput(imageName, Context.MODE_PRIVATE);
bitmap.compress(Bitmap.CompressFormat.JPEG, 35, fos);
an image that i receive through
bitmap = BitmapFactory.decodeStream(inputStream);
I am able to retrieve the image later for display:
FileInputStream fis = openFileInput(imageName);
ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
DataOutputStream outWriter = new DataOutputStream(bufStream);
int ch;
while((ch = fis.read()) != -1)
outWriter.write(ch);
outWriter.close();
byte[] data = bufStream.toByteArray();
bufStream.close();
fis.close();
imageBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
I now want to delete this file permanently. I have tried creating a new file and deleting it, but the file is not found:
File file = new File(imageName);
file.delete();
I have read on the android developer website that i must open private internal files using the openFileInput(...) method which returns an InputStream allowing me to read the contents, which i don't really care about - i just want to delete it.
can anyone point me in the right direction for deleting a file which is stored in internal storage?
Erg, I found the answer myself. Simple answer too :(
All you have to do is call the deleteFile(imageName) method.
if(activity.deleteFile(imageName))
Log.i(TAG, "Image deleted.");
Done!