ProgressDialog is not showing when .3gp file converting to a .zip - android

I am working on Android app.
I need to show a progress dialog box when I click on button.
In that button I am converting video file to .zip file and calculating that file size.
In this process I need to show a ProgressDialog, but it is not showing.
Screen get struck while calculating and after calculation it shows ProgressDialog and then screen navigating to the next screen.
My Code:
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaCheck.this.runOnUiThread(new Runnable() {
public void run() {
pd = ProgressDialog.show(MediaCheck.this, "",
"Checking the video compatability. Please wait", true);
}
});
video_Path= makeZip(video_Path);
if (video_Path.equalsIgnoreCase("File size is too large")) {
pd.dismiss();
Toast.makeText(getApplicationContext(),
"Large video", Toast.LENGTH_LONG)
.show();
return;
}
pd.dismiss();
// Doing screen navigation here.
}
});
Code to make a zip and know the size
private static String makeZip(String videoPath) {
byte[] buffer = new byte[1024];
String[] videoFileName = videoPath.split("/");
File directory = null;
try {
ContextWrapper cw = new ContextWrapper(context_this);
// path to /data/data/yourapp/app_data/imageDir
directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
FileOutputStream fos = new FileOutputStream(directory
+ "/IRCMS_Video.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze = null;
ze = new ZipEntry(videoFileName[5]);
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(videoPath);
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
File videoZip = new File(directory + "/IRCMS_Video.zip");
videoLength = videoZip.length() / (1024 * 1024);
if (videoLength > 3)
return "File size is too large";
in.close();
zos.closeEntry();
// remember close it
zos.close();
System.out.println("Done");
} catch (IOException ex) {
ex.printStackTrace();
}
return directory.toString() + "/IRCMS_Video.zip";
}
}
Please help...

then you should try ASYNCTASK to easily perform your operation and reduce the complexity of using threads
private class Converter extends AsyncTask<String, Void, Void> { //Converter is class name
protected String doInBackground(String... urls) {
//THIS METHOD WILL BE CALLED AFTER ONPREEXECUTE
//YOUR NETWORK OPERATION HERE
return null;
}
protected void onPreExecute() {
super.onPreExecute();
//THIS METHOD WILL BE CALLED FIRST
//DO OPERATION LIKE SHOWING PROGRESS DIALOG PRIOR TO BEGIN NETWORK OPERATION
}
protected void onPostExecute(String result) {
super.onPostExecute();
//TNIS METHOD WILL BE CALLED AT LAST AFTER DOINBACKGROUND
//DO OPERATION LIKE UPDATING UI HERE
}
}

You are doing calculation on UI thread therfore it hangs your app. Do calculation on background thread. You can resolve this by-
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pd = ProgressDialog.show(MediaCheck.this, "",
"Checking the video compatability. Please wait", true);
Thread background = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
video_Path= makeZip(video_Path);
MediaCheck.this.runOnUiThread(new Runnable()
{
public void run()
{
if (video_Path.equalsIgnoreCase("File size is too large")) {
pd.dismiss();
Toast.makeText(getApplicationContext(),
"Large video", Toast.LENGTH_LONG)
.show();
pd.dismiss();
return;
}
}
});
}
});
background.start();
// Doing screen navigation here.
}
});

Related

How to display ProgressBar in the form of a Notification?

I'm Developing an android application to download .mp3 from Server.
When clicked on the download button ProgressBar will appear,displaying the
percentage on screen.
This works fine. Now i want to make that download work in background by Showing Notification with a ProgressBar
can anyone help me to find a code to Use the Service and Building Notification?Thank You
My MainActivity.java code:
public class MainActivity extends Activity {
final MediaPlayer mp=new MediaPlayer();
//---------------------
Clone c=new Clone();
//------------------
// button to show progress dialog
Button btnShowProgress;
// Progress Dialog
private ProgressDialog pDialog;
ImageView my_image;
// Progress dialog type (0 - for Horizontal progress bar)
public static final int progress_bar_type = 0;
// File url to download
private static String file_url = "http://www.eecindia.co.in/up/01%20-%20Pretham%20-%20Oruthikku%20Pinnil%20[Maango.me].mp3";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// show progress bar button
btnShowProgress = (Button) findViewById(R.id.btnProgressBar);
// Image view to show image after downloading
my_image = (ImageView) findViewById(R.id.my_image);
/**
* Show Progress bar click event
* */
btnShowProgress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//----------------------------------------------
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Select The Extension To Download...");
builder.setItems(new CharSequence[]
{".mp3", ".mp4", ".txt", ".srt"},
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// The 'which' argument contains the index position
// of the selected item
switch (which) {
case 0:
/////////////////////////////////////////////////////////////////
File folder = new File(Environment.getExternalStorageDirectory().getPath() + "/Jithin's/");
if (!folder.exists()) {
try {
folder.mkdirs();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + folder);
}
}
c.setA(Environment.getExternalStorageDirectory().toString() + "/Jithin's/downloadedfile.mp3");
// starting new Async Task
new DownloadFileFromURL().execute(file_url);
/////////////////////////////////////////////////////////////
break;
case 1:
////////////////////////////////////////////////////////////
File folde = new File(Environment.getExternalStorageDirectory().getPath() + "/Jithin's/");
if (!folde.exists()) {
try {
folde.mkdirs();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + folde);
}
}
c.setA(Environment.getExternalStorageDirectory().toString() + "/Jithin's/downloadedfile.mp4");
// starting new Async Task
new DownloadFileFromURL().execute(file_url);
////////////////////////////////////////////////
break;
case 2:
File fold = new File(Environment.getExternalStorageDirectory().getPath() + "/Jithin's/");
if (!fold.exists()) {
try {
fold.mkdirs();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + fold);
}
}
c.setA(Environment.getExternalStorageDirectory().toString() + "/Jithin's/downloadedfile.txt");
// starting new Async Task
new DownloadFileFromURL().execute(file_url);
break;
case 3:
File fol = new File(Environment.getExternalStorageDirectory().getPath() + "/Jithin's/");
if (!fol.exists()) {
try {
fol.mkdirs();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + fol);
}
}
c.setA(Environment.getExternalStorageDirectory().toString() + "/Jithin's/downloadedfile.srt");
// starting new Async Task
new DownloadFileFromURL().execute(file_url);
break;
}
}
});
builder.create().show();
/////-------------------------------------
}
});
}
/**
* Showing Dialog
* */
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type:
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading File. Please Wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(false);
pDialog.show();
return pDialog;
default:
return null;
}
}
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
*/
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
// 6yi7 conection.connect();
conection.setRequestProperty("Accept-Encoding", "identity");
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(c.getA());
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
*/
protected void onProgressUpdate(String... progress) {
// setting progress percentage
try {
pDialog.setProgress(Integer.parseInt(progress[0]));
} catch (Exception d) {
Log.d("Error .. ", d.getMessage());
}
}
/**
* After completing background task
* Dismiss the progress dialog
**/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
Toast.makeText(MainActivity.this, "Downloaded Succesfully.. check Jithin's folder 2 see file...", Toast.LENGTH_LONG).show();
//my_image.setImageDrawable(Drawable.createFromPath(imagePath));
}
}
//---------------------------------
protected void onStop(){
super.onStop();
Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);
}
}
You can use foreground Notification.Here is your Example
project demonstrating the use of startForeground().

