Cancel GetObjectRequest Amazon S3 - android

I download an image from S3 using their SDK as follows:
s3Client.getObject(new GetObjectRequest("a24images", s3FileURLString), file);
However, I can't find anything in the docs to indicate how to:
• cancel a request
• pause a request
Any advice on implementing cancel and pause on these requests would be appreciated please.

The variant of the getObject method you are using may not allow for cancellation, but if you just use the more basic s3Client.getObject(
new GetObjectRequest(bucketName, key)); then this should just give you a reference to an input stream as already mentioned by sanket.
There is not really much "optimization" being done here, but if you wanted to see or reuse the code that Amazon itself uses it's here:
https://github.com/aws/aws-sdk-java/blob/master/src/main/java/com/amazonaws/services/s3/internal/ServiceUtils.java?source=c#L236

As far as I know, the:
S3Object object = s3.getObject(new GetObjectRequest(bucketname, key));
will give you a handler to the object. You would further need to read the object to either a file system or an output stream like this:
InputStream is = object.getObjectContent();
int read = 0;
byte[] bytes = new byte[BYTES_DOWNLOAD];
OutputStream os = response.getOutputStream();
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
os.flush();
os.close();
The while loop above will actually read the object from S3 and in this case convert it to an OutputStream.
You may want to look at controlling the while loop with a boolean value that you can set from wherever you need to cancel this request.
Is this what you need to achieve ?
Or have I got the question wrong ?
This answer is in terms with the java sdk.
Thanks

try with this.
myS3Client.shutdown();
but i did manual tracking i just take one Boolean and when user try to cancel then it will be false and the time when download from s3 just check weather it is true or false if false then i delete that file from my side in sdcard.

Related

Buffered file reading in Flutter

I have following Dart code and I am trying to make reading the file buffered. Just like Java's BufferedReader or C++ ifstream. Is there such functionality? I cannot even find buffer mentioned in file.dart nor file_impl.dart. If I understood my debugging correctly, it seems that Dart is reading the whole file at once.
So could anybody help me make it buffered or point me in right direction where the buffer is?
final file = File(join(documentsDirectory, "xxx.txt"));
final List<String> lines = await file.readAsLines(); //file.readAsLinesSync()
lines.forEach((line) {
....
});
Use file.openRead(). This will return a Stream of bytes. If you want to read as characters, transform the stream using the appropriate decoder (probably utf8).
As it says, you must read the stream to the end, or cancel it.

How to get object from Google cloud storage bucket

I have used this below code for get object from google cloud storage bucket.i have error in getMetadata. Can any one please tell me here what is getMetadata and how to get that ?
Storage.Objects.Get getObject = client.objects().get(bucketName, objectname);
if (getMetadata == true) {
StorageObject object = getObject.execute();
} else {
// Downloading data.
ByteArrayOutputStream out = new ByteArrayOutputStream();
// If you're not in AppEngine, download the whole thing in one request, if possible.
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(true);
getObject.executeMediaAndDownloadTo(out);
}
It looks like you're running through the sample code snippet; in that snippet, getMetadata is simply referring to your own choice of whether you want to view the object's metadata like size, content-type, creation time, etc., or whether you actually want to download the object's contents.
In your actual code using it, you probably won't structure it that way using any getMetadata variable. Instead, you should just use the code from the branch of that conditional that you need in each particular circumstance. For example, if you just want to get the size of the object so that you can display the number of bytes somewhere without actually downloading it:
Storage.Objects.Get getObject = client.objects().get(bucketName, objectname);
StorageObject object = getObject.execute();
System.out.println("Size is: " + object.getSize().longValue());
Or if you just wanted to dump the contents to System.out:
Storage.Objects.Get getObject = client.objects().get(bucketName, objectname);
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(true);
getObject.executeMediaAndDownloadTo(System.out);

Dropobx Sync API doesn't update

I'm working with the Dropbox Sync API and read in a file from dropbox, when I change the value in this file manually when my app isn't running and I start the app again, the change doesn't come through in my Android app. The value from file.readString() hasn't changed. After I restart my app several times, the changes come through. I tried dbxFs.syncNowAndWait(), file.update() and several other things to make this work. I can't seem to find the problem, after syncNowAndWait, the dropbox filesystem should "Force a check for new file info from the server" according to the documentation, but this doesn't seem to happen. Any ideas? Thanks!
dbxFs.syncNowAndWait();
DbxFile file = dbxFs.open(new DbxPath("Apps/serverIP/serverIP.txt"));
sendIPBroadcast(file.readString().split("\n")[0]);
All reads in the Sync API are from cache, and all downloads are asynchronous. So you need to open the file (which will open the cached copy from the last time you ran the app) and register a listener to be notified when a new version of the file has been downloaded. A new version will only be downloaded if you keep the file open. See https://www.dropbox.com/developers/sync/start/android#listeners for an example of how to set up a listener.
I was able to fix my problem by directly downloading the content from the dropbox URL. So I have the content immediately instead of have to wait for the updated content to be downloaded and cached. For further changes, I have a listener running.
URL url = new URL("url");
URLConnection ucon = url.openConnection();
String ip = getServerResponse(new byte[1], new DataInputStream(ucon.getInputStream()));
private String getServerResponse(byte[] b, DataInputStream in) throws IOException {
String serverSentence = "";
while(true){
in.read(b, 0, 1);
String character = new String(b, "UTF-8");
if(character.equals("*")) break;
serverSentence += character;
}
return serverSentence;
}

