Storage Access Framework - Saving Uri - java

My app needs to archive a folder Uri (from an Inten with ACTION_OPEN_DOCUMENT_TREE and the right flags inside that has been returned to the app from user selection) in the suitable form to use it next time the app is run or the device is booted (takePersistableUriPermission is used).
Saving the Uri path as a string seems not to be enough, because
Uri uri;
uri=Uri.parse(uriPath);
docUri= DocumentsContract.buildDocumentUriUsingTree(uri,
DocumentsContract.getTreeDocumentId(uri));
gives an error like invalid Uri.
Saving also the Uri id is not useful.
I see that the Uri has many parameters inside. I checked which parameters have values inside my sample Uri and a few are.
So I would know how to save a Uri so the app has all necessary data to recreate it and the DocumentsContract class (or similar) can query its parameters not throwing any exceptions.
Any suggestion is welcome

The right way to archive a Uri is by means of saving the uri.toString() value.
Then to retrieve it: uri=Uri.parse(archivedUriString);

Related

How to give read access permission for Firestore imageurl in Java

I am able to access the Firestore image url on my browser window.
I want to convert this image url into BufferedImage after reading I have to find sub-image to get barcode value presented on my image.
Here is the code, I have connected with my bucket using Firestore and selecting few images from bucket based on conditions.
And rules for writing/reading is given as allow read, write: if true; in Firestore storage.
And initialized my FireBaseInitialize with key.json (service account details).
BufferedImage img = ImageIO.read(new File(imageUrl)); // imageUrl is contains path (environment, bucket, database name) & token
Getting below IIOException,
javax.imageio.IIOException: Can't read input file!
java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1310)
How to give read permission for images in Firestore bucket in order to read by Java ImageIO class. I am not using android version. This is specific to Java.
I suspect if permission is missing I am unable to access collection itself, correct me if I am wrong ?
Note: For testing purpose I have changed the storage permission to access to all.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
Still getting the same error, javax.imageio.IIOException: Can't read input file!
The javax.imageio.IIOException was thrown because the File class can only be instantiated with paths that are accessible through the local system, that does not include HTTP or HTTPS URIs.
Hopefully next version of Java would handle cloud things in a better way. If someone able to request for this feature from Java would be much appreciated.

Is there a way to retrieve file from SharePoint without file name?

I know how to retrieve a file with a specified name like this:
HttpGet httpGet = new HttpGet(siteUrl +
"_api/web/GetFolderByServerRelativeUrl('Shared%20Documents/Working%20Files/FolderName')/Files('"
+workbookName+"')/$value");
but is there a way to retrieve it without the name? maybe by index?
Ive checked the documentation on https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/working-with-folders-and-files-with-rest but saw no other examples on how else to retrieve files
Every file you upload into the Sharepoint will have the field Id mapped to it. This ID would be returned as part of the response whenever you create the file in the Sharepoint. This response would also return several links and fields related to the particular file you uploaded, in order to perform any operations on that file.
Using these fields such as Id, E-Tag you should be able to form another request to get the file name.
You can also find the request URL in the response you received after file creation.

Get real path from URI? Android 9+

I have the uri of my files. Now I need to get its real path to send them. (the uri is like: "content://some-path").
This is for Android 9
So with Android 9+ you can only use file paths inside you applications private storage area otherwise you have to use URI's and ContentResolvers
See https://developer.android.com/training/data-storage/files/external-scoped for details of the changes in 9+
So I see three solutions when using Retrofit2
Get a Java FileDescriptor from a contentResolver and read the file from the contentResolver, writing it to your App's private storage area. You can then get a Java File Object as normal from this copy of the file. This is similar to stackoverflow.com/a/52814247/3518278 as suggested by ViVekH
Get a Java FileDescriptor from a contentResolver and read it in to a in memory Byte array. I'm not a Retrofit2 user but I believe you can create Request Body or Multipart part from a Byte array instead of a Java File object.
Raise a feature request with RetroFit2 / OKHTTP to be able to give it a Java FileDescriptor object instead of a File Object
Note with the contentResolver you can query it to get the "Display Name" as the filename part of the Path.

Streaming audio file directly from blob

