How to get URI from an asset File? - android

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();
}

Related

Download file from drive to upload into another drive using Google Drive API in Android Studio

So, In my app I need to get a file from the user's drive and upload it to mine.
I've searched and it seems like the only way to do this is by downloading the file from the user's drive and then uploading it to mine.
I already have all the OAuth2 settled and I'm able to create, get and list files.
But my problem is that according to google's documentation, I'm suposed to download the file to a ByteArrayOutputStream declared as an OutputStream, but when I upload the file, I'm supposed to upload a java.io file
Does anyone knows how I can get the outputstream from the download method and turn it into a file in order to send to the upload method?
This is my code so far:
The code to download the file (I got it from google)
public Task<java.io.File> downloadFile(PostFileHolder postFileHolder) {
return Tasks.call(mExecutor, () -> {
// Retrieve the metadata as a File object.
Log.i("download file", "chegou");
OutputStream outputStream = new ByteArrayOutputStream();
mDriveService.files().export(postFileHolder.getGoogleId(), "application/pdf")
.executeMediaAndDownloadTo(outputStream);
// I need to use the export method because I will have some docs and slides files
return null;
});
}
And this is the code to upload files:
public Task<File> uploadFileWithMetadata(java.io.File javaFile, String mimeType, boolean isSlide, #Nullable final String folderId) {
return Tasks.call(mExecutor, () -> {
Log.i("upload file", "chegou" );
String convertTo;
if(isSlide){
convertTo = TYPE_GOOGLE_SLIDES;
}
else{
convertTo = TYPE_GOOGLE_DOCS;
}
List<String> folder;
if (folderId == null) {
folder = Collections.singletonList("root");
} else {
folder = Collections.singletonList(folderId);
}
File metadata = new File()
.setParents(folder)
.setName(javaFile.getName())
.setMimeType(convertTo);
FileContent mediaContent = new FileContent(convertTo, javaFile);
File uploadedFile = mDriveService.files().create(metadata, mediaContent)
.setFields("id,name,size,createdTime,modifiedTime,starred,thumbnailLink,mimeType")
.execute();
Log.i("File ID: " , uploadedFile.getId());
return uploadedFile;
});
}
Thanks!
You can simply use following minimal code to create a file. And use this file later on to upload.
val outputStream = ByteArrayOutputStream() // Your
val byteData = bos.toByteArray()
val mainFile = File("Path with filename")
//write the bytes in file
val fos = FileOutputStream(mainFile)
fos.write(bitmapdata)
fos.flush()
fos.close()
Since ur outputStream was initialized as ByteArrayOutputStream so you can simply use cast method e.g ((ByteArrayOutputStream) outputStream).toByteArray()
Regarding path, You can save file anywhere in your internal file directory or external storage as temporary file. I would recommend you to go through Data and File Storage Overview and this tutorial for more information.

Where to store files for user in Android?

I have to export files from my application and looking for a solution, where I can save files, to give the user the possibility to open them.
I tried already getFilesDir().getPath() which worked well, until I realized that the folder can't open from a real device (/data/user/0/com.myapplication.example/files) since the /data path is just a storage area for the application.
What are the alternatives?
You should have a look here https://developer.android.com/training/data-storage
I'm not sure what file type you are trying to store however what you have tried stores the file withing the applications directory and not the devices. To combat this I would look under either Media or Documents and other files again in the above link. I would be able to be of further assistance if I knew what file type you are trying to store. Hope this helps you in some way.
This is a function to store a float array to the phone external storage. Pass the file name.extension in the String name. You could modify it to export your file.
public static void save(float[] input_array, String name)
{
final String TAG2 = "->save()";
String string_array = Arrays.toString(input_array);
String fullName = Environment.getExternalStorageDirectory().getPath() + "/SercanFolder/" + name;
String path = Environment.getExternalStorageDirectory().getPath() + "/SercanFolder";
File folder = new File(path);
if(!folder.exists())
{
folder.mkdirs();
}
BufferedWriter buf;
try
{
buf = new BufferedWriter(new FileWriter(fullName));
buf.write(string_array,0,string_array.length());
buf.close();
Log.d(TAG+TAG2, "array saved as document. ");
}
catch (IOException e)
{
Log.e(TAG+TAG2, "problems while saving the file. ");
}
}
The suggestion with getExternalStorage().getPath() (Thanks to blackapps) helped me to save the pdf in a folder, which can be opened in the file manager.

Android - Google Drive SDK - Open file