Find out that file download [duplicate]

I am trying to write a simple application that gets updated. For this I need a simple function that can download a file and show the current progress in a ProgressDialog. I know how to do the ProgressDialog, but I'm not sure how to display the current progress and how to download the file in the first place.
There are many ways to download files. Following I will post most common ways; it is up to you to decide which method is better for your app.
Use AsyncTask and show the download progress in a dialog
=============================================================
This method will allow you to execute some background processes and update the UI at the same time (in this case, we'll update a progress bar).
Imports:
import android.os.PowerManager;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
This is an example code:
// declare the dialog as a member field of your activity
ProgressDialog mProgressDialog;
// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true); //cancel the task
}
});
The AsyncTask will look like this:
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/file_name.extension");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate and onPreExecute run on the UI thread, so there you can change the progress bar:
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
}
}
For this to run, you need the WAKE_LOCK permission.
<uses-permission android:name="android.permission.WAKE_LOCK" />
Download from Service
========================
The big question here is: how do I update my activity from a service?. In the next example we are going to use two classes you may not be aware of: ResultReceiver and IntentService. ResultReceiver is the one that will allow us to update our thread from a service; IntentService is a subclass of Service which spawns a thread to do background work from there (you should know that a Service runs actually in the same thread of your app; when you extends Service, you must manually spawn new threads to run CPU blocking operations).
Download service can look like this:
public class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
public DownloadService() {
super("DownloadService");
}
#Override
protected void onHandleIntent(Intent intent) {
String urlToDownload = intent.getStringExtra("url");
ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
try {
//create url and connect
URL url = new URL(urlToDownload);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
String path = "/sdcard/BarcodeScanner-debug.apk" ;
OutputStream output = new FileOutputStream(path);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int) (total * 100 / fileLength));
receiver.send(UPDATE_PROGRESS, resultData);
output.write(data, 0, count);
}
// close streams
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Bundle resultData = new Bundle();
resultData.putInt("progress" ,100);
receiver.send(UPDATE_PROGRESS, resultData);
}
}
Add the service to your manifest:
<service android:name=".DownloadService"/>
And the activity will look like this:
// initialize the progress dialog like in the first example
// this is how you fire the downloader
mProgressDialog.show();
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("url", "url of the file to download");
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
startService(intent);
Here is were ResultReceiver comes to play:
private class DownloadReceiver extends ResultReceiver{
public DownloadReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == DownloadService.UPDATE_PROGRESS) {
int progress = resultData.getInt("progress"); //get the progress
dialog.setProgress(progress);
if (progress == 100) {
dialog.dismiss();
}
}
}
}
2.1 Use Groundy library
Groundy is a library that basically helps you run pieces of code in a background service, and it is based on the ResultReceiver concept shown above. This library is deprecated at the moment. This is how the whole code would look like:
The activity where you are showing the dialog...
public class MainActivity extends Activity {
private ProgressDialog mProgressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.btn_download).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String url = ((EditText) findViewById(R.id.edit_url)).getText().toString().trim();
Bundle extras = new Bundler().add(DownloadTask.PARAM_URL, url).build();
Groundy.create(DownloadExample.this, DownloadTask.class)
.receiver(mReceiver)
.params(extras)
.queue();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
});
}
private ResultReceiver mReceiver = new ResultReceiver(new Handler()) {
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
switch (resultCode) {
case Groundy.STATUS_PROGRESS:
mProgressDialog.setProgress(resultData.getInt(Groundy.KEY_PROGRESS));
break;
case Groundy.STATUS_FINISHED:
Toast.makeText(DownloadExample.this, R.string.file_downloaded, Toast.LENGTH_LONG);
mProgressDialog.dismiss();
break;
case Groundy.STATUS_ERROR:
Toast.makeText(DownloadExample.this, resultData.getString(Groundy.KEY_ERROR), Toast.LENGTH_LONG).show();
mProgressDialog.dismiss();
break;
}
}
};
}
A GroundyTask implementation used by Groundy to download the file and show the progress:
public class DownloadTask extends GroundyTask {
public static final String PARAM_URL = "com.groundy.sample.param.url";
#Override
protected boolean doInBackground() {
try {
String url = getParameters().getString(PARAM_URL);
File dest = new File(getContext().getFilesDir(), new File(url).getName());
DownloadUtils.downloadFile(getContext(), url, dest, DownloadUtils.getDownloadListenerForTask(this));
return true;
} catch (Exception pokemon) {
return false;
}
}
}
And just add this to the manifest:
<service android:name="com.codeslap.groundy.GroundyService"/>
It couldn't be easier I think. Just grab the latest jar from Github and you are ready to go. Keep in mind that Groundy's main purpose is to make calls to external REST apis in a background service and post results to the UI with easily. If you are doing something like that in your app, it could be really useful.
2.2 Use https://github.com/koush/ion
Use DownloadManager class (GingerBread and newer only)
=============================================================
GingerBread brought a new feature, DownloadManager, which allows you to download files easily and delegate the hard work of handling threads, streams, etc. to the system.
First, let's see a utility method:
/**
* #param context used to check the device version and DownloadManager information
* #return true if the download manager is available
*/
public static boolean isDownloadManagerAvailable(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
return true;
}
return false;
}
Method's name explains it all. Once you are sure DownloadManager is available, you can do something like this:
String url = "url you want to download";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Some descrition");
request.setTitle("Some title");
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "name-of-the-file.ext");
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
Download progress will be showing in the notification bar.
Final thoughts
First and second methods are just the tip of the iceberg. There are lots of things you have to keep in mind if you want your app to be robust. Here is a brief list:
You must check whether user has an internet connection available
Make sure you have the right permissions (INTERNET and WRITE_EXTERNAL_STORAGE); also ACCESS_NETWORK_STATE if you want to check internet availability.
Make sure the directory were you are going to download files exist and has write permissions.
If download is too big you may want to implement a way to resume the download if previous attempts failed.
Users will be grateful if you allow them to interrupt the download.
Unless you need detailed control of the download process, then consider using DownloadManager (3) because it already handles most of the items listed above.
But also consider that your needs may change. For example, DownloadManager does no response caching. It will blindly download the same big file multiple times. There's no easy way to fix it after the fact. Where if you start with a basic HttpURLConnection (1, 2), then all you need is to add an HttpResponseCache. So the initial effort of learning the basic, standard tools can be a good investment.
This class was deprecated in API level 26. ProgressDialog is a modal
dialog, which prevents the user from interacting with the app. Instead
of using this class, you should use a progress indicator like
ProgressBar, which can be embedded in your app's UI. Alternatively,
you can use a notification to inform the user of the task's progress. For more details Link
Don't forget to add permissions to your manifest file if you're gonna be downloading stuff from the internet!
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloandroid"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:debuggable="true">
</application>
</manifest>
Yes the code above will work .But if you are updating your progressbar in onProgressUpdate of Asynctask and you press back button or finish your activity AsyncTask looses its track with your UI .And when you go back to your activity, even if download is running in background you will see no update on progressbar. So on OnResume() try to run a thread like runOnUIThread with a timer task that updates ur progressbar with values updating from the AsyncTask running background.
private void updateProgressBar(){
Runnable runnable = new updateProgress();
background = new Thread(runnable);
background.start();
}
public class updateProgress implements Runnable {
public void run() {
while(Thread.currentThread()==background)
//while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
Message msg = new Message();
progress = getProgressPercentage();
handler.sendMessage(msg);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
}
}
}
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
progress.setProgress(msg.what);
}
};
Don't forget to Destroy the thread when ur activity is not visible.
private void destroyRunningThreads() {
if (background != null) {
background.interrupt();
background=null;
}
}
I'd recommend you to use my Project Netroid, It's based on Volley. I have added some features to it such as multi-events callback, file download management. This could be of some help.
I have modified AsyncTask class to handle creation of progressDialog at the same context .I think following code will be more reusable.
(it can be called from any activity just pass context,target File,dialog message)
public static class DownloadTask extends AsyncTask<String, Integer, String> {
private ProgressDialog mPDialog;
private Context mContext;
private PowerManager.WakeLock mWakeLock;
private File mTargetFile;
//Constructor parameters :
// #context (current Activity)
// #targetFile (File object to write,it will be overwritten if exist)
// #dialogMessage (message of the ProgresDialog)
public DownloadTask(Context context,File targetFile,String dialogMessage) {
this.mContext = context;
this.mTargetFile = targetFile;
mPDialog = new ProgressDialog(context);
mPDialog.setMessage(dialogMessage);
mPDialog.setIndeterminate(true);
mPDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mPDialog.setCancelable(true);
// reference to instance to use inside listener
final DownloadTask me = this;
mPDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
me.cancel(true);
}
});
Log.i("DownloadTask","Constructor done");
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
Log.i("DownloadTask","Response " + connection.getResponseCode());
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(mTargetFile,false);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
Log.i("DownloadTask","Cancelled");
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mPDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mPDialog.setIndeterminate(false);
mPDialog.setMax(100);
mPDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
Log.i("DownloadTask", "Work Done! PostExecute");
mWakeLock.release();
mPDialog.dismiss();
if (result != null)
Toast.makeText(mContext,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(mContext,"File Downloaded", Toast.LENGTH_SHORT).show();
}
}
Do not forget to replace "/sdcard..." by new File("/mnt/sdcard/...") otherwise you will get a FileNotFoundException
While I was starting to learn android development, I had learnt that ProgressDialog is the way to go. There is the setProgress method of ProgressDialog which can be invoked to update the progress level as the file gets downloaded.
The best I have seen in many apps is that they customize this progress dialog's attributes to give a better look and feel to the progress dialog than the stock version. Good to keeping the user engaged with some animation of like frog, elephant or cute cats/puppies. Any animation with in the progress dialog attracts users and they don't feel like being kept waiting for long.
We can use the coroutine and work manager for downloading files in kotlin.
Add a dependency in build.gradle
implementation "androidx.work:work-runtime-ktx:2.3.0-beta01"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.1"
WorkManager class
import android.content.Context
import android.os.Environment
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import com.sa.chat.utils.Const.BASE_URL_IMAGE
import com.sa.chat.utils.Constants
import kotlinx.coroutines.delay
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.net.URL
class DownloadMediaWorkManager(appContext: Context, workerParams: WorkerParameters)
: CoroutineWorker(appContext, workerParams) {
companion object {
const val WORK_TYPE = "WORK_TYPE"
const val WORK_IN_PROGRESS = "WORK_IN_PROGRESS"
const val WORK_PROGRESS_VALUE = "WORK_PROGRESS_VALUE"
}
override suspend fun doWork(): Result {
val imageUrl = inputData.getString(Constants.WORK_DATA_MEDIA_URL)
val imagePath = downloadMediaFromURL(imageUrl)
return if (!imagePath.isNullOrEmpty()) {
Result.success(workDataOf(Constants.WORK_DATA_MEDIA_URL to imagePath))
} else {
Result.failure()
}
}
private suspend fun downloadMediaFromURL(imageUrl: String?): String? {
val file = File(
getRootFile().path,
"IMG_${System.currentTimeMillis()}.jpeg"
)
val url = URL(BASE_URL_IMAGE + imageUrl)
val connection = url.openConnection()
connection.connect()
val lengthOfFile = connection.contentLength
// download the file
val input = BufferedInputStream(url.openStream(), 8192)
// Output stream
val output = FileOutputStream(file)
val data = ByteArray(1024)
var total: Long = 0
var last = 0
while (true) {
val count = input.read(data)
if (count == -1) break
total += count.toLong()
val progress = (total * 100 / lengthOfFile).toInt()
if (progress % 10 == 0) {
if (last != progress) {
setProgress(workDataOf(WORK_TYPE to WORK_IN_PROGRESS,
WORK_PROGRESS_VALUE to progress))
}
last = progress
delay(50)
}
output.write(data, 0, count)
}
output.flush()
output.close()
input.close()
return file.path
}
private fun getRootFile(): File {
val rootDir = File(Environment.getExternalStorageDirectory().absolutePath + "/AppName")
if (!rootDir.exists()) {
rootDir.mkdir()
}
val dir = File("$rootDir/${Constants.IMAGE_FOLDER}/")
if (!dir.exists()) {
dir.mkdir()
}
return File(dir.absolutePath)
}
}
Start downloading through work manager in activity class
private fun downloadImage(imagePath: String?, id: String) {
val data = workDataOf(WORK_DATA_MEDIA_URL to imagePath)
val downloadImageWorkManager = OneTimeWorkRequestBuilder<DownloadMediaWorkManager>()
.setInputData(data)
.addTag(id)
.build()
WorkManager.getInstance(this).enqueue(downloadImageWorkManager)
WorkManager.getInstance(this).getWorkInfoByIdLiveData(downloadImageWorkManager.id)
.observe(this, Observer { workInfo ->
if (workInfo != null) {
when {
workInfo.state == WorkInfo.State.SUCCEEDED -> {
progressBar?.visibility = View.GONE
ivDownload?.visibility = View.GONE
}
workInfo.state == WorkInfo.State.FAILED || workInfo.state == WorkInfo.State.CANCELLED || workInfo.state == WorkInfo.State.BLOCKED -> {
progressBar?.visibility = View.GONE
ivDownload?.visibility = View.VISIBLE
}
else -> {
if(workInfo.progress.getString(WORK_TYPE) == WORK_IN_PROGRESS){
val progress = workInfo.progress.getInt(WORK_PROGRESS_VALUE, 0)
progressBar?.visibility = View.VISIBLE
progressBar?.progress = progress
ivDownload?.visibility = View.GONE
}
}
}
}
})
}
My personal advice is to use Progress Dialog and build up before execution , or initiate at OnPreExecute() , publish progress often if you use horizontal style of progress bar of the progress dialog. The remaining part is to optimize the algorithm of doInBackground.
Use Android Query library, very cool indeed.You can change it to use ProgressDialog as you see in other examples, this one will show progress view from your layout and hide it after completion.
File target = new File(new File(Environment.getExternalStorageDirectory(), "ApplicationName"), "tmp.pdf");
new AQuery(this).progress(R.id.progress_view).download(_competition.qualificationScoreCardsPdf(), target, new AjaxCallback<File>() {
public void callback(String url, File file, AjaxStatus status) {
if (file != null) {
// do something with file
}
}
});
Permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Using HttpURLConnection
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class DownloadFileUseHttpURLConnection extends Activity {
ProgressBar pb;
Dialog dialog;
int downloadedSize = 0;
int totalSize = 0;
TextView cur_val;
String dwnload_file_path =
"http://coderzheaven.com/sample_folder/sample_file.png";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button) findViewById(R.id.b1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showProgress(dwnload_file_path);
new Thread(new Runnable() {
public void run() {
downloadFile();
}
}).start();
}
});
}
void downloadFile(){
try {
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection)
url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//connect
urlConnection.connect();
//set the path where we want to save the file
File SDCardRoot = Environment.getExternalStorageDirectory();
//create a new file, to save the downloaded file
File file = new File(SDCardRoot,"downloaded_file.png");
FileOutputStream fileOutput = new FileOutputStream(file);
//Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
runOnUiThread(new Runnable() {
public void run() {
pb.setMax(totalSize);
}
});
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
// update the progressbar //
runOnUiThread(new Runnable() {
public void run() {
pb.setProgress(downloadedSize);
float per = ((float)downloadedSize/totalSize) *
100;
cur_val.setText("Downloaded " + downloadedSize +
"KB / " + totalSize + "KB (" + (int)per + "%)" );
}
});
}
//close the output stream when complete //
fileOutput.close();
runOnUiThread(new Runnable() {
public void run() {
// pb.dismiss(); // if you want close it..
}
});
} catch (final MalformedURLException e) {
showError("Error : MalformedURLException " + e);
e.printStackTrace();
} catch (final IOException e) {
showError("Error : IOException " + e);
e.printStackTrace();
}
catch (final Exception e) {
showError("Error : Please check your internet connection " +
e);
}
}
void showError(final String err){
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(DownloadFileDemo1.this, err,
Toast.LENGTH_LONG).show();
}
});
}
void showProgress(String file_path){
dialog = new Dialog(DownloadFileDemo1.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.myprogressdialog);
dialog.setTitle("Download Progress");
TextView text = (TextView) dialog.findViewById(R.id.tv1);
text.setText("Downloading file from ... " + file_path);
cur_val = (TextView) dialog.findViewById(R.id.cur_pg_tv);
cur_val.setText("Starting download...");
dialog.show();
pb = (ProgressBar)dialog.findViewById(R.id.progress_bar);
pb.setProgress(0);
pb.setProgressDrawable(
getResources().getDrawable(R.drawable.green_progress));
}
}
I am adding another answer for other solution I am using now because Android Query is so big and unmaintained to stay healthy. So i moved to this https://github.com/amitshekhariitbhu/Fast-Android-Networking.
AndroidNetworking.download(url,dirPath,fileName).build()
.setDownloadProgressListener(new DownloadProgressListener() {
public void onProgress(long bytesDownloaded, long totalBytes) {
bar.setMax((int) totalBytes);
bar.setProgress((int) bytesDownloaded);
}
}).startDownload(new DownloadListener() {
public void onDownloadComplete() {
...
}
public void onError(ANError error) {
...
}
});
You can observer the progress of the download manager using LiveData and coroutines, see the gist below
https://gist.github.com/FhdAlotaibi/678eb1f4fa94475daf74ac491874fc0e
data class DownloadItem(val bytesDownloadedSoFar: Long = -1, val totalSizeBytes: Long = -1, val status: Int)
class DownloadProgressLiveData(private val application: Application, private val requestId: Long) : LiveData<DownloadItem>(), CoroutineScope {
private val downloadManager by lazy {
application.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
}
private val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
override fun onActive() {
super.onActive()
launch {
while (isActive) {
val query = DownloadManager.Query().setFilterById(requestId)
val cursor = downloadManager.query(query)
if (cursor.moveToFirst()) {
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
Timber.d("Status $status")
when (status) {
DownloadManager.STATUS_SUCCESSFUL,
DownloadManager.STATUS_PENDING,
DownloadManager.STATUS_FAILED,
DownloadManager.STATUS_PAUSED -> postValue(DownloadItem(status = status))
else -> {
val bytesDownloadedSoFar = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
val totalSizeBytes = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
postValue(DownloadItem(bytesDownloadedSoFar.toLong(), totalSizeBytes.toLong(), status))
}
}
if (status == DownloadManager.STATUS_SUCCESSFUL || status == DownloadManager.STATUS_FAILED)
cancel()
} else {
postValue(DownloadItem(status = DownloadManager.STATUS_FAILED))
cancel()
}
cursor.close()
delay(300)
}
}
}
override fun onInactive() {
super.onInactive()
job.cancel()
}
}
Important
AsyncTask is deprecated in Android 11.
For more information please checkout following posts
Android AsyncTask API deprecating in Android 11.What are the alternatives?
https://developer.android.com/reference/android/os/AsyncTask
Probably should move to concorency Framework as suggested by google
private class DownloadTask extends AsyncTask<String, Integer, String> {
private PowerManager.WakeLock mWakeLock;
String onlinePathBundle, onlinePathMusic, offlinePathBundle, offlinePathMusic;
CircleProgressBar progressBar;
RelativeLayout rl_progress;
ImageView btn_download;
TextView tv_progress;
public DownloadTask(String onlinePathBundle, String onlinePathMusic, String offlinePathBundle, String offlinePathMusic, CircleProgressBar progressBar, RelativeLayout rl_progress, ImageView btn_download,
TextView tv_progress) {
this.offlinePathBundle = offlinePathBundle;
this.offlinePathMusic = offlinePathMusic;
this.progressBar = progressBar;
this.rl_progress = rl_progress;
this.btn_download = btn_download;
this.tv_progress = tv_progress;
this.onlinePathBundle = onlinePathBundle;
this.onlinePathMusic = onlinePathMusic;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setMax(100);
rl_progress.setVisibility(View.VISIBLE);
btn_download.setVisibility(View.GONE);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
mWakeLock.acquire();
}
#Override
protected String doInBackground(String... sUrl) {
String firstResult = downTask(onlinePathBundle, 1, offlinePathBundle);
String seondResult = downTask(onlinePathMusic, 2, offlinePathMusic);
if (firstResult != null) {
Toast.makeText(SplashActivity.this, "Download error: " + firstResult, Toast.LENGTH_LONG).show();
return firstResult;
} else {
return seondResult;
}
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
progressBar.setProgress(progress[0]);
tv_progress.setText(progress[0] + "%");
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
rl_progress.setVisibility(View.GONE);
btn_download.setVisibility(View.VISIBLE);
if (result != null) {
Toast.makeText(SplashActivity.this, "Download error: " + result, Toast.LENGTH_LONG).show();
} else {
rl_progress.setVisibility(View.GONE);
btn_download.setVisibility(View.GONE);
}
}
public String downTask(String onlineNewPath, int numberOfTask, String offlineNewPath) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(onlineNewPath);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(offlineNewPath);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) {// only if total length is known
if (numberOfTask == 1) {
publishProgress((int) (total * 50 / fileLength));
} else if (numberOfTask == 2) {
publishProgress(((int) (total * 50 / fileLength)) + 50);
}
}
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
}
I have came across a Simple File Download library
Fetch and importantly it has Storage Access Framework, Content Provider and URI support. If anyone is still searching might found it helpful.
implementation "androidx.tonyodev.fetch2:xfetch2:3.1.6" //AndroidX
implementation "com.tonyodev.fetch2:fetch2:3.0.12" //Support lib
Required permissions in case your are not using app specific directory.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Internet permission
<uses-permission android:name="android.permission.INTERNET"/>
private Fetch fetch;
FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
.setDownloadConcurrentLimit(3)//Concurrent Download limit
.build();
fetch = Fetch.Impl.getInstance(fetchConfiguration);
String url = "http:www.example.com/test.txt";//URL of file
String file = "/downloads/test.txt";//Path of file
final Request request = new Request(url, file);
request.setPriority(Priority.HIGH);
request.setNetworkType(NetworkType.ALL);//Preferred network type
request.addHeader("clientKey", "SD78DF93_3947&MVNGHE1WONG");//Auth header if any
fetch.enqueue(request, updatedRequest -> {
//Request was successfully enqueued for download.
}, error -> {
//An error occurred enqueuing the request.
});
}
Listen for update and progress
FetchListener fetchListener = new FetchListener() {
#Override
public void onQueued(#NotNull Download download, boolean waitingOnNetwork) {
if (request.getId() == download.getId()) {
showDownloadInList(download);
}
}
#Override
public void onCompleted(#NotNull Download download) {
}
#Override
public void onError(#NotNull Download download) {
Error error = download.getError();
}
#Override
public void onProgress(#NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
if (request.getId() == download.getId()) {
updateDownload(download, etaInMilliSeconds);
}
int progress = download.getProgress();
}
#Override
public void onPaused(#NotNull Download download) {
}
#Override
public void onResumed(#NotNull Download download) {
}
#Override
public void onCancelled(#NotNull Download download) {
}
#Override
public void onRemoved(#NotNull Download download) {
}
#Override
public void onDeleted(#NotNull Download download) {
}
};
fetch.addListener(fetchListener);
//Remove listener when done.
fetch.removeListener(fetchListener);
This example code is taken from the owner page all credit goes to Tonyo Francis

