Using Volley to download image/video to external storage (Android) - java

i have urls of i got as response from a volley JsonObectRequest. What i want to be able to do is save those images directly into a folder on my external storage so i don't have to load them from the internet anymore. Please keep in mind that download may also include videos...
//Here is the volley code for retrieving the urls
private static final String endpoint = "http://api.androidhive.info/json/glide.json";
//Code to extract image url
JsonArrayRequest req = new JsonArrayRequest(endpoint,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
pDialog.hide();
images.clear();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject object = response.getJSONObject(i);
Image image = new Image();
image.setName(object.getString("name"));
JSONObject url = object.getJSONObject("url");
image.setSmall(url.getString("small"));
image.setMedium(url.getString("medium"));
image.setLarge(url.getString("large"));
image.setTimestamp(object.getString("timestamp"));
} catch (JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
}
}
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
pDialog.hide();
}
});
Now, how do i request a download so they files are save in my external using volley. Thank you

public boolean storeImages(Bitmap imageBitmap, String fileName, String dirName, int index) {
File file;
if (isExternalStorageWritable() && isExternalStorageReadable()) {
file = storeImageExternalMemory(dirName, albumName, String.valueOf(index));
}
try {
assert file != null;
FileOutputStream out = new FileOutputStream(file);
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
updateImageTable(file, index); // Implement Your own method to update ur DB table, U can access file location from DB table for future use of images
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
Convert your downloaded image into bitmap and the save to desired location in cellphone. Then You can reuse image.
private File storeImageExternalMemory(String dirName, String mediaName) {
String packageName = mContext.getPackageName();
File mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/Android/data/" + packageName + dirName);
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath(), mediaName + ".jpeg");
return mediaFile;
}
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}

Related

Send multiple photos from Room with Retrofit (Android)

