I want to ensure a byte array is being converted to a jpg correctly.
I've simplified the problem as follows:
public String saveToFile(String filename, String contents) {
String storageState = Environment.getExternalStorageState();
if(!storageState.equals(Environment.MEDIA_MOUNTED)) {
throw new IllegalStateException("Media must be mounted");
}
File directory = Environment.getExternalStorageDirectory();
File file = new File(directory, filename);
FileWriter fileWriter;
try {
fileWriter = new FileWriter(file, false);
fileWriter.write(contents);
fileWriter.close();
return file.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Test
public void testDummyTest() throws Exception{
String out = saveToFile("preview-test.jpg", "preview-test.jpg");
}
This test passes and the path is something like file:///var/folders/z_/_syx1dpx7v9_pmktgdbx7f_m0000gn/T/android-external-cache8656399524188278404robolectric/ddf1c2ec-c0a8-44ce-90e4-7de2a384c57f/preview-test.jpg
However, I can't find this file my machine (yes, I've searched for it). I suspect this is a temp cache and its being cleared/deleted before I can view it.
Please can you tell me how to locate the "preview-test.jpg" file so I may open it in an image viewer, thus proving the image looks like it should. Thanks.
Note: the problem is not the jpg encoding, its simply getting direct access to the file.
I found a partial solution.
Rather than using the shadow environment to provide a path, I can instead use an absolute path for the machine. Eg root "/" would work.
So the code would look something like...
public String saveToFile(String filename, String contents) throws IOException {
File file = new File("/", filename);
FileWriter fileWriter;
fileWriter = new FileWriter(file, false);
fileWriter.write(contents);
fileWriter.close();
return file.getAbsolutePath();
}
#Test
public void testDummyTest() throws Exception {
String out = saveToFile("preview-test.jpg", "preview-test.jpg");
}
This then leaves a file on the root directory of the machine. :) Hope this helps somebody else out there.
Related
I am using Android Studio with Java.
I have written a method (namely deleteWithExtension) to delete files from device internal memory. This method is adding some test files and tries to get the listof these files.
But the problem is that, the code never goes in the for-loop because of the array theFiles[] returns null. As you can see that, the code begins with sample files adding process so it should not be empty. I can also see those sample files in the Device File Explorer of Android Studio.
public static void CreateFile(Context mContext, String fileName, String textToBeWritten) {
try {
File dosya = new File(mContext.getFilesDir() + fileName);
dosya.createNewFile();
FileWriter fw = new FileWriter(dosya);
BufferedWriter yazici = new BufferedWriter(fw);
yazici.write(textToBeWritten);
yazici.flush();
yazici.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void deleteWithExtension(Context mContext, String extension) {
//First let's add a few sample files with same extension.
CreateFile(mContext,"SampleFile1.smp","anything1");
CreateFile(mContext,"SampleFile2.smp","anything2");
CreateFile(mContext,"SampleFile3.smp","anything3");
CreateFile(mContext,"SampleFile4.smp","anything4");
CreateFile(mContext,"SampleFile5.smp","anything5");
//Now, 5 sample files have been added. Let get them and put in an array.
File dir = mContext.getFilesDir();
final String[] theFiles = dir.list();
for (final String file : theFiles) {
//do something here....
int aa=9;
//The code never goes into here, because array theFiles is always null but 5 sample files was added at first.
}
}
replace the CreateFile() method as follows. I hope I can help you.
public static void CreateFile(Context mContext, String fileName, String textToBeWritten) {
try {
File dosya = new File(mContext.getFilesDir() + File.separator + fileName);
dosya.createNewFile();
FileWriter fw = new FileWriter(dosya);
BufferedWriter yazici = new BufferedWriter(fw);
yazici.write(textToBeWritten);
yazici.flush();
yazici.close();
} catch (Exception e) {
e.printStackTrace();
}
}
My app should save files to a place where, when you connect your phone/tablet to a computer, you can see them through the system file explorer.
This is the way I implemented file writing:
protected String mDir = Environment.DIRECTORY_DOCUMENTS;
protected File mPath = Environment.getExternalStoragePublicDirectory(mDir);
protected void writeLogFile(String filename) {
File f = new File(mPath, filename + ".txt");
f.getParentFile().mkdirs();
try (BufferedWriter bw = new BufferedWriter(new FileWriter(f, false))) {
// Details omitted.
} catch (Exception e) {
e.printStackTrace();
return;
}
makeText("Wrote " + f.getAbsolutePath());
}
This is what I see when I connect my Sony Xperia Z4 tablet to Windows (notice missing documents folder):
This is the directory to which the file is written (using above implementation):
What is wrong with my implementation?
What is wrong with my implementation?
MediaStore has not discovered your newly-created files yet. What you see in Windows — and in many on-device "gallery" apps — is based on what MediaStore has indexed.
Use MediaScannerConnection and its scanFile() method to tell MediaStore about your file, once you have written out your data to disk:
public void scanFile(Context ctxt, File f, String mimeType) {
MediaScannerConnection
.scanFile(ctxt, new String[] {f.getAbsolutePath()},
new String[] {mimeType}, null);
}
or, in Kotlin:
fun scanFile(ctxt: Context, f: File, mimeType: String) {
MediaScannerConnection.scanFile(ctxt, arrayOf(f.getAbsolutePath()), arrayOf(mimeType), null)
}
GUYS
I'm new to android and this is my first post in StackOverflow.English as my second language,I'm not that good at it.I just looked for some answers here before,Now I think it's time for me to get involved in it.
There have been a problem occured when I try to copy the system log which located in /dev/log/* to my SD card.After some search on the answers here,I came across Copy file (image) from CacheDir to SD Card.So I had my code below:
private final String srcLocation = "/dev/log/radio";
private final String desLocation = "/mnt/sdcard/radio";
FileInputStream src;
FileOutputStream dst;
FileChannel mFCsrc;
FileChannel mFCdst;
public boolean copyFile(String sourceLocation, String destLocation) throws IOException {
try {
File sd = Environment.getExternalStorageDirectory();
if(sd.canWrite()){
File source=new File(sourceLocation);
File dest=new File(destLocation);
if(!dest.exists()){
dest.createNewFile();
}
if(source.exists()){
src = new FileInputStream(source);
dst = new FileOutputStream(dest);
mFCsrc = src.getChannel();
mFCdst = dst.getChannel();
mFCsrc.transferTo(0, mFCsrc.size(), mFCdst);
}
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
} finally {
if (mFCsrc != null) {
mFCsrc.close();
}
if (mFCdst != null) {
mFCdst.close();
}
}
}
I do have the file in my SD card which I can see it from my DDMS window,but it's size is 0.So,anyone gets a clue? Thanks in advance.(I try to give you a picture of my DDMS window,but since my reputation is not enough,I cann't use a picture.I'm sorry about that!!)
You should debug. Step trough your code with the debugger and check what is happening.
Random thing that might be happening, but we have no way of knowing for sure: If "source" doesn't exist, you will create dest, but because source.exists() will return false,you don't do anything after that. You'll end up with the current behaviour, a newly created file without contents.
i want to write on external sdcard (path: /mnt/external1/). i can read that path, but when i create a new folder on it pro grammatically it not create. i have already declare read write permission in manifeast.xml.
when i write code f.mkdir(); it return false;
and when i create an outputStream obj for that path and try to write something on that it through an exception Permission denied.
Note: My aim is to write something on external sdcrad which path is /mnt/external1 .
plz give me some solution .
my code is
public int createFolder(String FolderName)
{
File f = new File("/mnt/external1"+FolderName);
if(!f.exists())
{
if(f.mkdirs())
{
files= getFiles(path);
imageadapter.notifyDataSetChanged();
return 1;
}
}
}
public void createFolder(String FolderName)
{
File f = new File(new File("/mnt/external1"), FolderName);
if(!f.exists())
{
f.mkdirs();
}
}
This should work, but it is hardcoded for motorola xoom, tested.
Seems like this has been an issue for Xoom tablets (at least) since 3.2. Reference 18501 or 18559 on the Android bug list. You might have to rely solely on the path that getExternalStorageDirectory() returns for you.
try this way. this is the example not perfect code for your but you can get some idea/help
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)){
String path=Environment.getExternalStorageDirectory()+"myfolder";
boolean exists = (new File(path)).exists();
if(!exists) new File(path).mkdirs();
}
Use following code if it works
public int createFolder(String FolderName)
{
File f = new File(Enviornment.getExternalStorageDirectory(), FolderName);
if(!f.exists())
{
if(f.mkdirs())
{
files= getFiles(path);
imageadapter.notifyDataSetChanged();
return 1;
}
}
}
I have been trying to get the URI path for an asset file.
uri = Uri.fromFile(new File("//assets/mydemo.txt"));
When I check if the file exists I see that file doesn't exist
File f = new File(filepath);
if (f.exists() == true) {
Log.e(TAG, "Valid :" + filepath);
} else {
Log.e(TAG, "InValid :" + filepath);
}
Can some one tell me how I can mention the absolute path for a file existing in the asset folder
There is no "absolute path for a file existing in the asset folder". The content of your project's assets/ folder are packaged in the APK file. Use an AssetManager object to get an InputStream on an asset.
For WebView, you can use the file Uri scheme in much the same way you would use a URL. The syntax for assets is file:///android_asset/... (note: three slashes) where the ellipsis is the path of the file from within the assets/ folder.
The correct url is:
file:///android_asset/RELATIVEPATH
where RELATIVEPATH is the path to your resource relative to the assets folder.
Note the 3 /'s in the scheme. Web view would not load any of my assets without the 3. I tried 2 as (previously) commented by CommonsWare and it wouldn't work. Then I looked at CommonsWare's source on github and noticed the extra forward slash.
This testing though was only done on the 1.6 Android emulator but I doubt its different on a real device or higher version.
EDIT: CommonsWare updated his answer to reflect this tiny change. So I've edited this so it still makes sense with his current answer.
Finally, I found a way to get the path of a file which is present in assets from this answer in Kotlin. Here we are copying the assets file to cache and getting the file path from that cache file.
#Throws(IOException::class)
fun getFileFromAssets(context: Context, fileName: String): File = File(context.cacheDir, fileName)
.also {
if (!it.exists()) {
it.outputStream().use { cache ->
context.assets.open(fileName).use { inputStream ->
inputStream.copyTo(cache)
}
}
}
}
Get the path to the file like:
val filePath = getFileFromAssets(context, "fileName.extension").absolutePath
Please try this code working fine
Uri imageUri = Uri.fromFile(new File("//android_asset/luc.jpeg"));
/* 2) Create a new Intent */
Intent imageEditorIntent = new AdobeImageIntent.Builder(this)
.setData(imageUri)
.build();
Be sure ,your assets folder put in correct position.
Works for WebView but seems to fail on URL.openStream(). So you need to distinguish file:// protocols and handle them via AssetManager as suggested.
Try this out, it works:
InputStream in_s =
getClass().getClassLoader().getResourceAsStream("TopBrands.xml");
If you get a Null Value Exception, try this (with class TopBrandData):
InputStream in_s1 =
TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");
InputStream is = getResources().getAssets().open("terms.txt");
String textfile = convertStreamToString(is);
public static String convertStreamToString(InputStream is)
throws IOException {
Writer writer = new StringWriter();
char[] buffer = new char[2048];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
String text = writer.toString();
return text;
}
try this :
Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat);
I had did it and it worked
Yeah you can't access your drive folder from you android phone or emulator because your computer and android are two different OS.I would go for res folder of android because it has good resources management methods. Until and unless you have very good reason to put you file in assets folder. Instead You can do this
try {
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.yourfile);
byte[] b = new byte[in_s.available()];
in_s.read(b);
String str = new String(b);
} catch (Exception e) {
Log.e(LOG_TAG, "File Reading Error", e);
}
If you are okay with not using assets folder and want to get a URI without storing it in another directory, you can use res/raw directory and create a helper function to get the URI from resID:
internal fun Context.getResourceUri(#AnyRes resourceId: Int): Uri =
Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(packageName)
.path(resourceId.toString())
.build()
Now if you have a mydemo.txt file under res/raw directory you can simply get the URI by calling the above helper method
context.getResourceUri(R.raw.mydemo)
Reference: https://stackoverflow.com/a/57719958
Worked for me Try this code
uri = Uri.fromFile(new File("//assets/testdemo.txt"));
String testfilepath = uri.getPath();
File f = new File(testfilepath);
if (f.exists() == true) {
Toast.makeText(getApplicationContext(),"valid :" + testfilepath, 2000).show();
} else {
Toast.makeText(getApplicationContext(),"invalid :" + testfilepath, 2000).show();
}