Multiple asynchronous tasks in Android App

I have a strange problem. I'm developing an Android app which has 3 independent Async Tasks. When I try to run the app on a quad core phone there is no problem. But if I try to run the app on a dual core phone app crashes. How can I modify my tasks for dual core phones ?
Here is my code
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
This is the first async task. The second one is the Parse.com file upload async saveInBackground method.
public void startUpload(String fileName) {
try {
photoFile = new ParseFile(fileName, scaledData);
if (isTac) {
pictures.setPhotoFileTac(photoFile);
} else if (isCanak) {
pictures.setPhotoFileCanak(photoFile);
} else if (isYaprak) {
pictures.setPhotoFileYaprak(photoFile);
}
// pictures.save();// Telefon çekirdeğine göre 2 asenkron methodu desteklemiyor o yüzden sadece save yazılabilir fakat başarılı kontolü SaveCallback' te yakalanamaz.
pictures.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e == null){
Toast.makeText(getApplicationContext(),"Buluta yükleme başarılı. " , Toast.LENGTH_LONG).show();
if(pdialog != null)
{
pdialog.dismiss();//Eğer işlem başarılı ise asenkron sınıfta yaratılan progressbar ı kapat.
}
}
else{
Toast.makeText(getApplicationContext(),"Hata" +e.toString(),Toast.LENGTH_LONG).show();
}
}
});
}
catch (Exception ex)
{
Toast.makeText(getApplicationContext(),"Bağlantı Hatası !",Toast.LENGTH_LONG).show();
}
}
And the third one is the progress bar of upload process.
public class AsyncUpload extends AsyncTask<String,Void,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pdialog = new ProgressDialog(TakePictureActivity.this);
pdialog.setMessage("Yükleniyor...");
pdialog.setIndeterminate(false);
pdialog.setCancelable(false);
pdialog.show();
}
#Override
protected String doInBackground(String... fileNames) {
return fileNames[0];
}
#Override
protected void onPostExecute(String name) {
startUpload(name);
super.onPostExecute(name);
}
}
And there is the code where I initialize upload session. (In if - else condition states the line new AsyncUpload().execute(fileName);
private void saveScaledPhoto(byte[] data) {
// Resize photo from camera byte array
pictureWidth = camera.getParameters().getPictureSize().width;
pictureHeight = camera.getParameters().getPictureSize().height;
Bitmap plantImage = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap plantImageScaled = Bitmap.createScaledBitmap(plantImage, pictureWidth, pictureHeight, false);
pictureCache = new PictureCache();
// Override Android default landscape orientation and save portrait
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedScaledPlantImage = Bitmap.createBitmap(plantImageScaled, 0,
0, plantImageScaled.getWidth(), plantImageScaled.getHeight(),
matrix, true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
rotatedScaledPlantImage.compress(Bitmap.CompressFormat.PNG, 100, bos);
scaledData = bos.toByteArray();
AlertDialog.Builder aDB = new AlertDialog.Builder(this);
aDB.setCancelable(false);
aDB.setTitle("Emin misiniz ?");
aDB.setMessage("Çektiğiniz resim analizde kullanılacaktır. Devam etmek istiyor musunuz ?.. ");
aDB.setPositiveButton("Evet", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (isTac) {
pictureCache.setByteArrayTac(scaledData);
isTac = false;
isCanak = true;
Toast.makeText(getApplicationContext(), "Taç yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "TacYaprak";
new AsyncUpload().execute(fileName);
} else if (isCanak) {
pictureCache.setByteArrayCanak(scaledData);
isCanak = false;
isYaprak = true;
Toast.makeText(getApplicationContext(), "Çanak yaprak görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "CanakYaprak";
new AsyncUpload().execute(fileName);
} else if (isYaprak) {
String plantTag = "A_Y";
pictureCache.setByteArrayYaprak(scaledData);
isYaprak = false;
Toast.makeText(getApplicationContext(), "Ağaç yaprağı görüntüsü alındı.", Toast.LENGTH_LONG).show();
String currentTimeStamp = getCurrentTimeStamp();
fileName = "AgacYapragi";
new AsyncUpload().execute(fileName);
}
if (!isTac && !isCanak && !isYaprak) {
finish();
}
}
});
aDB.setNegativeButton("Hayır", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDialog = aDB.create();
alertDialog.show();
}
Here is the logcat output..
java.lang.NullPointerException
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:482)
at com.altygtsoft.biomatch.TakePictureActivity.saveScaledPhoto(TakePictureActivity.java:202)
at com.altygtsoft.biomatch.TakePictureActivity.access$000(TakePictureActivity.java:45)
at com.altygtsoft.biomatch.TakePictureActivity$2$1$2.onPictureTaken(TakePictureActivity.java:147)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:855)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5371)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Just realized my idea is too big for a comment so->
What happens if you do the following?
//Beware pseudo-code
new AsyncTask<>({
onPreExecute(){
//keep your code from before
...
}
doInBackground(Params... params){
startUpload(params[0], params[1]); //minus the done() function, plus pictures?
}
onPostExecute(){
//As I'm not sure where it fits in, if possible execute done() here.
}
}).execute(fileName, pictures); //couldn't find the decleration of pictures, so I stole the decleration of independence instead. Also maybe you need to put pictures in there, depending on where it is and how public/static.