I have an app the stores photos with Room in the database I store a image in a byte[].
I have an activity where when I press the button upload the images through Retrofit but when I start to upload, the app throws an error.
Here is the code of the function to upload the images;
for (int i = 0; i < evidences.size(); i++) {
order = evidences.get(i).getMobmx();
ticketEv = evidences.get(i).getTicketEv();
Toast.makeText(this, "MOBMX: " + order, Toast.LENGTH_SHORT).show();
File filesDir = this.getFilesDir();
File photo = new File(filesDir, "" + order + ".jpeg");
FileOutputStream fos;
try {
fos = new FileOutputStream(photo);
fos.write(ticketEv);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), photo);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", photo.getName(), requestFile);
apiService.uploadPod(getString(R.string.uploadPodOfflinePetition), body, RequestBody.create(MediaType.parse("text/plain"), order))
.enqueue(new Callback<UserData>() {
#Override
public void onResponse(Call<UserData> call, Response<UserData> response) {
if (response.isSuccessful()) {
if (response.body() != null) {
try {
processResult(response.body().getMsg(), response.body().getData());
} catch (Exception e) {
Toast.makeText(OnlineEvidenceActivity.this, "Error procesando la respuesta del servidor, por favor intente de nuevo", Toast.LENGTH_SHORT).show();
}
}
} else {
try {
String erroResp = response.errorBody().string();
Log.i("ERROR", erroResp);
processError(erroResp);
} catch (IOException | JSONException e) {
e.printStackTrace();
Toast.makeText(OnlineEvidenceActivity.this, "Error al procesar respuesta", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<UserData> call, Throwable t) {
//RequestFailHandler.handleFail(OnlineEvidenceActivity.this, t);
Log.e("ERROREVIDENCIA", t.getMessage());
}
});
}
Here is the function when the response is successful:
private void processResult(String msg, Object data) {
StatusPODS statusPODS = new StatusPODS();
if (msg.equals("ok")) {
Toast.makeText(this, "Procesar evidencia", Toast.LENGTH_SHORT).show();
statusPODS.setMobmx(order);
statusPODS.setStatus("Exitoso");
evidenceDAO.insertStatus(statusPODS);
//evidenceDAO.deleteRow(order);
} else if (msg.equals("warning")) {
Toast.makeText(this, "" + data, Toast.LENGTH_SHORT).show();
statusPODS.setMobmx(order);
statusPODS.setStatus("Warning");
evidenceDAO.insertStatus(statusPODS);
//evidenceDAO.deleteRow(order);
} else {
//Error
Toast.makeText(this, "" + data, Toast.LENGTH_SHORT).show();
statusPODS.setMobmx(order);
statusPODS.setStatus("Error");
evidenceDAO.insertStatus(statusPODS);
//evidenceDAO.deleteRow(order);
}
}
This is the Service endpoint:
#Multipart
#POST("mobile/uploadpodoffline")
Call<UserData> uploadPod(#Header("petition") String petition,
#Part MultipartBody.Part image,
#Part ("order") RequestBody order);
And finally this is the error when upload the first image:
HTTP FAILED: java.net.ProtocolException: expected 422764 bytes but received 425984
Any solution to upload the images creating a new File and send through the for loop with retrofit (?)
Thanks

How to restore file from GDrive?

I am making an app which stores its SQLite Database backup on GDrive. I succeeded in signing in and uploading the file in the drive but failed to restore it. Following is the code.
I use SQLiteDatabase to store the fileID so that when it is required while updating and restoring, it can be used. I am looking for a method which will make use of FileID to restore.
Error occurs at file.getDownloadUrl() and file.getContent().
class DriveClassHelper
{
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private static Drive mDriveService;
private String FileID = null;
private static String filePath = "/data/data/com.example.gdrivebackup/databases/Data.db";
DriveClassHelper(Drive mDriveService)
{
DriveClassHelper.mDriveService = mDriveService;
}
// ---------------------------------- TO BackUp on Drive -------------------------------------------
public Task<String> createFile()
{
return Tasks.call(mExecutor, () ->
{
File fileMetaData = new File();
fileMetaData.setName("Backup");
java.io.File file = new java.io.File(filePath);
String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("application/x-sqlite-3");
FileContent mediaContent = new FileContent(mimeType, file);
File myFile = null;
FileID = getFileIDFromDatabase();
try {
if (FileID != null) {
Log.i("CALLED : ", FileID);
//mDriveService.files().delete().execute();
myFile = mDriveService.files().update(FileID, fileMetaData, mediaContent).execute();
} else {
myFile = mDriveService.files().create(fileMetaData, mediaContent).execute();
MainActivity.demoSQLite.insertData(myFile.getId());
}
} catch (Exception e) {
e.printStackTrace();
}
if (myFile == null) {
throw new IOException("Null Result when requesting file creation");
}
Log.i("ID:", myFile.getId());
return myFile.getId();
}
);
}
// -------------------------------------------------------------------------------------------------
// ---------------------------------- TO get File ID -------------------------------------------
private static String getFileIDFromDatabase()
{
String FileIDFromMethod = null;
Cursor result = MainActivity.demoSQLite.getData();
if (result.getCount() == 0) {
Log.i("CURSOR :", "NO ENTRY");
return null;
} else {
while (result.moveToNext()) {
FileIDFromMethod = result.getString(0);
}
return FileIDFromMethod;
}
}
// -------------------------------------------------------------------------------------------------
// ---------------------------------- TO Restore -------------------------------------------
public static class Restore extends AsyncTask<Void, Void, String>
{
#Override
protected String doInBackground(Void... params) {
String fileId = null;
try
{
fileId = getFileIDFromDatabase();
if (fileId != null)
{
File file = mDriveService.files().get(fileId).execute();
downloadFile(file);
}
else
{
return null;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return fileId;
}
private void downloadFile(File file)
{
InputStream mInput = null;
FileOutputStream mOutput = null;
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) //Error occurs at file.getDownloadUrl()
{
try
{
HttpResponse resp = mDriveService.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
mInput = resp.getContent();
String outFileName = "file://" + Environment.getDataDirectory().getPath() + filePath;
// Log.e("com.example.myapp", "getDatabasePath="+ getDatabasePath(""));
//Log.e("com.example.myapp", "outFileName="+outFileName);
// String outFileName = "../databases/" + "Quickpay.db";
mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
}
catch (IOException e)
{
// An error occurred.
e.printStackTrace();
// return null;
}
finally
{
try
{
//Close the streams
if (mOutput != null)
{
mOutput.close();
}
if (mInput != null)
{
mInput.close();
}
}
catch (IOException e)
{
Log.e("com.example.myapp", "failed to close databases");
}
}
}
else
{
// The file doesn't have any content stored on Drive.
// return null;
Log.e("com.example.myapp", "No content on Drive");
}
}
}
}
The Gradle file is like
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0')
{
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.api-client:google-api-client-android:1.26.0')
{
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
As far as i know Download URL is only avalibale in Google drive api v2 and not in V3.
Short lived download URL for the file. This field is only populated for files with content stored in Google Drive; it is not populated for Google Docs or shortcut files.
It was not very stable in my opinion as not all file types would return a download url.
Using Google Drive v3 you should download the file using a stream.
String fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().get(fileId)
.executeMediaAndDownloadTo(outputStream);
This should work with the restore. Let me know if it doesnt and i will have a look its been a while since i have tried restore.

Android Amazon S3 Upload. error 405

I have been trying for several days to connect Amazon S3 to my Android project. I downloaded the example "https://github.com/awslabs/aws-sdk-android-samples" "S3TransferUtilitySample" and everything works fine on it, I see the files through the aws admin panel.
I copied into my project "Constants.java" with the working settings, also copied "Util.java" without changes.
The purpose of my project is to record the file from the microphone and transfer it to the cloud.
Here is the singleton that should implement this operations :
public class RecorderHelper {
private static final String TAG = "UploadActivity";
private static TransferUtility sTransferUtility;
static private Util util;
static RecorderHelper singleton;
static Boolean RecordStateRecording;
private static MediaRecorder recorder;
private final String RECORD = Environment.getExternalStorageDirectory() + "/record.aac";
String fileName;
private RecorderHelper() {
}
public static RecorderHelper getSingleton(Context context) {
if (singleton == null) {
RecordStateRecording = false;
singleton = new RecorderHelper();
util = new Util();
AmazonS3Client s3Client = util.getS3Client(context);
sTransferUtility = util.getTransferUtility(context);
}
;
return singleton;
}
public void StopRecording() {
try {
if (RecordStateRecording) {
recorder.stop();
recorder.reset();
recorder.release();
AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl(RECORD));
if (aacTrack.getSamples().size() > 1000) {
CroppedTrack aacTrackShort = new CroppedTrack(aacTrack, aacTrack.getSamples().size() - 1000, aacTrack.getSamples().size());
Movie movie = new Movie();
movie.addTrack(aacTrackShort);
Container mp4file = new DefaultMp4Builder().build(movie);
FileChannel fc = new FileOutputStream(new File(fileName)).getChannel();
mp4file.writeContainer(fc);
fc.close();
aacTrackShort.close();
aacTrack.close();
} else {
aacTrack.close();
}
}
File file = new File(RECORD);
TransferObserver observer = sTransferUtility.upload(Constants.BUCKET_NAME, file.getName(),
file);
observer.setTransferListener(new UploadListener());
} catch (Exception e) {
Log.e("RECORD", e.getMessage());
}
RecordStateRecording = false;
}
public void StartNewRecording(String UUID) {
StopRecording();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
fileName = Environment.getExternalStorageDirectory() + "/" + UUID + ".aac";
recorder.setOutputFile(RECORD);
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start(); // Recording is now started
RecordStateRecording = true;
}
private class UploadListener implements TransferListener {
// Simply updates the UI list when notified.
#Override
public void onError(int id, Exception e) {
Log.e(TAG, "Error during upload: " + id, e);
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
Log.d(TAG, String.format("onProgressChanged: %d, total: %d, current: %d",
id, bytesTotal, bytesCurrent));
}
#Override
public void onStateChanged(int id, TransferState newState) {
Log.d(TAG, "onStateChanged: " + id + ", " + newState);
}
}
}
However, the file does not appear in the cloud and the listener tells me about the 405 error. Here is the full text.
Can anyone tell me what I'm doing wrong?
Unable to unmarshall error response (Attempt to invoke virtual method
'boolean java.lang.String.equals(java.lang.Object)' on a null object
reference). Response Code: 405, Response Text:
I'm ussing the latest SDK :
compile 'com.amazonaws:aws-android-sdk-s3:2.6.+'
Not sure about stacktrace because because i just get a callback to my listener about the transfer fails.
API 22

How can I pass my base64 string on my web server?

Are my codes correct? I already have published this on my Web server. What happens are, it is creating a text file but the base64 string are not written on that text file.
These are my codes from Android Studio
private void uploadImage() {
final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
loading.dismiss();
Toast.makeText(MainActivity.this, s , Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
loading.dismiss();
Toast.makeText(MainActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
String image = getStringImage(bitmap);
Map<String,String> params = new Hashtable<String, String>();
params.put("b64", image);
Log.d("base64: ", String.valueOf(params));
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
These are my codes on VS
[HttpPost]
public String ProcessImg([FromBody] string b64)
{
String base64 = b64;
String jsonStr = null;
//function to create image from b64 string
try
{
var FilePath = ConfigurationManager.AppSettings["imgFilePath"];
if (!Directory.Exists(FilePath))
{
Directory.CreateDirectory(FilePath);
}
//to create file and write base64 string
var name = DateTime.Now.ToString("MMddyyyy-HHmmss");
var FileName = Path.Combine(FilePath, name + ".png");
string path = Path.Combine(FilePath, name + ".txt");
StreamWriter file = new StreamWriter(path);
file.Write(base64);
file.Close();
if (File.Exists(FileName))
{
jsonStr = "file successfully created on server. :" + FileName;
}
else
{
jsonStr = "Sorry the file you tried to convert failed.";
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
jsonStr = ex.Message;
}
//Algo
return jsonStr;
}
StreamWriter is best used with the using keyword as it implements IDisposable which automatically calls the Dispose() method like this:
using(StreamWriter file = new StreamWriter())
{
file.Write(base64);
}
Otherwise you will have to call the Flush() method manually to write the buffered input to the disk before closing the file:
StreamWriter file = new StreamWriter();
file.Write(base64);
file.Flush();
file.Close();
The flush part is done when the stream's Dispose() method is called, thus implementing it with the using keyword automatically takes care of that.

File Not Found Exception : Open failed:ENOENT

I am new for android, Im downloading image from URL and set in listView. Its working some mobile and not creating file/directory in some mobile.
Its throw error like:
java.io.FileNotFoundException: /storage/emulated/0/.tam/veg.png: open failed: ENOENT (No such file or directory)
I don't know why its throw error like this some mobile. I want to create directory all type of mobile. Please anyone help me.
Here my code:
public class ImageStorage {
public static String saveToSdCard(Bitmap bitmap, String filename) {
String stored = null;
File sdcard = Environment.getExternalStorageDirectory();
File folder = new File(sdcard.getAbsoluteFile(), ".tam");//the dot makes this directory hidden to the user
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), filename) ;
if (file.exists())
return stored ;
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
stored = "success";
} catch (Exception e) {
e.printStackTrace();
}
return stored;
}
public static File getImage(String imagename) {
File mediaImage = null;
try {
String root = Environment.getExternalStorageDirectory().getAbsolutePath();
File myDir = new File(root);
if (!myDir.exists())
return null;
mediaImage = new File(myDir.getPath() + "/.tam/"+imagename);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mediaImage;
}
public static File checkifImageExists(String imagename) {
File file = ImageStorage.getImage("/" + imagename);
if (file.exists()) {
return file;
} else {
return null;
}
}
public static String getImageName(String value){
String getName[] = value.split("/");
return getName[4];
}
}
Below path not in all mobile:
/storage/emulated/0/
Thanks in advance!!
Maybe u should check if there's external storage in the mobile before u use this path
public String getDir(Context context) {
String checkPath = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
checkPath = Environment.getExternalStorageDirectory().getPath();
} else {
checkPath = context.getCacheDir().getPath();
}
return checkPath;
}

Categories

Resources