Android Creating a memory resident input file that can be attached to an email

The final objective will be clear shortly.
I want to create a file object and instead of getting data from a real physical file I want to provide the buffer myself.
Then, I want to use this file, which does not really exist in the sdcard or anywhere outside my app, give it a name and send it by email as an attachment (using the EXTRA_STREAM).
I found the following bit of code, by Adriaan Koster (#adriaankoster), the post Write byte[] to File in Java
// convert byte[] to File
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
File fileFromBytes = (File) ois.readObject();
bis.close();
ois.close();
System.out.println(fileFromBytes);
I used it to create this function
private File fileFromBytes(byte[] buf) {
File f = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
ObjectInputStream ois = new ObjectInputStream(bis);
f = (File) ois.readObject();
bis.close();
ois.close();
}
catch (Exception e) {}
return f;
}
and here is where I am stuck, because when I use it:
// When sent as body the mail is sent OK
// emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, dump());
// When I try to attach the mail is empty
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, fileFromBytes(dump().getBytes()));
I know from examples I've seen the second argument should be an URI, but: How do I create a virtual URI to fit my file?
EDIT:
The option to attach data directly from within the application is important to certain kind of applications. Namely, security & banking applications that do not want to move sensitive data around too much. Surely if the data does not reach the sdcard and goes directly to a mail attachment it is harder to sniff than within the application memory.
This is not my specific case, but I wanted to point out that this capability is important to have.
The first thing you'll want to do, I imagine, is create a ContentProvider. You can see an example implementation here
https://github.com/dskinner/AndroidWeb/blob/master/src/org/tsg/web/WebContentProvider.java
where in the above link's case, you would add this to your AndroidManifest.xml
<provider
android:name="org.tsg.web.WebContentProvider"
android:authorities="your.package.name" />
Now, you'll have a content uri available for use, content://your.package.name/.
The portion of the above ContentProvider your interested in, again I imagine, is the openFile method. When sharing data by intent across apps, certain things are expected. In your case, you're looking to share some byte data that's meant to be attached to the email.
So if you pass in a content uri to the email app such as content://your.package.name/foo with the appropriate intent flags, then openFile will get called on your ContentProvider. In this case, you can inspect the end of the uri segment to see foo was requested, and return appropriately.
The next issue you bring up is not having the file actually on disk. While I can't vouch for the method you used above (though it looks kosher), what you need to be returning is a ParcelFileDescriptor from your ContentProvider. If you look at the link I provided, you could possibly try to use that as a sample to get the file descriptor from your File object (my knowledge waivers here), but I imagine, the data simply wont be available at that point.
What you do bring up is security though. It's important to note that you can write data to disk privately so only the app has access to the data. I believe, but you might want to double check on this, if that data is private to the app, you can expose it via the ContentProvider and possibly lock down who and how the provider gets used, who can call it, etc. You may want to dig into android docs for that portion or look at some other SO questions.
Anyway, good luck.
Create the file in the application's cache directory. It will be created in the internal filesystem. Use 'getCacheDir()' API for getting the path to the cache dir. Write the data into this dir and then get the URI from the File object using ' Uri.fromFile (File file) '. When you are finished with the file, delete it.
Your application's cache is only available to your app, hence its safe to use for your purpose.
You can do some encryption if the data is too critical.
I think in order to do this, you are going to have to expose a ContentProvider, which will allow you handle a URI. The email application should then openInputStream on your URI, at which point you return an InputStream on your in-memory data.
I've not tried it, but in theory this should work.
i was busy with adding attachment to mail and i can send mail with attachment.
if you want to take a look: can not send mail with attachment in Android

Verify sqlite database before import into android app

I have an app in which I have added Export/Import DB functionality... I want to do two things:
1) When exporting: Scramble the exported database so that normal folks (I know that some people can decode the best camouflage techniques) cannot read the contents...
2) When importing: Verify the file being imported to make sure that it is something that will work with my app and not anything else.
I have seen some links here about encryption that can address the 1st point here. But I dont want to do encryption. I want to do some simple scrambling. And I have seen some posts about verifying the table contents by checking for the tables that my application looks for. That is a good solution but i need to load the file first to verify and roll back if there are errors.
Any help would be greatly appreciated...
very very simple way: add some header to the file which you can later read back in and check:
// w/o exception handling finally etc
String secret = "zomg,secret";
byte[] header = secret.getBytes();
byte[] buffer = new byte[4096];
FileInputStream in = new FileInputStream("/your/sqlite.db");
FileOutputStream out = new FileOutputStream("/sdcard/the.secretfile");
out.write(header);
int read = 0;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
out.close();
in.close();
The best and simple way to deal with this is to generate Checksum (MD5) of your database file and compare with your per-calculated one. For more info
So I finally settled to doing DES encryption using cipherinputstream and instead of adding a header to verify the integrity, I am checking to see if all my table names are present in the file being imported. I saw that the sqlite DB file has the ddl statements in clear text. This is probably not the most elegant/complete solution but it works.

Categories

Resources