I am using Azure mobile service to upload images from android device.
I have followed the documentation to upload images successfully.
But I can't find any documentation to download the blobs.
Code i used to upload blob is here..
public void uploadPhoto() {
if (MainActivity.mClient == null) {
return;
}
final Assignment_Attachment item = new Assignment_Attachment();
item.setAttachementIdentifier(attachmentUniqueIdentifier);
item.setFilename(MAP_FILE_NAME_KEY);
item.setContainerName("schoolonlineblobattachment");
// Use a unigue GUID to avoid collisions.
UUID uuid = UUID.randomUUID();
String uuidInString = uuid.toString();
item.setResourceName(uuidInString);
// Send the item to be inserted. When blob properties are set this
// generates a SAS in the response.
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
final Assignment_Attachment entity = addItemInTable(item);
Log.d("sasquerystring", "sasquerystring" + entity.getSasQueryString());
// If we have a returned SAS, then upload the blob.
if (entity.getSasQueryString() != null) {
// Get the URI generated that contains the SAS
// and extract the storage credentials.
StorageCredentials cred = new StorageCredentialsSharedAccessSignature(entity.getSasQueryString());
URI imageUri = new URI(entity.getImageUri());
// Upload the new image as a BLOB from a stream.
CloudBlockBlob blobFromSASCredential = new CloudBlockBlob(imageUri, cred);
blobFromSASCredential.uploadFromFile(DATA_FOR_UPLOAD);
}
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
} catch (final Exception e) {
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//other logic here
}
};
runAsyncTask(task);
}
I can see a "downloadToFile()" method, but still searching a way to use the SAS thing for download process.
Has anybody done this? Any help is appreciated.
To use the SAS, you need a sharedAccessPolicy:
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: 'w',
Expiry: azure.date.minutesFromNow(5)
}
}
The sharedAccessPolicy.AccessPolicy.Permissions w' is for uploading while 'r' is for downloading.
Not verified myself yet, but you can try http://inessential.com/2014/04/22/mobile_services_and_blob_storage. See also the code at https://code.msdn.microsoft.com/windowsapps/Upload-File-to-Windows-c9169190.
Hope it will help.
Related
I am trying to upload an image from storage to server. Am I doing anything wrong here? Do I need to use a PHP script for this?
private class UploadImage extends AsyncTask{
File picPath;
String picName;
public UploadImage(File picPath, String picName){
this.picPath= picPath;
this.picName = picName;
}
#Override
protected Void doInBackground(Void... params) {
String uril = getResources().getString(R.string.ServerPath) + "MyFiles/" + picName;
AndroidNetworking.upload(uril)
.addMultipartFile(picName, picPath)
.addMultipartParameter("key","value")
.setPriority(Priority.MEDIUM)
.build()
.setUploadProgressListener(new UploadProgressListener() {
#Override
public void onProgress(long bytesUploaded, long totalBytes) {
if (bytesUploaded == totalBytes){
Toast.makeText(getApplicationContext(), "Image Uploaded!",Toast.LENGTH_SHORT).show();
}
}
});
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(getApplicationContext(), "Uploaded!",Toast.LENGTH_SHORT).show();
}
}
Please note the library which you have considers UPLOAD as POST, but if you need to use 'PUT' method your API call will fail and provide you 400, bad request.
I have implemented the file upload to Amazon S3 following the Amazon guide and I have noticed that it is too slow. It takes around 10 sec to upload a simple png file around 20kb.
Initially I thought that the problem was related with threads and I have implemented an AsyncTask to upload the image, but the problem is still there. Following is the code employed to upload the image.
private class UploadFileTask extends AsyncTask<String, Integer, String> {
String remotePath;
String remoteFileName;
File file;
Context context;
S3UploadInterface listener;
public UploadFileTask(Context context,String remotePath,String remoteFileName, File file, S3UploadInterface listener){
this.context=context;
this.remotePath=remotePath;
this.remoteFileName=remoteFileName;
this.file=file;
this.listener=listener;
}
protected String doInBackground(String... params) {
credentialsProvider = new CognitoCachingCredentialsProvider(context,
"MY_PRIVATE_CREDENTIAL",
Regions.US_EAST_1);
TransferManager transferManager = new TransferManager(credentialsProvider);
Upload upload = transferManager.upload(remotePath, remoteFileName, file);
TransferProgress transferred = upload.getProgress();
while (!upload.isDone()) {
try {
publishProgress((int) transferred.getPercentTransferred());
} catch (Exception e) {
listener.uploadFailed(e);
}
}
return "uploaded";
}
protected void onProgressUpdate(Integer... progress) {
if (listener!=null)
listener.currentUploadProgress(progress[0]);
}
protected void onPostExecute(String result) {
if (listener!=null)
listener.uploadCompleted();
}
}
Any idea to solve this problem?
Thanks :)
This is going to hammer your CPU
while (!upload.isDone()) {
try {
publishProgress((int) transferred.getPercentTransferred());
} catch (Exception e) {
listener.uploadFailed(e);
}
}
Try adding Thread.sleep to give other threads time to run.
I have a group of images that users upload in my app. I store the image path in an sqlite database and the image in the internal storage of the app.
I was able to go around deleting a single image if the user selects it and chooses to delete it. My problem now is that I have a clear all button sort of, that is meant to clear a particular group of images. How do I loop around this?
Here I have made a asynTask class for deleting multiple files at once.
private class DeleteFilesAsync extends AsyncTask<String, Integer, Integer> {
ProgressDialog mProgressDialog;
ArrayList<String> fileNames = new ArrayList<String>();
public DeleteFilesAsync(ArrayList<String> fileNames) {
this.fileNames = fileNames;
}
#Override
protected void onPreExecute() {
try {
mProgressDialog = new ProgressDialog(
SavedImageListingActivity.this);
mProgressDialog.setMessage("deleting...");
mProgressDialog.show();
} catch (Exception e) {
// TODO: handle exception
}
super.onPreExecute();
}
#Override
protected Integer doInBackground(String... params) {
for (int i = 0; i < fileNames.size(); i++) {
String fileName = fileNames.get(i);
File file = new File(fileName);
if (file.exists()) {
if (file.isFile()) {
file.delete();
onProgressUpdate(i);
}
}
}
return null;
}
#Override
protected void onPostExecute(Integer result) {
try {
mProgressDialog.dismiss();
} catch (Exception e) {
// TODO: handle exception
}
// Do more here after deleting the files
super.onPostExecute(result);
}
}
How to use it
new DeleteFilesAsync(imgFilesSelected).execute("");
Where imgFilesSelected is type ArrayList<String>
Add all files path in imgFilesSelected list like
imgFilesSelected.add("my_path_dir/filename.jpg");
imgFilesSelected.add("my_path_dir/filename2.png");
imgFilesSelected.add("my_path_dir/filename3.png"); // etc
then pass it to DeleteFilesAsync() class contructor as shown above.
All done.
I'm having difficulties keeping track of my queue and uploading them at a later moment.
The upload image is a asynctask and in the postexecute a mail is going out to send the uploaded picture.
This is my UploadImage AsyncTask. I think i'm doing way too difficult and that it can be done much easier than it is right now.
private class UploadImageTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
/**
* Private integer which counts how many times we've tried to upload the
* Image.
*/
private int _counter = 0;
private List<String> imageUploadList = new ArrayList<String>();
#Override
protected void onPreExecute() {
super.onPreExecute();
if(AppStatus.haveNetworkConnection(_context)){
if(isPhotoTaken()){
dialog = new ProgressDialog(Step4.this);
dialog.setCancelable(false);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(getString(R.string.uploadingMessage));
dialog.setTitle(getString(R.string.uploadingTitle));
dialog.show();
}
}
}
protected Integer doInBackground(Void... params) {
init();
postData();
return null;
}
public void init(){
_counter = 0;
_beenHere = true;
for(String path : imageUploadList){
Debug.out("Path: "+path);
}
}
public void postData() {
if (isPhotoTaken()) {
if(AppStatus.haveNetworkConnection(_context)){
if(_beenHere){
ImageUploader.uploadFile(getPhotoPath(),
"http://obo.nl/android-upload-image.php", Step4.this);
} else {
for(String path : imageUploadList){
Debug.out(path);
ImageUploader.uploadFile(path,
"http://obo.nl/android-upload-image.php", Step4.this);
}
}
} else {
if (_counter == 0) {
_counter++;
_activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(_context,
getString(R.string.noInternetImageNotUploaded),
Toast.LENGTH_LONG).show();
}
});
imageUploadList.add(getPhotoPath());
}
try {
if(_beenHere){
_beenHere = false;
goToNextIntent();
}
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
postData();
}
}
}
private void goToNextIntent(){
Intent intent = new Intent(Step4.this, Step5.class);
intent.putExtra(EXTRA_MESSAGE, (Serializable) _user);
intent.putExtra(EXTRA_MESSAGE2, _isRepairable);
intent.putExtra(EXTRA_MESSAGE3, _injury);
intent.putExtra(EXTRA_MESSAGE4, _category);
intent.putExtra(EXTRA_MESSAGE5, _inch);
intent.putExtra(EXTRA_MESSAGE6, _size);
startActivity(intent);
}
protected void onPostExecute(Integer result) {
if(isPhotoTaken()){
if(dialog != null){
dialog.dismiss();
}
}
mailing(_isRepairable);
new MyAsyncTask().execute(_mail);
}
}
The line:
if(AppStatus.haveNetworkConnection(_context))
returns a boolean true if the user has a working internet connection. false otherwise.
What I want is to queue all the image paths (and mails sent afterwards) in the desired ArrayList so i can send them all at a later moment when the user has a working internet Connection. Please help me out!
You could store your image paths in a list (or something similar) and persist the list, let's say in Shared Preferences. As you finish uploading a picture, you will remove it from that list and continue to the next one, and so on until your list is empty.
While uploading, if the internet connection drops it will not affect you, you will always have persisted the list of images that are still to be uploaded.
Register a broadcast receiver to listen for wi-fi connection, when it gets connected it could automatically continue the upload - this is just a suggestion.
I'm trying to add import contacts from gmail account function in my android app. So the first problem is to get access token from gmail. I've found that there is GoogleAuthUtil class which can help me with it.
Here is my code:
private void importContactsFromGmail() {
showProgressDialog();
GetTokenTask getTokenTask = new GetTokenTask();
getTokenTask.execute();
String token = "";
try {
token = getTokenTask.get();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(token);
hideProgressDialog();
}
private class GetTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String token = "";
try {
token = GoogleAuthUtil.getToken(activity, <My_gmail_account>, "https://www.google.com/m8/feeds/");
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
}
Now after calling GoogleAuthUtil.getToken my app completely freezes(no errors in Logcat). I completely stuck and I need your help.
What is wrong with my code? Maybe I should import contacts in some other way?
Not sure if this is related but calling the .get() method on the main thread is not correct because is blocking method.
What if you use the AsyncTask in this way?
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new GetTokenTask().execute();
}
static class GetTokenTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... unused) {
String token = "";
try {
token = GoogleAuthUtil.getToken(activity, <My_gmail_account>, "https://www.google.com/m8/feeds/");
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
#Override
protected void onPostExecute(String token) {
Toast.makeText(MainActivity.this, token, Toast.LENGTH_SHORT).show();
}
}
}
(I wrote without compiling it, maybe it needs to be adjusted)
On Android devices, Gmail contacts are synced locally onto the device and are available via a public Contacts Provider, therefore there's no reason you'd need to use the Google API to pull what is already available. There is a whole training series dedicated specifically to retrieving a list of contacts.
Note that the Contacts training series does assume you have knowledge of Content Providers already, so it may be helpful to read up on the basics of Content Providers as well.