How should I notify images Content Provider, that I just saved a file in Pictures directory? I expect e.g. Gallery-like apps to be able to see my new file.
Uri uri = Uri.fromFile(file);
getContext().getContentResolver().notifyChange(uri, null);
which I found somewhere (Vogella?) does not seem to work. Or is it a wrong approach from the start?
The image notification is done after the image is inserted into media database. This is usually done by the android system media scanner when it finds the image.
You can write your own code to insert the image into the media database and then call getContext().getContentResolver().notifyChange(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null); to notify that some image has changed without beeing specific exatly which image.
If you modified an image that is already in the media database you have to translate the file uri into a content: uri. getContext().getContentResolver().notifyChange(imageContentUri, null); .
If you are implementing for android-4.4 or later You can ask the media scanner to (re)analyse your file. For details see How to trigger MediaScan on Nexus 7? . in pre android-4.4 this might not work as expected (i.e. on my android-4.2 it starts a complete rescan)
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've been trying for several hours to open an image from Android's external storage with Intent.ACTION_VIEW. And as you might have figured out already, I'm still not able to do that.
I've searched all over Google and I've tried a lot of ways to make this work, however none of them did. All what I could find are questions that are up to 1 year old. I tried using FileProvider and here's what I ended up with:
File imagePath = new File(Environment.getExternalStorageDirectory(), "LyceeLamartine/cache");
File newFile = new File(imagePath, "calendrier.png");
Uri contentUri = FileProvider.getUriForFile(MainActivity.this, "ml.toufic.lyceelamartine.fileprovider", newFile);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(contentUri, "image/*");
startActivity(intent);
The code above opens Google Photos successfully but it shows a black screen and the path seems to be: content://ml.toufic.lyceelamartine.fileprovider/name/calendrier.png and this seems like an internal storage path.
The image I want to access is stored at: "/storage/emulated/0/LyceeLamartine/cache/calendrier.png" and I'm using a phone with Android O (8.0).
I'm still a beginner in Java and any help would be greatly appreciated!
the path seems to be: content://ml.toufic.lyceelamartine.fileprovider/name/calendrier.png and this seems like an internal storage path.
That is not a path. That is a Uri. It has a scheme (content). It points to your FileProvider (ml.toufic.lyceelamartine.fileprovider). It seems fine — if there were a problem with the Uri, FileProvider would have thrown an exception when you tried to create it.
The code above opens Google Photos successfully but it shows a black screen
There are two problems with your Intent.
First, do not use a wildcard MIME type. It is your file. You know what the MIME type is. Use the actual MIME type (in this case, image/png).
Second, call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) on the Intent as part of setting it up, before calling startActivity(). Right now, no app has rights to use your content.
I am trying to get the path of the image the user selects from the gallery. So far I have made the button and used the following code to get the user to select the image from gallery:
public void image(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);
}
Now, I'm trying to get the path of this image so that I can store it in the database to be used to retrieve it later. I know how to insert the path into the DB but just don't know how to get the path name.
Also, I want to copy the image the user has selected and paste into a new folder, where all the images will be.
Any help will be appreciated.
Thanks
So far I have made the button and used the following code to get the user to select the image from gallery
No, you are asking the user to select an image. Any number of apps can offer an activity that supports ACTION_GET_CONTENT for image/* data, not just something that you consider to be a gallery.
Now, I'm trying to get the path of this image so that I can store it in the database to be used to retrieve it later
There is no path, and there is nothing that you can store that you can necessarily use later. The Uri that you get back (via the Intent passed into onActivityResult()) will work for a short time. It is reminiscent of a URL you might get to an image in a Web site, where the URL only works while the user is authenticated. Either use the Uri right away, or plan on having the user pick the image again in the future. Or, switch to the Storage Access Framework and hope that you get a Uri that is durable and has persistable permissions (and set your minSdkVersion to 19 or higher).
I want to copy the image the user has selected and paste into a new folder, where all the images will be
It is unclear what "copy the image the user has selected and paste into a new folder" means to you. If you mean what computer users would refer to as "copy the file", use ContentResolver and openInputStream() to get an InputStream on the image. Then, use standard Java I/O to copy that to some file under your control. The path to that file you could store in your database, as you are now managing that copy of the file. However, this causes duplication of data (two copies of the image), which the user may or may not want.
You can store image in bytearray format in sqlite database.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos);
byte[] byteArray=baos.toByteArray();
and then use this byteArray to insert image in Sqlite. :)
Hope this helps to you.
Can I get and edit the list of files, downloaded with DownloadProvider?
What do I mean? We have an application called Downloads in Android that displays all the downloads made with DownloadProvider. The records it displays are stored in a database somewhere in /data and are not strongly connected with real files. E.g. if I delete a record in Downloads, the file is deleted too, but not vice versa.
So, I want to delete the file in filesystem and delete the record in Downloads application about this file.
Currently I have tried using something like:
DownloadManager dm = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterByStatus(DownloadManager.STATUS_PAUSED|
DownloadManager.STATUS_PENDING|
DownloadManager.STATUS_RUNNING|
DownloadManager.STATUS_SUCCESSFUL);
Cursor cur = dm.query(query);
and I don't see any ID's in query which I could pass to the DownloadManager.remove(long...IDs). Can I do what I want with Android API or the only way to achieve this is to edit the database itself?
Try call
mDownloadManager.remove(long... ids)