So I am working on this project where I want to store an audio file in a LARGEBLOB on a database, the size of the file is limited to about 10MB, and be able to load the data through a java servlet that allows for playing of the media file.
Most of the sources I have been able to find suggests storing it locally, however, I want to avoid this solution based on the fact that I'd like to rebuild the website somewhere completely different and not have to rely on the folder structure to be the same.
The issues that I am encountering area mainly that the web browser misinterprets the binary data provided by the servlet. It manages to retrieve that it is an audio file of some sort, however; it is unable to determine the type of audio file, which leads me to believe that the servlet is either not providing enough data, or that I am not doing enough to instruct the web browser on how to play the file.
For example, if I have a file audio.mp3 which I have uploaded to the database into a table Tracks and stored in a column TrackFile. Assuming the query of selecting the right song from the table, what data would the servlet need to provide in order for the browser to play the file when accessing the servlet. Currently when I load the servlet, the browser seems to assume that the type is audio/mpeg instead of audio/mp3. The content currently delivered by the servlet also looks something like this:
response.setHeader("Content-Type", this.getServletContext().getMimeType(t.getTrackName() + '.' + t.getFileType()));
response.setHeader("Content-Length", String.valueOf(t.getTrackData().length));
response.setHeader("Content-Disposition", "inline; filename=\"" + t.getTrackName() + '.' + t.getFileType() + "\"");
response.getOutputStream().write(t.getTrackData());
where t is an object which holds all the data which can be retrieved from the database table about a specific track. The method getTrackData() returns a byte[] with contents of the column TrackFile in it. The source of this method is: link, although I adapted it in order to make it work with audio files, although it doesn't.
Are there any obvious things that I should have caught onto based on the fact that I can't get it to play back the file or is what I want to achieve generally impossible so to say?

Came across the Intent parameter Uri.parse("mailto:"). What exactly does Uri.parse do?

I am trying to create a new intent to send email and came across this code to create an Intent.
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
What does Intent.ACTION_SEND do?
What does Uri.parse("mailto:") do?
Documentation is written to that purpose :
What does Intent.ACTION_SEND do?
Activity Action: Deliver some data to someone else. Who the data is
being delivered to is not specified; it is up to the receiver of this
action to ask the user where the data should be sent.
When launching a SEND intent, you should usually wrap it in a chooser
(through createChooser(Intent, CharSequence)), which will give the
proper interface for the user to pick how to send your data and allow
you to specify a prompt indicating what they are doing.
Input: getType() is the MIME type of the data being sent. get*Extra
can have either a EXTRA_TEXT or EXTRA_STREAM field, containing the
data to be sent. If using EXTRA_TEXT, the MIME type should be
"text/plain"; otherwise it should be the MIME type of the data in
EXTRA_STREAM. Use / if the MIME type is unknown (this will only
allow senders that can handle generic data streams). If using
EXTRA_TEXT, you can also optionally supply EXTRA_HTML_TEXT for clients
to retrieve your text with HTML formatting.
As of JELLY_BEAN, the data being sent can be supplied through
setClipData(ClipData). This allows you to use
FLAG_GRANT_READ_URI_PERMISSION when sharing content: URIs and other
advanced features of ClipData. If using this approach, you still must
supply the same data through the EXTRA_TEXT or EXTRA_STREAM fields
described below for compatibility with old applications. If you don't
set a ClipData, it will be copied there for you when calling
startActivity(Intent).
Optional standard extras, which may be interpreted by some recipients
as appropriate, are: EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC, EXTRA_SUBJECT.
Output: nothing.
Constant Value: "android.intent.action.SEND"
What does Uri.parse("mailto:") do?
Intent (String action,
Uri uri)
Create an intent with a given action and for a given data url. Note
that the action must be in a namespace because Intents are used
globally in the system -- for example the system VIEW action is
android.intent.action.VIEW; an application's custom action would be
something like com.google.app.myapp.CUSTOM_ACTION.
Note: scheme and host name matching in the Android framework is
case-sensitive, unlike the formal RFC. As a result, you should always
ensure that you write your Uri with these elements using lower case
letters, and normalize any Uris you receive from outside of Android to
ensure the scheme and host is lower case.
More information about intent

Categories