I am used to opening my files in my apps using the next code:
public void openFile(#NonNull String uri) {
checkNotNull(uri);
File file = new File(uri);
String dataType = null;
if (ContentTypeUtils.isPdf(uri)) dataType = "application/pdf";
else if (ContentTypeUtils.isImage(uri)) dataType = "image/*";
if (file.exists() && dataType != null) {
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(Uri.fromFile(file), dataType);
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(target, "Open file");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "There is a problem when opening the file :(");
}
} else {
Toast.makeText(getContext(), "Invalido", Toast.LENGTH_LONG).show();
}
}
I had always used static files so this was enough, but now I am using the Google Drive SDK for Android. I possess the driveId of the file I want to open but the problem is I cannot find a clean way to open the file contents I obtain by doing this:
Drive.DriveApi.fetchDriveId(mGoogleApiClient, documentFile.getDriveId())
.setResultCallback(driveIdResult -> {
PendingResult<DriveApi.DriveContentsResult> open =
driveIdResult.getDriveId().asDriveFile().open(
mGoogleApiClient,
DriveFile.MODE_READ_ONLY,
null);
open.setResultCallback(result -> {
DriveContents contents = result.getDriveContents();
InputStream inputStream = contents.getInputStream();
// I know I can get the input stream, and use it to write a new file.
});
});
So the only thing that comes to my mind is creating a static route to create a file every time I have to open it, and erasing it every time I have to open a new file.
What I have understood up until now is that the Google Drive API for Android already saves an instance of the file so what I have in mind sounds unnecessary, I would like to know if there is a better way to achieve this. Is there a way I can open the file and do something similar to what I do with the Intent.ACTION_VIEW in a cleaner way?
Thanks in advance.
Well since it seems this will not be answered I will post what I did. All I did was create a temp file where I put my contents to be read. I still don't know if it was the best choice so this question will still be opened for a better answer.
open.setResultCallback(result -> {
DriveContents contents = result.getDriveContents();
InputStream inputStream = contents.getInputStream();
writeTempFile(inputStream);
});
And here the implementation of the `writeTempFile`:
private synchronized File writeTempFile(#NonNull InputStream inputStream) {
checkNotNull(inputStream);
File filePath = new File(mActivity.getFilesDir(), "TempFiles");
if (!filePath.exists()) filePath.mkdirs();
File file = new File(filePath, TEMP_FILE);
try {
OutputStream outputStream = new FileOutputStream(file);
IOUtils.copyLarge(inputStream, outputStream);
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
return file;
}

Where does Robolectic on Android, save files created during test runs?

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.

Android Show image by path

i want to show image in imageview without using id.
i will place all images in raw folder and open
try {
String ss = "res/raw/images/inrax/3150-MCM.jpg";
in = new FileInputStream(ss);
buf = new BufferedInputStream(in);
Bitmap bMap = BitmapFactory.decodeStream(buf);
image.setImageBitmap(bMap);
if (in != null) {
in.close();
}
if (buf != null) {
buf.close();
}
} catch (Exception e) {
Log.e("Error reading file", e.toString());
}
but this is not working i want to access image using its path not by name
read a stream of bytes using openRawResource()
some thing like this should work
InputStream is = context.getResources().openRawResource(R.raw.urfilename);
Check this link
http://developer.android.com/guide/topics/resources/accessing-resources.html#ResourcesFromCode
It clearly says the following
While uncommon, you might need access your original files and directories. If you do, then saving your files in res/ won't work for you, because the only way to read a resource from res/ is with the resource ID
If you want to give a file name like the one mentioned in ur code probably you need to save it on assets folder.
You might be able to use Resources.getIdentifier(name, type, package) with raw files. This'll get the id for you and then you can just continue with setImageResource(id) or whatever.
int id = getResources().getIdentifier("3150-MCM", "raw", getPackageName());
if (id != 0) //if it's zero then its not valid
image.setImageResource(id);
is what you want? It might not like the multiple folders though, but worth a try.
try {
// Get reference to AssetManager
AssetManager mngr = getAssets();
// Create an input stream to read from the asset folder
InputStream ins = mngr.open(imdir);
// Convert the input stream into a bitmap
img = BitmapFactory.decodeStream(ins);
} catch (final IOException e) {
e.printStackTrace();
}
here image directory is path of assets
like
assest -> image -> somefolder -> some.jpg
then path will be
image/somefolder/some.jpg
now no need of resource id for image , you can populate image on runtime using this

Categories

Resources