I have an android app where the user selects a file which creates a URI.
The URI is then used to read the file into a buffer.
I can get the URI-string by doing uri.toString();
The URI-string looks like:
content://com.android.providers.downloads.documents/document/msf%3A12858
To make things quicker, for development purposes, I want to hardcode the URI-string and use it in reverse order to generate the URI.
Is this possible?
EDIT1:
Here is the code to get the data_uri for the selected file:
// at this point the user has the uri (after clicking on the button and selecting file)
Uri uri = intent.getData();
InputStream stream = context.getContentResolver().openInputStream(uri);
byte[] byteArray = JasonHelper.readBytes(stream);
String encoded = Base64.encodeToString(byteArray, Base64.NO_WRAP);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("data:image/jpeg;base64,");
stringBuilder.append(encoded);
String data_uri = stringBuilder.toString();
I can get the data_uri after I select a file.
EDIT2:
The problem is that I want to start with hardcoded uri (for development purposes).
I run the program once and get the value of the content uri string.
I then hardcode the uriStr and set uri1 from it:
String uriStr = "content://com.android.providers.downloads.documents/document/msf%3A13819";
Uri uri1 = Uri.parse(uriStr);
I restart the program but the value of uri1 is different from the value of the uri from the original run.
For example: the values of the fields authority, fragment, path are null where before they had some values (see snapshot).
According to here Uri Access Lifetime is only for the duration of the app (and even shorter).
In my case, the origin is a file uri and I assume that the file does not move.
Can I hard-code anything such that the file can be opened after the program restarts without having to select the file again?
I got nothing on whatever you said, but you should probably be using Uri.parse(...)
Something like Uri.parse(myURL)
From here
I now understand that content uri cannot be used when the app restarts.
But if the content is saved to the file system, e.g. to the internal storage of the app, then assuming the read permissions are ok, the file can be openned programatically by providing the file path.
Related
Is there a way in Firebase Storage to generate a download url pointing to nothing, in order to upload a file to that url later? something like that (in Kotlin):
fun generateItemPhotoUrl(id: String) =
storageRef.child("$Id/${generateUniqueName()}.${COMPRESS_FORMAT.name}").downloadUrl
This code returns a failed task...
I want this so my upload process can look like so:
// Case: old photo is null but new one is not - upload new photo to a new uri
generateItemPhotoUrl(itemId).continueWithTask { generateTask ->
if (generateTask.isSuccessful) {
val destUrl = generateTask.result.toString()
// Uploading may take time, so first update document to hold a uri, so consecutive
// calls will result in updating instead of uploading a new file
updateItemPhoto(itemId, destUrl).continueWithTask { updateTask ->
if (updateTask.isSuccessful)
uploadFileToDest(destUrl, newImage).continueWithTask { uploadTask ->
if (!uploadTask.isSuccessful) updateItemPhoto(itemId, null)
}
}
}
}
As explained in code, I need this to prevent the case of updating the item's photo twice in a row too fast for the first one to finish it's upload. I end up with 2 files - one of them is not referenced from anywhere. If I could do something like this, the second upload will go to my "update" case (instead of the "new photo" case presented here) - where the file will be switched correctly.
Is there a way in Firebase Storage to generate a download URL pointing to nothing, in order to upload a file to that URL later?
No, this is not possible. You cannot generate a Storage URL in advance and upload the file sometime later. You get the download URL only when the file is successfully uploaded on the Firebase servers. This is because the URL that comes from the UploadTask contains a token that is generated on the server, and it's apart of the URL. To get the entire download URL of an uploaded file, please see my answer from the following post:
How to get the download url from Firebase Storage?
The process of uploading the file is asynchronous, meaning that any code that needs that URL, needs to be inside the" onSuccess()" method, or be called from there. So there is no need to upload the file twice.
I am trying to make a simple android app that uses OpenAPLR
http://doc.openalpr.com/cloud_api.html
So I copied the code under the Java section on how to make a REST api request and put it all into onClick method of a button and took a picture of a license plate and saved it as license_plate.jpg in the location
app/res/drawable/license_plate.jpg
But whenever I run the application I always get an error pointing to these lines
Path path = Paths.get("drawable/license_plate.jpg");
byte[] data = Files.readAllBytes(path);
java.nio.file.NoSuchFileException: drawable/license_plate.jpg
Where should I be saving this image so I can use it during the application?
And where should I be saving images used for future applications when I am not just using a single picture I have already preloaded?
You give wrong path. You can only save a picture in your device and
then give image folder path for example :
Path path = Paths.get("/storage/projects/alpr/samples/testing/car1.jpg");
byte[] data = Files.readAllBytes(path);
I have an Android application that i'm working on and now i'm trying to get a File from an URI (i'll use an intent to get an image from gallery and then upload it to a node.js server using Ion). Te problem is it always throws an exception. I tried debugging and got the Uri.toString(). It looks something kind of like this:
content://com.android.providers.media.documents/document/image%3A102
I know for a fact that it should look like this:
content://com.android.providers.media.documents/document/image:102
I know that the %3A is a representation of :, but why does it appear in the Uri and, how can i fix it? Finally, how can i get my file from this Uri?
i'm trying to get a File from an URI
A Uri is not a file. A Uri does not have to point to anything on the filesystem, let alone a place that you can access.
but why does it appear in the Uri
A Uri is an opaque handle. It can be whatever the ContentProvider wants it to be.
how can i fix it?
You don't, any more than you "fix" https://stackoverflow.com/questions/41795342/get-path-from-uri-throws-exception because you do not like eight-digit numbers starting with 4. Just as the Stack Overflow Web server defines that URLs it uses, so does a ContentProvider define what Uri values it uses.
Finally, how can i get my file from this Uri?
Ideally, you don't. You use ContentResolver and openInputStream() to get an InputStream on the content identified by that Uri, and Ion uses that.
If Ion does not support this and can only work with a file, use the InputStream to copy the bytes to some FileOutputStream that you control (e.g., in getCacheDir()). Use that file for your upload, then delete the file when you are done.
I am trying to use my app to open a file from external storage.
I am using Share via feature.
my code Export
File filelocation = new File(sPath);
Uri path = Uri.fromFile(filelocation);
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("vnd.android.cursor.dir/email");
emailIntent.putExtra(Intent.EXTRA_STREAM, path);
String mystring = ctx.getResources().getString(R.string.Import_rule);
emailIntent.putExtra(Intent.EXTRA_TEXT, mystring);
Import function
if (Intent.ACTION_SEND.equals(in.getAction()))
{
uri = (Uri) in.getParcelableExtra(Intent.EXTRA_STREAM);
uri.getPath();
}
When i try to get the uri.getPath() i see difference in differnt devices versions.
in Android 5.0 devicve :
file:///storage/emulated/0/Download/DeviceList.zip
in Android 6.0 device
content://0#media/external/file/1147
I dont know why the URI scheme is different across versions?
How can i resolve this?
Can you tell me how can i read from content and save as file
I dont know why the URI scheme is different across versions?
content has been a valid scheme since Android 1.0. It is has been preferred for years due to better security. It will become extremely important in the future, as Android N is beginning to ban file Uri values.
Also, please note that change in schemes this has little to do with the Android OS version. It has more to do with the version of the app you are using to trigger the ACTION_SEND Intent.
How can i resolve this?
Support both of them.
Can you tell me how can i read from content and save as file
Use ContentResolver and openInputStream() to get an InputStream on the content pointed to by the Uri. Then, use Java I/O to copy that data to a local file.
I'm having trouble coverting from a URI to a nio.Path in the general case. Given a URI with multiple schemas, I wish to create a single nio.Path instance to reflect this URI.
//setup
String jarEmbeddedFilePathString = "jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml";
URI uri = URI.create(jarEmbeddedFilePathString);
//act
Path nioPath = Paths.get(uri);
//assert --any of these are acceptable
assertThat(nioPath).isEqualTo("C:/Program Files (x86)/OurSoftware/OurJar_x86_1.0.68.220.jar/com/our_company/javaFXViewCode.fxml");
//--or assertThat(nioPath).isEqualTo("/com/our_company/javaFXViewCode.fxml");
//--or assertThat(nioPath).isEqualTo("OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml")
//or pretty well any other interpretation of jar'd-uri-to-path any reasonable person would have.
This code currently throws FileSystemNotFoundException on the Paths.get() call.
The actual reason for this conversion is to ask the resulting path about things regarding its package location and file name --so in other words, as long as the resulting path object preserves the ...com/our_company/javaFXViewCode.fxml portion, then its still very convenient for us to use the NIO Path object.
Most of this information is actually used for debugging, so it would not be impossible for me to retrofit our code to avoid use of Paths in this particular instance and instead use URI's or simply strings, but that would involve a bunch of retooling for methods already conveniently provided by the nio.Path object.
I've started digging into the file system provider API and have been confronted with more complexity than I wish to deal with for such a small thing. Is there a simple way to convert from a class-loader provided URI to a path object corresponding to OS-understandable traversal in the case of the URI pointing to a non-jar file, and not-OS-understandable-but-still-useful traversal in the case where the path would point to a resource inside a jar (or for that matter a zip or tarball)?
Thanks for any help
A Java Path belongs to a FileSystem. A file system is implemented by a FileSystemProvider.
Java comes with two file system providers: One for the operating system (e.g. WindowsFileSystemProvider), and one for zip files (ZipFileSystemProvider). These are internal and should not be accessed directly.
To get a Path to a file inside a Jar file, you need to get (create) a FileSystem for the content of the Jar file. You can then get a Path to a file in that file system.
First, you'll need to parse the Jar URL, which is best done using the JarURLConnection:
URL jarEntryURL = new URL("jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml");
JarURLConnection jarEntryConn = (JarURLConnection) jarEntryURL.openConnection();
URL jarFileURL = jarEntryConn.getJarFileURL(); // file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar
String entryName = jarEntryConn.getEntryName(); // com/our_company/javaFXViewCode.fxml
Once you have those, you can create a FileSystem and get a Path to the jar'd file. Remember that FileSystem is an open resource and needs to be closed when you are done with it:
try (FileSystem jarFileSystem = FileSystems.newFileSystem(jarPath, null)) {
Path entryPath = jarFileSystem.getPath(entryName);
System.out.println("entryPath: " + entryPath); // com/our_company/javaFXViewCode.fxml
System.out.println("parent: " + entryPath.getParent()); // com/our_company
}