Downloading not stops on AsynchTask even on pressing the back button

I am downloading pdf file in AsynchTask, so as it downloading the file, my progress dialog is getting update. However Problem is that if i press the back button than my alert box gets pop up and the downloading gets stop in background. I want that it should continue its downloading even after alert dialog gets called or pause the download once alert gets pop up and continue downloading once if i click the cancel button of alert dialog.
Here is a snippet,
#Override
protected Dialog onCreateDialog(int id)
{
switch (id)
{
case progress_bar_type:
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
pDialog.setOnKeyListener(new DialogInterface.OnKeyListener()
{
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
running = false;
AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
AlertDialog.setIcon(R.drawable.ic_launcher);
alertDialog.setTitle("Ariisto");
alertDialog.setMessage("Do you Want to Cancel the Download ?");
alertDialog.setCancelable(true);
alertDialog.setPositiveButton("YES", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// TODO Auto-generated method stub
File externalFile = new File(Environment.getExternalStorageDirectory(),"downloadedfile.pdf");
externalFile.delete();
pDialog.dismiss();
running = false;
Log.d("External File", "DELETED");
pDialog.setProgress(0);
count = 2;
}
});
alertDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
new DownloadFileFromURL().execute(file_url);
running = true;
count = 0;
}
});
AlertDialog alert = alertDialog.create();
alert.show();
}
return false;
}
});
return pDialog;
default:
return null;
}
}
class DownloadFileFromURL extends AsyncTask<String, String, String>
{
/**
* Before starting background thread
* Show Progress Bar Dialog
* */
#SuppressWarnings("deprecation")
protected void onPreExecute()
{
super.onPreExecute();
showDialog(progress_bar_type);
publishProgress(""+(int)(0));
running = true;
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
Log.d("------------","iNSIDE ON CANCELLED METHOD");
super.onCancelled();
}
#Override
protected String doInBackground(String... file_url)
{
// TODO Auto-generated method stub
int count;
try
{
URL url = new URL(file_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// getting file length
int lenghtOfFile = connection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
FileOutputStream output = new FileOutputStream("/sdcard/downloadedfile.pdf");
byte data[] = new byte[1024];
long total = 0;
while ( ((count = input.read(data)) != -1) && (running == true) )
{
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress(""+(int)((total*100)/lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
output.flush();
// closing streams
output.close();
input.close();
}
catch (Exception e)
{
Log.e("Error: ", " "+e.getMessage());
}
return null;
}
protected void onProgressUpdate(String... progress)
{
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
#SuppressWarnings("deprecation")
protected void onPostExecute(String file_url)
{
// dismiss the dialog after the file was downloaded
if(running == true){
dismissDialog(progress_bar_type);
// Displaying downloaded image into image view
// Reading image path from sdcard
String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.pdf";
// setting downloaded into image view
Log.d(imagePath, "show file");
File file = new File(Environment.getExternalStorageDirectory(),"downloadedfile.pdf");
Uri external = Uri.fromFile(file);
viewPdf(external);
}
}
}
I have a requirement very similar to this. A user will click on a listItem and an AsyncTask will start downloading it, and then displays it when done. Should the user tap the back-button before the download is complete, an alert dialog is displayed asking whether to abort the download. Should the download complete WHILE that dialog is displayed, it simply dismisses the dialog and finishes that activity. I don't have time to pull and sanitize the code, but the pattern is as follows:
The activity has two private fields:
private DownloadTask downloader = null;
private AlertDialog dlgCancel = null;
in onBackPressed:
if( downloader != null ) {
dlgCancel =....
dlgCancel.show();
} else
finish();
in the DownloadTask's onPostExecute:
if( isCancelled() ) {
... dismiss the download
} else {
if( dlgCancel == null ) {
... handle the download here ...
} else {
dlgCancel.dismiss();
dlgCancel = null;
Activity.finish();
}
}
and finally, in the onClick for the Abort-Download button:
downloader.cancel( true );
Activity.finish();
Note that you'll need to watch for isCancelled() in your AsyncTask's doInBackground() so that you can react as quickly as possible. Some operations won't return immediately.

How to implement the Progress dialog for this code?

I my application i am going to implement the Progress dialog till its getting loading. . .
The code is like:
copyFileFromAssetsToSDCard("Alone.mp4");
intent = new Intent(this,VideoPlayerController.class);
startActivity(intent);
So how to implement it ??
Thanks.
Code for the function is:
public void copyFileFromAssetsToSDCard(String fileFromAssets){
AssetManager is = this.getAssets();
InputStream fis;
try {
fis = is.open(fileFromAssets);
FileOutputStream fos;
fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), fileFromAssets));
byte[] b = new byte[8];
int i;
while ((i = fis.read(b)) != -1) {
fos.write(b, 0, i);
}
fos.flush();
fos.close();
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public class MainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new progressTask().execute("");
}
public void copyFileFromAssetsToSDCard(String fileFromAssets){
AssetManager is = this.getAssets();
InputStream fis;
try {
fis = is.open(fileFromAssets);
FileOutputStream fos;
fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), fileFromAssets));
byte[] b = new byte[8];
int i;
while ((i = fis.read(b)) != -1) {
fos.write(b, 0, i);
}
fos.flush();
fos.close();
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
private class progressTask extends AsyncTask<String, Void, Void> {
ProgressDialog pd = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
pd.show();
}
protected Long doInBackground(String... params) {
copyFileFromAssetsToSDCard("Alone.mp4");
}
protected void onPostExecute(Void result) {
pd.dismiss();
}
}
}
I have made a arrangement of your all tasks together. Try it. Hope it will help you out.
You can do like this,
Create an ArrayList<String> files = new ArrayList<String>(); and add all the files that you can to copy to SDCard like the below.
files.add("test.png");
files.add("icon.png");
new myAsyncTask().execute(files);
Then you can just use this ArrayList object to pass to AsynTask and get it done.
private class myAsyncTask extends AsyncTask<ArrayList<String>, Void, Void>
{
ArrayList<String> files;
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(mainact.this, "Loading...", "");
}
#Override
protected Void doInBackground(ArrayList<String>... params) {
files = params[0];
for (int i = 0; i < files.size(); i++) {
copyFileFromAssetsToSDCard(files.get(i));
}
return null;
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
}
}
try to move the copy code to a thread and show the dialog, and after thread ends, remove the dialog launch the new activity.
Something like this :
showDialog(10);//10 is the dialog id
new Thread(new Runnable(){
public void run(){
copyFileFromAssetsToSDCard("Alone.mp4");
handler.sendEmptyMessage(1);
}
}).start();
Make a handler to receive the message:
Handler handler=new Handler(){
void handleMessage(Message msg){
switch(msg.what){
case 1:
removeDialog(10);
intent = new Intent(this,VideoPlayerController.class);
startActivity(intent);
break;
}
};
};
try this code for Displaying Progress Dialog Box,
ProgressDialog progDailog = ProgressDialog.show(this,"Process ", "please wait....",false,true);
new Thread ( new Runnable()
{
public void run()
{
// Put Intent your code here
}
}
I think you want to implement Copy operation in background thread(during that you want to display progress bar or dialog) and once copy operation is completed then you want to start another activity, if this is the case then i would suggest you to implement AsyncTask and this is the best practice to implement threading process in Android i think, because we developer don't need to take care about Thread Management if we have implemented this AsyncTask.
For your case:
private class myBackgroundTask extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute()
{
// Show Progress bar or dialog
}
protected Long doInBackground(Void... void) {
// write your Copy from Assets to SDcard code here
}
protected void onPostExecute(Long result)
{
if(dialog.isShowing()) // if progress dialog is showing
{
dialog.dismiss();
}
// And now Write Start Activity code here
}
}
Update:
FYI, just a quick update AsyncTask is known as Painless Threading in Android, go through this article and i am sure you will sure come to know about the importance of this concept as compared to general threading implementation.

Categories

Resources