Provided I have an array of image URLs, I am trying to download all these images one-by-one using glide. Presently, I am able to download a single image when I provide its URL. And here is the code:
private void downx()
{
File sd = getExternalCacheDir();
File folder = new File(sd, "/mobio/");
if (!folder.exists()) {
if (!folder.mkdir()) {
Log.e("ERROR", "Cannot create a directory!");
} else {
folder.mkdirs();
}
}
final File[] fileName = {new File(folder, "one.jpg"), new File(folder, "two.jpg"),new File(folder, "three.jpg")};
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params)
{
try
{
theBitmap = Glide.
with(getApplicationContext()).
load(urls[2]).
asBitmap().
into(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL).
get();
}
catch (final ExecutionException e)
{
Log.e("TAG", e.getMessage());
}
catch (final InterruptedException e)
{
Log.e("TAG", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Void dummy) {
if (null != theBitmap) {
// The full bitmap should be available here
Log.d("TAG", "Image loaded");
Log.e("GLIDE","I am Ready");
try {
FileOutputStream outputStream = new FileOutputStream(String.valueOf(fileName[1]));
theBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.execute();
}
Now the problem is: What approach do I adopt if I need to download multiple images, and how do I force my code to adapt to handle multiple downloads?
I have used a class which takes a list of URLs and downloads the Images to a file. Please check this Gist for more. This uses Picasso to download Images but you can edit the download code to use glide as well. Should be a one line change. Hope this helps.
https://gist.github.com/bpr10/a765a015bf1c774816ba58c7ae6413d6
I guess it will be better to use Download Manager as it will handle queuing, network availability etc.
Related
I am currently on the beginner level when it comes to Android & I am currently scratching my head over an issue that I am currently facing.
I am creating an Android app to check if "cache.json" exists in the internal storage:
If it does not exist then first create it & write a string fetched from HTTP API to the file (replaced with fixed string in code below).
Regardless, read the file after writing is done (if necessary) & do appropriate stuff.
This is the code snippet:
public class ShowClasses extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
filename = "cache.json";
file = new File(getApplicationContext().getFilesDir(), filename);
if (file.exists()) {
System.out.println("EXISTS");
} else {
System.out.println("DOES NOT EXIST");
writeFile();
}
readFile();
}
public void writeFile() {
new JsonTask().execute(email);
}
public void readFile() {
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int c;
result = "";
try {
while( (c = fin.read()) != -1){
result = result + Character.toString((char)c);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
private class JsonTask extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
result = ""; // Clear result
super.onPreExecute();
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
return "THIS STRING IS GOING TO BE RETURNED " + params[0];
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fileout = null;
try {
fileout = new FileOutputStream(file);
fileout.write(result.getBytes());
//display file saved message
msg("File saved successfully!");
} catch (Exception e) {
e.printStackTrace();
}
try {
fileout.close();
} catch (IOException e) {
e.printStackTrace();
}
if (pd.isShowing()){
pd.dismiss();
}
}
}
}
I have tried to remove un-necessary part of the code so that it is smaller in length.
The actual issue I am facing is when writeFile() & readFile() both are called. I get a FileNotFoundException in readFile() when I open the stream even though the file should be created since writeFile() is called before readFile().
If I writeFile on one execution & then call readFile() on the other, it simply works as it should be.
This is the error that I am facing.
System.err: java.io.FileNotFoundException: /data/user/0/host.timetable.timetablenotifier/files/cache.json (No such file or directory)
System.err: at java.io.FileInputStream.open(Native Method)
Any help would be really appreciated.
Thanks
writeFile() is asynchronous. When that method returns, nothing has happened with respect to this file. At most, onPreExecute() of your JsonTask might be called. So, when you call readFile(), the file will not exist yet.
Beyond that:
You have an AsyncTask that you use in writeFile(), but you do your disk I/O in onPostExecute(), and that method is called on the main application thread.
You are doing disk I/O on the main application thread in readFile().
You catch exceptions, log them, but then continue executing your code, when most of those exceptions mean that the later statements are going to fail as well.
Reading in data one int at a time has not been a recommended approach for getting close to 20 years, for performance reasons.
You will have multiple issues related to configuration changes, such as screen rotations, as neither your AsyncTask nor your ProgressDialog account for configuration changes
Also:
getApplicationContext().getFilesDir() could be replaced by getFilesDir() in onCreate()
You do not need createNewFile()
AsyncTask runs in a background thread so the other code in the main thread doesn't wait for the execution to complete. In simpler terms, your readFile() method is executed before writeFile() completes and hence there is a FileNotFoundException. What would work for you is if you put the readFile() method at the end of the onPostExecute() method inside your Asynctask
Basically I have been using Vaadin Designer to design my UI. One of my use cases asks me to upload an iCalendar file, I use a grammar (ANTLR) to get from it what I need. I came across my issue when after seeing the Vaadin Upload documentation and applying it to my use case when running it, nothing would happen and no exception would be thrown. After a bit of research and debugging I believe this is due to the Thread for the upload being shutdown for some reason.
Here is my code, any help?
private void uploadLogic() {
class IcalendarUploader implements Upload.Receiver, Upload.SucceededListener, Upload.FinishedListener, Upload.FailedListener {
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
try {
//We'll store the uploadad file as temporary file.
tempFile = File.createTempFile("temp", ".ics");
fos = new FileOutputStream(tempFile);
} catch (IOException e) {
Notification.show(e.getMessage(), Notification.Type.WARNING_MESSAGE);
return null;
}
}
#Override
public void uploadFinished(Upload.FinishedEvent event) {
try {
controller.importIcalendar(tempFile);
tempFile.delete();
Notification.show("Uploaded iCalendar file with :\n" + controller.iCalendarDetails(),
Notification.Type.HUMANIZED_MESSAGE);
} catch (IOException e) {
Notification.show(e.getMessage(), Notification.Type.WARNING_MESSAGE);
}
}
#Override
public void uploadSucceeded(Upload.SucceededEvent event) {
try {
if(controller.saveTimeSlot()){
Notification.show("Uploaded iCalendar file with :\n" + controller.iCalendarDetails()
+"\nSaved time slot with success",
Notification.Type.HUMANIZED_MESSAGE);
}else {
Notification.show("Uploaded iCalendar file with :\n" + controller.iCalendarDetails()
+ "\nTime slot has an overlapp!",
Notification.Type.WARNING_MESSAGE);
}
} catch (DataConcurrencyException e) {
Notification.show(e.getMessage(), Notification.Type.WARNING_MESSAGE);
} catch (DataIntegrityViolationException e) {
Notification.show(e.getMessage(), Notification.Type.WARNING_MESSAGE);
}
}
#Override
public void uploadFailed(Upload.FailedEvent event) {
Notification.show("Upload failed", Notification.Type.ERROR_MESSAGE);
}
}
IcalendarUploader receiver = new IcalendarUploader();
upload.setReceiver(receiver);
}
Hey I am trying to upload an image to my ftp server but from some reason the connection isn't working and I can figure out why..
here is the connection code:
public void uploadingFilestoFtp() throws IOException {
FTPClient ftpclient = new FTPClient();
FileInputStream fis = null;
boolean result;
try {
ftpclient.connect(host);
result = ftpclient.login(username, password);
if (result == true) {
System.out.println("Logged in Successfully !");
} else {
System.out.println("Login Fail!");
return;
}
ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
ftpclient.changeWorkingDirectory("/");
File file = new File(imagePath);
fis = new FileInputStream(file);
// Upload file to the ftp serverresult = ftpclient.storeFile(testName, fis);
if (result == true) {
System.out.println("File is uploaded successfully");
} else {
System.out.println("File uploading failed");
}
ftpclient.logout();
} catch (FTPConnectionClosedException e) {
e.printStackTrace();
} finally {
try {
ftpclient.disconnect();
} catch (FTPConnectionClosedException e) {
System.out.println(e);
}
}
}
I am using exactly the details of the ftp server but it doesn't seems to work
How can I get this mehod to work?
android.os.NetworkOnMainThreadException
You are trying to make a network request from the UI thread. Android doesn't allow any network request from main(UI) thread. You need to create a class extending AsyncTask.
public class UploadFileTask extends AsyncTask <Void, Void, Void > {
public void onPreExecute() {
}
public void doInBackground(Void...unused) {
uploadingFilestoFtp(); //Call your method here. Put necessary try-catch block.
}
public void onPostExecute(Void unused) {
// do something when upload is done.
}
}
Note that this onPreExecute() and onPostExecute() run on the UI thread. So you can do any stuff before or after the network call. Make the network call in doInBackground() method.
Check this answer How to fix android.os.NetworkOnMainThreadException?
I have a Parse Android app for which I am implementing Facebook sign up. Currently I am stuck on grabbing images to set as profile pictures of new ParseUser's. I have successfully used the Facebook Graph API to retrieve the correct URL (I have checked this by plugging it into a browser, where I am shown the right profile picture), but I now need a way to turn that URL into a byte array (byte[]) so that I can save the ParseFile field of our ParseUser's profile picture. I have already looked at all these SO questions:
• java.net.URL read stream to byte[]
• Efficiently read file from URL into byte[] in Java
• Get image with given url and convert it to byte array
None of these have worked. I am currently trying to use the Apache IOutils, like in the solution from the second link. Here is my current code for the AsyncTask:
private class SetProfPicWithURL extends AsyncTask<URL, Integer, byte[]> {
#Override
protected byte[] doInBackground(URL... imageURL) {
Log.i("SetProfPicWithURL", "invocation, URL: " + imageURL[0]);
InputStream is = null;
byte[] bytes = null;
try {
is = imageURL[0].openStream();
bytes = IOUtils.toByteArray(is);
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (is != null) try {
is.close();
if(bytes == null){Log.e("LoginActivity", "bytes is null int SetProfPicWithURL");}
final ParseFile imageFile = new ParseFile("image.jpg", bytes);
imageFile.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("LoginActivity", "getCurrentUser.put");
ParseUser.getCurrentUser().put(ParseUtils.PARSE_PROFILE_IMAGE, imageFile);
ParseUser.getCurrentUser().saveInBackground();
} else {
e.printStackTrace();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
return bytes;
}
}
Now when this code executes, I get no error logs, and a ParseFile is created. However, no profile pictures load within the app, and when I click to examine the file in the dashboard, I get this error message:
The file “tfss-0280f98d-7180-4528-9d24-3ec47d3b25d4-image.jpg” could
not be opened because it is empty.
Honestly, I'm at a loss. I've spent significantly more time on this one photo issue than any other part of implementing the Facebook login. And the way our database is set up, it is really not ideal to create another field to save the URL and load with Picasso. Any help with this issue is truly appreciated!
Directly save your imagefile as profile picture like this :
final ParseFile imageFile = new ParseFile("image.jpg", bytes);
ParseUser.getCurrentUser().put(ParseUtils.PARSE_PROFILE_IMAGE, imageFile);
ParseUser.getCurrentUser().saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("LoginActivity", "Profile saved succesfully");
} else {
e.printStackTrace();
}
}
});
EDIT :
Use this to get image byte array from url.
try {
java.net.URL img_value = new java.net.URL(imageURL);
Bitmap mIcon = BitmapFactory
.decodeStream(img_value.openConnection()
.getInputStream());
if (mIcon != null)
imgByteArray = encodeToByteArray(mIcon);
} catch (Exception e) {
e.printStackTrace();
}
public byte[] encodeToByteArray(Bitmap image) {
Log.d(TAG, "encodeToByteArray");
Bitmap b= image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imgByteArray = baos.toByteArray();
return imgByteArray ;
}
Can someone possibly help me with this?
I want to observe a file to see if it gets modified so that I can update the activity. After several tests, I've determined it's just plain not working.
Am I doing something wrong?
I'm creating a FileObserver with an onEvent method to display a Toast and log data just to see if it's working, however the onEvent is never getting called.
I have tried it both with an existing and a new file, but it doesn't seem to work in either case.
Context context = this;
File fileFolder = context.getFilesDir();
String fileName = "quest";
FileObserver questObserver = new FileObserver(fileFolder.getPath()) { // also tried fileFolder.getName()
#Override
public void onEvent(int event, String path) {
Toast.makeText(getApplicationContext(), "onEvent fired", Toast.LENGTH_LONG).show();
Log.d(TAG, "FileObserver().onEvent");
}
};
questObserver.startWatching();
/* create file */
ObjectOutputStream objectOut = null;
try {
FileOutputStream fileOut = context.openFileOutput(fileName, Context.MODE_PRIVATE);
objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(new Quest());
fileOut.getFD().sync();
} catch (IOException e) {
Log.d(TAG, e.getMessage());
} finally {
if (objectOut != null) {
try {
objectOut.close();
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
}
}
/* read file */
ObjectInputStream objectIn = null;
Quest quest = null;
try {
FileInputStream fileIn = context.openFileInput(fileName);
objectIn = new ObjectInputStream(fileIn);
quest = (Quest) objectIn.readObject();
} catch (FileNotFoundException e) {
// Do nothing
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (objectIn != null) {
try {
objectIn.close();
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
}
}
Toast.makeText(context, quest.getTitle(), Toast.LENGTH_LONG).show();
questObserver.stopWatching();
Any help would be greatly appreciated.
'public abstract void onEvent (int event, String path)" -
This method is invoked on a special FileObserver thread. It runs
independently of any threads, so take care to use appropriate
synchronization! Consider using post(Runnable) to shift event handling
work to the main thread to avoid concurrency problems.
http://developer.android.com/reference/android/os/FileObserver.html
If you put the toast through a handler.post(new Runnable(){...}), that should work.
Assuming your file doesn't (always) exist you should probably put your observer on the files folder, obtained like so:
Context ctx = ...;
File filesFolder = ctx.getFilesDir();
Note that this will also ensure that the filesFolder directory will be created.
Your observer will now be notified whenever a file is written, deleted or updated using for instance Context#.openFileOutput(..) - and you can filter in your FileObserver for the file name, in your example "quest".