My code:
private class selectBookInAutor extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
arr_book_title.clear();
arr_book_href.clear();
mProgressDialog = new ProgressDialog(_context);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... params) {
Document doc = null;
StringBuilder sb = new StringBuilder();
try {
doc = Jsoup.connect(params[0]).userAgent("Mozilla").get();
Elements links = doc.select("li>a");
for (Element link : links) {
sb.append(link.text());
arr_book_title.add(link.text());
arr_book_href.add(Jsoup.clean(link.attr("abs:href"), Whitelist.basic()));
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
#Override
protected void onPostExecute(String result) {
if (result != ""){
final CharSequence[] items = arr_book_title.toArray(new CharSequence[arr_book_title.size()]);
final ArrayList seletedItems = new ArrayList();
AlertDialog.Builder builder = new AlertDialog.Builder(_context);
builder.setTitle("Select The Difficulty Level");
builder.setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) {
if (isChecked) {
seletedItems.add(indexSelected);
}else if(seletedItems.contains(indexSelected)){
seletedItems.remove(Integer.valueOf(indexSelected));
}
}
}).setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
for (Object s : seletedItems){
String[] separated = selGroupParam.split(";");
String _idautor = separated[0].toString();
long id_book = db.insertBOOK(_idautor, arr_book_href.get(Integer.valueOf(s.toString())).toString(), "", arr_book_title.get(Integer.valueOf(s.toString())).toString());
new **saveBookInAutor().execute(arr_book_href.get(Integer.valueOf(s.toString())).toString(), _idautor, String.valueOf(id_book));**
}
refreshList();
}
}).setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
}).create().show();
}else{
Toast.makeText(_context, "Error", Toast.LENGTH_SHORT).show();
}
mProgressDialog.dismiss();
}
}
private class saveBookInAutor extends AsyncTask<String, Void, String> {
String _idautor, _idbook;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog2 = new ProgressDialog(_context);
mProgressDialog2.setMessage("Save to file");
mProgressDialog2.setIndeterminate(false);
mProgressDialog2.show();
}
#Override
protected String doInBackground(String... params) {
Document doc = null;
String _html = "";
_idautor = params[1];
_idbook = params[2];
try {
doc = Jsoup.connect(params[0]).userAgent("Mozilla").get();
_html = doc.select("dd").outerHtml();
} catch (IOException e) {
e.printStackTrace();
}
return Jsoup.clean(_html, Whitelist.basic());
}
#Override
protected void onPostExecute(String result) {
if (result != ""){
Toast.makeText(_context, "Save file", Toast.LENGTH_SHORT).show();
String html = "<html lang='ru'><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head><body>"+result+"</body></html>";
//String html = result;
**savePageToFile(_idautor + "_" + String.valueOf(_idbook), html);**
}else{
Toast.makeText(_context, "Error", Toast.LENGTH_SHORT).show();
}
mProgressDialog2.dismiss();
}
}
public void refreshList() {
Intent intent = new Intent(_context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
_context.startActivity(intent);
}
public void savePageToFile(String filename, String html) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(_context.openFileOutput(filename, Context.MODE_PRIVATE));
outputStreamWriter.write(html);
outputStreamWriter.close();
}
catch (IOException e) {
//Log.e("Exception", "File write failed: " + e.toString());
}
}
When you select a page and clicking "Ok" ProgressDialog mProgressDialog2 opens and displays just a 1 second. Because of this, I do not see the download Page or not.
How to make mProgressDialog2 displayed all the while to save the page as a file?
Thank you!
UPD
What i want is :
Start mProgressDialog.
After downloading the page disappears and AlertDialog comes with the question what to choose.
After choosing, mProgressDialog2 should be displayed as long as it downloads and saves the file in the webpage.
However mProgressDialog2 disappears in 1 second, and process of saving the file goes on in silence.
In your onPostExecute method, you unconditionally call
mProgressDialog2.dismiss();
This is closing the dialog immediately after it is displayed. That call should be moved to the handler code for each of the buttons. (i.e.the onClick method for the positive and negative buttons)
in onPostExecute(), compare Strings like
if(!result.equals(""))
and try once.
use equals() method for String comparisons.
Related
I am uploading some file to server using AsyncTask and I want to show a progress dialog in AsyncTask.
My AsyncTask is working fine and executing all the steps, but it never shows the dialog.I don't know what I have done wrong.
I have written below code but not working. Can someone help please!!!
Activity:
public class MainActivity extends AppCompatActivity {
ImageView videoImage ;
EditText editTextVideoTitle;
EditText editTextVideoDescription;
Button btnPostButton;
Button btnCancelButton;
private String mVideoPath;
private String mVideoThumb;
String strVideoTitle;
String strVideoDescription;
boolean videoPosted;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_vid_with_desc);
editTextVideoTitle = (EditText) findViewById(R.id.videoTitle);
editTextVideoDescription = (EditText) findViewById(R.id.videoDescription);
btnPostButton = (Button) findViewById(R.id.postButton);
btnCancelButton = (Button) findViewById(R.id.cancelButton);;
mVideoPath = getIntent().getStringExtra("path");
mVideoThumb = getIntent().getStringExtra("thumb");
btnPostButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videoPosted = postVideo();
if (videoPosted) {
Toast.makeText(getApplicationContext(), "Your video posted successfully.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Error in posting video, please try again.", Toast.LENGTH_SHORT).show();
}
}
});
}
public boolean postVideo() {
Log.i("Info", "PostVidWithDescActivity : postVideo : Start");
String strUserId = "";
String strReservedfield = "";
boolean isVideoPosted = false;
sharedPreferences = this.getSharedPreferences("com.app.rapid", Context.MODE_PRIVATE);
strVideoTitle = editTextVideoTitle.getText().toString();
strVideoDescription = editTextVideoDescription.getText().toString();
try {
strUserId = sharedPreferences.getString("userId", "");
strReservedfield = "ReservedField";
outputData = new PostToServerAsyncTask().execute(mVideoPath, strUserId, strVideoTitle, strVideoDescription, strReservedfield).get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
if (null != outputData && outputData.equalsIgnoreCase("200")) {
isVideoPosted = true;
} else{
isVideoPosted = false;
}
return isVideoPosted;
}
private class PostToServerAsyncTask extends AsyncTask<String, Void, String> {
private String content;
private String Error = null;
private int serverResponseCode;
Context context;
ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("inputBuilder","PostToServerAsyncTask : onPreExecute Start") ;
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.setIndeterminate(false);
//progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.YELLOW));
progressDialog.setCancelable(false);
progressDialog.show();
Log.i("inputBuilder","PostToServerAsyncTask : onPreExecute End") ;
}
#Override
protected String doInBackground(String... inputData) {
/*
File upload code
*/
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Some string";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("inputBuilder","PostToServerAsyncTask : onPostExecute Start") ;
if (null != progressDialog && progressDialog.isShowing()) {
progressDialog.dismiss();
}
Log.i("inputBuilder","PostToServerAsyncTask : onPostExecute End") ;
}
}
}
Could you please try this?
#Override
protected void onPreExecute() {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.setIndeterminate(false);
//progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.YELLOW));
progressDialog.setCancelable(false);
progressDialog.show();
});
}
I think the general problem is in async task, which actually is on the separate thread
I have a GoogleTranslate.java file that has a class, GoogleTranslate, that extends AsyncTask. The purpose of this task is to perform Google translations.
I have another class, MyVocab, that allows the user to input a word to translate in an alert dialog. So on a click to the alert dialog button, the word will be translated to the desired language by calling on the GoogleTranslate class. However, when I pass a progress bar from MyVocab to GoogleTranslate it doesn't work. When the operation is running (for an observable amount of time), the progress bar doesn't show. I set the progress bar as VISIBLE in onPreExecute and set it as GONE in onPostExecute.
I'm wondering if it's because I have GoogleTranslate and MyVocab in two different java files since most of the examples I see have async class and the class that calls it in the same java file. Please let me know if there's anything I'm doing wrong that's causing this problem.
Here's the related code:
GoogleTranslate.java
public class GoogleTranslate extends AsyncTask<String, Void, String>{
private ProgressBar mProgressBar;
public GoogleTranslate(ProgressBar progressBar) {
super();
mProgressBar = progressBar;
}
#Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(String s) {
mProgressBar.setVisibility(View.GONE);
}
#Override
protected String doInBackground(String... params) {
String vocab = params[0];
String source = params[1];
String target = params[2];
String sourceQuery = "";
String targetQuery = "&target=" + target;
// "" means its
if (!source.equals("Detect Language")) {
sourceQuery = "&source=" + source;
}
try {
String APIKey = "MY_API_KEY";
String encodedQuery = URLEncoder.encode(vocab, "UTF-8");
URL url = new URL("https://www.googleapis.com/language/translate/v2?key=" +
APIKey +
"&q=" +
encodedQuery +
sourceQuery +
targetQuery);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
}
finally {
urlConnection.disconnect();
}
}
catch (Exception e) {
return null;
}
}
}
Parts of method from MyVocab:
protected void addVocabAlertDialog(final VocabDbHelper dbHelper, final String category,
final VocabCursorAdapter cursorAdapter) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add Vocab");
LayoutInflater li = LayoutInflater.from(CategoryItem.this);
View promptsView = li.inflate(R.layout.alert_dialog_add_vocab, null);
final EditText vocabInput = (EditText) promptsView.findViewById(R.id.vocabInput);
final EditText definitionInput = (EditText) promptsView.findViewById(R.id.definitionInput);
final ProgressBar progressBar = (ProgressBar) promptsView.findViewById(R.id.progressBar);
builder.setView(promptsView);
final GoogleTranslate googleTranslate = new GoogleTranslate(progressBar);
// Set up the buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String vocab = vocabInput.getText().toString();
String definition = definitionInput.getText().toString();
dbHelper.insertVocab(category, vocab, definition, 0);
if (!category.equals(VocabDbContract.CATEGORY_NAME_MY_WORD_BANK)) {
dbHelper.insertVocab(VocabDbContract.CATEGORY_NAME_MY_WORD_BANK, vocab, definition, 0);
}
// Update Cursor
Cursor cursor = dbHelper.getVocabCursor(category);
cursorAdapter.changeCursor(cursor);
}
});
final AlertDialog dialog = builder.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String vocab = vocabInput.getText().toString();
SharedPreferences sharedPreferences = getSharedPreferences("Translation", MODE_PRIVATE);
int sourcePos = sharedPreferences.getInt("Source", 0); // 0 is for Detect Language
int targetPos = sharedPreferences.getInt("Target", 19); // 19 is for English
String source = LanguageOptions.FROM_LANGUAGE_CODE[sourcePos];
String target = LanguageOptions.TO_LANGUAGE_CODE[targetPos];
final AlertDialog.Builder builder = new AlertDialog.Builder(CategoryItem.this);
builder.setMessage("Network is unavailable. Please try again later.");
builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog dialog = builder.create();
if (isNetworkAvailable()) {
AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab, source, target);
try {
String translatedJSON = asyncTask.get();
JSONParser jsonParser = new JSONParser();
String translatedText = jsonParser.parseJSONForTranslation(translatedJSON);
definitionInput.setText(translatedText);
} catch (Exception e) {
dialog.show();
}
}
else {
dialog.show();
}
}
});
}
XML file that contains progress bar:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Vocab"
android:id="#+id/vocabInput"
android:inputType="textAutoComplete"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Definition"
android:id="#+id/definitionInput"
android:inputType="textAutoComplete"
android:layout_below="#+id/vocabInput"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"
android:indeterminate="true"
android:id="#+id/progressBar"/>
I'd suggest using ProgressDialog instead.
I switched from ProgressBar because I faced a similar issue, even after programmatically creating one in the default constructor of my AsyncTask.
public class GoogleTranslate extends AsyncTask<String, Void, String> {
private ProgressDialog mProgressDialog;
private Context mContext;
public GoogleTranslate(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(
mContext,
"Please wait", // Title
"Translating", // Message
true // Indeteriminate flag
);
}
#Override
protected String doInBackground(String... params) {
...
}
#Override
protected void onPostExecute(String s) {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
}
...
}
}
Call this AsyncTask like this:
new GoogleTranslate(getActivity() /* or getContext() */).execute(vocab, source, target);
Try to avoid the AsyncTask get() method and use a listener instead.
You should update your code this way:
1) In your googleTranslate class, add a listener:
private Listener listener;
public interface Listener{
void onTaskResult(String string);
}
public void setListener(Listener listener){
this.listener = listener;
}
and call it in your onPostExecute:
#Override
protected void onPostExecute(String s) {
if (listener!=null){ listener.onTaskResult(s); }
mProgressBar.setVisibility(View.GONE);
}
2) update your main class replacing the get with the listener management, replacing this:
AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab, source, target);
try {
String translatedJSON = asyncTask.get();
JSONParser jsonParser = new JSONParser();
String translatedText = jsonParser.parseJSONForTranslation(translatedJSON);
definitionInput.setText(translatedText);
} catch (Exception e) {
dialog.show();
}
with this:
googleTranslate.setListener(new GoogleTranslate.Listener() {
#Override
public void onTaskResult(String string) {
String translatedJSON = string;
JSONParser jsonParser = new JSONParser();
String translatedText = jsonParser.parseJSONForTranslation(translatedJSON);
definitionInput.setText(translatedText);
}
});
googleTranslate.execute(vocab, source, target);
I hope it helped.
add this before executing the googleTranslate :
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
AsyncTask<String, Void, String> asyncTask = googleTranslate.execute(vocab,source, target);
and also implement the onProgressUpdate in googleTranslate.
this link may help :
http://www.concretepage.com/android/android-asynctask-example-with-progress-bar
Try passing ProgressBar as constructor argument of GoogleTranslate class.
Add progress bar in your onPreExecute method and hide it in onPostExecute.
private class MyAsyncThread extends AsyncTask<Void, Void, String>
{
#SuppressWarnings("finally")
#Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
// your code
}
catch (Exception e) {
// TODO: handle exception
}
finally
{
return "OK";
}
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(this, null, "Please wait....");
}
That's because you are blocking Main Thread by asyncTask.get() call, so no UI operations can run until asyncTask completes.
Remove this call and process the asyncTask's results in its onPostExecute(String s) and onCancelled() callbacks instead.
I have an AlertDialog builder in class. I am setting some message into it which comes from reading a file. Earlier as file text wasn't too large it use to load easily, now since the text has grown more it takes a time to load dialog and blocks UI. How can i run this in thread ?
Edited code :
public class Eula TaskCompleteListner{ {
static interface OnEulaAgreedTo {
void onEulaAgreedTo();
}
public static boolean show(final Activity activity,final Context context,final Boolean flag) {
final Preferences prefs = Preferences.getInstance();
Log.d(TAG, "insideEula");
if (!prefs.getEulaStatus(context)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(
activity);
Log.d(TAG, "insideEulaLaunch");
builder.setTitle(R.string.eula_title);
builder.setCancelable(true);
builder.setPositiveButton(R.string.eula_accept,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
prefs.setEulaStatus(context, true);
if (activity instanceof OnEulaAgreedTo) {
((OnEulaAgreedTo) activity).onEulaAgreedTo();
}
}
});
builder.setNegativeButton(R.string.eula_refuse,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
refuse(activity);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
refuse(activity);
}
});
MyAsync async= new MyAsync(activity, new TaskCompleteListner() {
public boolean onComplete(String result) {
builder.setMessage(data);
builder.create().show();
return false;
}
}) ;
MyAsync async= new MyAsync(this, activity) ;
async.excecute();
//builder.setMessage(readEula(activity)); //READING FILE AND SETTING HERE
//builder.create().show();
return false;
}
return true;
}
private static void refuse(Activity activity) {
activity.finish();
}
#Override
public boolean onComplete(String result) {
// TODO Auto-generated method stub
builder.setMessage(readEula(activity)); //READING FILE AND SETTING HERE
builder.create().show();
return false;
}
Async Task Class
public class MyAsync extends AsyncTask<Void, Void, String>{
public static final String ASSET_EULA = "EULA";
TaskCompleteListner taskCompleteListner;
Activity activity;
public interface TaskCompleteListner{
public boolean onComplete(String result);
}
public MyAsync(TaskCompleteListner taskCompleteListner,Activity activity) {
this.taskCompleteListner = taskCompleteListner;
this.activity=activity;
}
#Override
protected String doInBackground(Void... params) {
String data=(String)readEula(activity);
return data;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
taskCompleteListner.onComplete(result);
}
private static CharSequence readEula(Activity activity) { //READING FILE HERE
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(activity.getAssets().open(ASSET_EULA)));
String line;
StringBuilder buffer = new StringBuilder();
while ((line = in.readLine()) != null)
buffer.append(line).append('\n');
byte[] latin1 = buffer.toString().getBytes("ISO-8859-1");
return new String(latin1);
//return buffer;
} catch (IOException e) {
return "";
} finally {
closeStream(in);
}
}
private static void closeStream(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// Ignore
}
}
}
}
You can use AsyncTask class, where you read your data in doInBackground() return the CharSequence and do the dialog.show() in onPostExecute().
EDIT:
heres what you can do,
create a class
private static class MyAsyncClass extends AsyncTask<Void,Void,CharSequence > {
Activity activity;
ProgressDialog dialog
public MyAsyncClass(Activity activity){
this.activity = activity;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(activity);
dialog.setMessage("Reading data");
dialog.setCancelable(false);
dialog.show();
}
#Override
protected CharSequence doInBackground(Void... params) {
return readEula(activity);
}
protected void onPostExecute(CharSequence data) {
if(dialog!=null && dialog.isShowing())
dialog.dismiss();
final AlertDialog.Builder builder = new AlertDialog.Builder(
activity);
Log.d(TAG, "insideEulaLaunch");
builder.setTitle(R.string.eula_title);
builder.setCancelable(true);
builder.setPositiveButton(R.string.eula_accept,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
prefs.setEulaStatus(context, true);
if (activity instanceof OnEulaAgreedTo) {
((OnEulaAgreedTo) activity).onEulaAgreedTo();
}
}
});
builder.setNegativeButton(R.string.eula_refuse,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
refuse(activity);
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
refuse(activity);
}
});
builder.setMessage(data);
builder.create().show();
}
}
then call this class as,
if (!prefs.getEulaStatus(context)) {
MyAsyncClass myAsyncClass = new MyAsyncClass(activity);
myAsyncClass.execute();
}
Correction to your Edit:
in your Eula class,
change this,
MyAsync async= new MyAsync(activity, new TaskCompleteListner() {
public boolean onComplete(String result) {
builder.setMessage(data);
builder.create().show();
return false;
}
}) ;
MyAsync async= new MyAsync(this, activity) ;
async.excecute();
to this,
MyAsync async= new MyAsync(activity, new TaskCompleteListner() {
public boolean onComplete(String result) {
builder.setMessage(data);
builder.create().show();
return false;
}
}) ;
async.excecute();
in your Async class,
change your constructor to,
public MyAsync(Activity activity, TaskCompleteListner taskCompleteListner) {
this.taskCompleteListner = taskCompleteListner;
this.activity=activity;
}
Use this Async Class to get the text
public class MyAsync extends AsyncTask<Void, Void, String>{
TaskCompleteListner taskCompleteListner;
Activity activity;
public interface TaskCompleteListner{
public boolean onComplete(String result);
}
public MyAsync(TaskCompleteListner taskCompleteListner,Activity activity) {
this.taskCompleteListner = taskCompleteListner;
this.activity=activity;
}
#Override
protected String doInBackground(Void... params) {
String data=(String) readEula(activity);
return data;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
taskCompleteListner.onComplete(result);
}
private static CharSequence readEula(Activity activity) { //READING FILE HERE
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(activity.getAssets().open(ASSET_EULA)));
String line;
StringBuilder buffer = new StringBuilder();
while ((line = in.readLine()) != null)
buffer.append(line).append('\n');
byte[] latin1 = buffer.toString().getBytes("ISO-8859-1");
return new String(latin1);
//return buffer;
} catch (IOException e) {
return "";
} finally {
closeStream(in);
}
}
private static void closeStream(Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// Ignore
}
}
}
}
You can use this in your Eula class as follows:
if (!prefs.getEulaStatus(context)) {
MyAsync async= new MyAsync(activity,new TaskCompleteListner() {
#Override
public boolean onComplete(String result) {
//TODO show your alert dialog here. Result has the string needed
return false;
}
}) ;
}
Hope this helps.
If its just a dialog u need to show, you can use the Activity's following method:
public final void runOnUiThread (Runnable action)
AsyncTask would be a cleaner approach. However, this will save you the trouble of extra code if you are looking for a quick switch onto the main thread.
Async task will be the better approach.
1. Do your background operation (readEula(Activity activity)) in doInBackGround and
2. show dialog in onPostExecute method.
In another approach create thread and do your operation (readEula(act)) in it and use handler to communicate to this thread and show alert dialog in you activity only.
How to show the progress bar in FTP download in async class in android?
I've tried many things but didn't get the progress bar. Here's my code,
and I'm calling this class from other Activity passing the context of that activity to this class.
package com.scft;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferListener;
import java.io.File;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.StrictMode;
import android.util.Log;
import android.widget.PopupWindow;
import android.widget.Toast;
public class ftpdownload_class {
static final String FTP_HOST= "**************";
/********* FTP USERNAME ***********/
static final String FTP_USER = "*********";
/********* FTP PASSWORD ***********/
static final String FTP_PASS ="*******";
File fileDownload=null;
long startTime_ftpDownload=0;
long endTime_ftpDownload=0;
long downloaded_file=0;
long startTime_ftpUpload=0;
long endTime_ftpUpload=0;
FTPClient client=null;
public static File m_fileName;
private PopupWindow pwindo;
String totaltime_ftpUpload,filesize_ftpUpload,ratevalue_ftpUpload,totaltime_ftpDownload,filesize_ftpDownload,ratevalue_ftp_download;
Context mContext=null;
public ftpdownload_class( Context c)
{
mContext=c;
}
public void ftp_downloadStart() {
FTPClient ftp = new FTPClient();
try {
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
ftp.connect(FTP_HOST,158);//158 is the port number
//System.out.println(ftp.connect(host)[0]);
ftp.login(FTP_USER, FTP_PASS);
fileDownload = new File("/sdcard/test.mp3");
fileDownload.createNewFile();
startTime_ftpDownload = System.currentTimeMillis();
ftp.download("test.mp3", fileDownload,
new FTPDataTransferListener() {
// lenghtOfFile = conection.getContentLength();
public void transferred(int arg0) {
// download_btn.setVisibility(View.GONE);
//Log.v("log_tag", "This is for transfer");
// Toast.makeText(getBaseContext(), " transferred ..."+arg0 , Toast.LENGTH_SHORT).show();
}
public void started() {
// TODO Auto-generated method stub
// Toast.makeText(getBaseContext(), " Download Started ...", Toast.LENGTH_SHORT).show();
//Log.v("log_tag", "This is for started");
}
public void failed() {
// download_btn.setVisibility(View.VISIBLE);
Toast.makeText(mContext, " failed ...", Toast.LENGTH_SHORT).show();
System.out.println(" failed ..." );
}
public void completed() {
// download_btn.setVisibility(View.VISIBLE);
endTime_ftpDownload = System.currentTimeMillis(); //maybe
Toast.makeText(mContext, " Download completed ...", Toast.LENGTH_SHORT).show();
getspeedfor_ftp_download();
//Log.v("log_tag", "This is for completed");
}
public void aborted() {
// download_btn.setVisibility(View.VISIBLE);
Toast.makeText(mContext," transfer aborted,please try again...", Toast.LENGTH_SHORT).show();
//Log.v("log_tag", "This is for aborted");
}
});
} catch (Exception e) {
e.printStackTrace();
try {
ftp.disconnect(true);
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
long downloaded_file_ftp=0;
public void getspeedfor_ftp_download()
{
downloaded_file_ftp = fileDownload.length();
//Log.d("DownloadManager", "download ended: " + ((endTime - startTime) / 1000) + " secs");
String abc = (((endTime_ftpDownload - startTime_ftpDownload) / 1000) + " secs");
totaltime_ftpDownload = abc;
double size = (downloaded_file_ftp/1024);
if(size<1000)
filesize_ftpDownload=String.valueOf(size).concat("Kb");
else
filesize_ftpDownload=String.valueOf(size/1024).concat("Mb");
double rate = (((downloaded_file_ftp / 1024) / ((endTime_ftpDownload - startTime_ftpDownload) / 1000)) * 8);
rate = Math.round( rate * 100.0 ) / 100.0;
if(rate > 1000)
ratevalue_ftp_download = String.valueOf(rate / 1024).concat(" Mbps");
else
ratevalue_ftp_download = String.valueOf(rate).concat(" Kbps");
Log.d("DownloadManager", "download speed: "+ratevalue_ftp_download);
alertStatus_ftp_download();
}
public void alertStatus_ftp_download()
{
AlertDialog.Builder alertDialogBuilderfor_ftp_download = new AlertDialog.Builder(mContext);
// set title
alertDialogBuilderfor_ftp_download.setTitle("Ftp Download Speed Status");
// set dialog message
alertDialogBuilderfor_ftp_download
.setMessage("Download Speed : "+ratevalue_ftp_download+", "+"\n Total File Size :"+filesize_ftpDownload+"\nTotal time taken : "+totaltime_ftpDownload)
//.setMessage("Download Speed "+ratevalue_ftp_download)
.setCancelable(false)
.setPositiveButton("Ok",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, close
// current activity
dialog.cancel();
}
})
.setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialogftp_download = alertDialogBuilderfor_ftp_download.create();
// show it
alertDialogftp_download.show();
}
}
After searching hours and hours, i finally built a solution like this.
Create an Uploader class like this UploadToFtp.java
public class UploadToFtp {
public FTPClient mFTPClient = null;
String host;
String username;
String password;
CopyStreamAdapter streamListener;
ProgressDialog pDialog;
boolean status = false;
public boolean ftpUpload1(String srcFilePath, String desFileName,
String desDirectory, String host, String username, String password,
final ProgressDialog pDialog) {
this.pDialog = pDialog;
this.host = host;
this.username = username;
this.password = password;
int port = 21;
mFTPClient = new FTPClient();
try {
mFTPClient.connect(host, port); // connecting to the host
mFTPClient.login(username, password); // Authenticate using username
// and password
mFTPClient.changeWorkingDirectory(desDirectory); // change directory
System.out.println("Dest Directory-->" + desDirectory); // to that
// directory
// where image
// will be
// uploaded
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
BufferedInputStream buffIn = null;
final File file = new File(srcFilePath);
System.out.println("on going file-->" + srcFilePath);
buffIn = new BufferedInputStream(new FileInputStream(file), 8192);
mFTPClient.enterLocalPassiveMode();
streamListener = new CopyStreamAdapter() {
#Override
public void bytesTransferred(long totalBytesTransferred,
int bytesTransferred, long streamSize) {
// this method will be called everytime some
// bytes are transferred
// System.out.println("Stream size" + file.length());
// System.out.println("byte transfeedd "
// + totalBytesTransferred);
int percent = (int) (totalBytesTransferred * 100 / file
.length());
pDialog.setProgress(percent);
if (totalBytesTransferred == file.length()) {
System.out.println("100% transfered");
removeCopyStreamListener(streamListener);
}
}
};
mFTPClient.setCopyStreamListener(streamListener);
status = mFTPClient.storeFile(desFileName, buffIn);
System.out.println("Status Value-->" + status);
buffIn.close();
mFTPClient.logout();
mFTPClient.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
}
Now make an Asynctask in the class where file is actually being fetched or being created, like this
class UploadTask extends AsyncTask<Void, Integer, Void> {
ProgressDialog pDialog;
Boolean uploadStat;
UploadToFtp utp = new UploadToFtp();
#Override
protected void onPreExecute() {
pDialog = new ProgressDialog(UploadActivity.this);
pDialog.setMessage("Uploading...");
pDialog.setCancelable(false);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
System.out.println("source url -> " + sourceUrl);
System.out.println("filename -> " + filename);
System.out.println("desDirectory -> " + desDirectory);
uploadStat = new UploadToFtp().ftpUpload1(sourceUrl, filename,
desDirectory, app.getHostname(), app.getUsername(),
app.getPassword(), pDialog);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (uploadStat) {
if (pDialog != null && pDialog.isShowing()) {
pDialog.dismiss();
}
reviewImageView.setImageBitmap(null);
mCurrentPhotoPath = "";
photo = null;
uploadMessage.setVisibility(View.VISIBLE);
UploadSuccess.setVisibility(View.VISIBLE);
} else {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
UploadActivity.this);
// Setting Dialog Message
alertDialog.setTitle("Error Uploading File");
alertDialog
.setMessage("Connection lost during upload, please try again!");
alertDialog.setCancelable(false);
// Setting Icon to Dialog
// Setting OK Button
alertDialog.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
dialog.cancel();
}
});
alertDialog.show();
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
if (pDialog != null && pDialog.isShowing()) {
pDialog.dismiss();
}
System.out.println("Result-->" + result);
super.onPostExecute(result);
}
}
Now simply call this Asynctask on button click or any other event you want
new UploadTask().execute();
You can do something like this..
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("waiting 5 minutes..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
Then write an async task to update progress..
private class DownloadZipFileTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... urls) {
//Copy you logic to calculate progress and call
publishProgress("" + progress);
//Your code Here
}
protected void onProgressUpdate(String... progress) {
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
This is the Procedure to use Progress Dialog update with the AsyncTask, write your code in doInBackground(String...)
In my android application, there is a app file at the sd card, and the same in our server, but the data in the server may be updated.
So I make an activity to check if latest data is avaiable.
This is an example, there is only one button "Check", when user hit this button, I will get the information of the local data, and then reqest to the server to check if it can be udpated.(THis is done by the CheckTask and a progress dialog will show up during the checking).
Then if a update is requred, I will provide a Dialog to tell the user, they can choose "Download Now" or "Download Later", if they choose "Download Now", a DownLoadTask will be executed,and a new ProgressDialog will be created to show the progress of the download.
Now I meet a problem:
Everything works well unless user click the "Download Now" and then cancel the download.
Then when user click the "Check" button, the CheckTask will not work normally.
This is the codes:
public class MyActivity extends Activity {
private DecimalFormat format = new DecimalFormat("0.#");
private final int Dialog_Offline_Check_HaveUpdate = 13;
private final int Dialog_Offline_Download = 14;
private CheckTask mCheckTask;
private ProgressDialog mCheckProgressDialog;
private DownloadTask mDownloadTask;
private ProgressDialog mDownloadProgressDialog;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.setupView();
}
private void setupView() {
mCheckProgressDialog = new ProgressDialog(this);
mCheckProgressDialog.setCanceledOnTouchOutside(false);
findViewById(R.id.check).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startCheckTask();
}
});
}
private void startCheckTask() {
if (mDownloadTask != null && !mDownloadTask.isCancelled()) {
showDialog(Dialog_Offline_Download);
} else {
//for debug
String data = String.format("{\"name\":\"%s\",\"size\":123455,\"lastModifiedTime\":\"2014-1-1\",\"hasUpdate\":false}", "Old Data");
AppData appData = null;
try {
appData = buildMapData(data);
} catch (JSONException e) {
e.printStackTrace();
}
if (mCheckTask != null) mCheckTask.cancel(true);
mCheckTask = new CheckTask();
mCheckTask.execute(String.format("http://xxxx?t=%s", appData.lastModifiedTime));
}
}
private void startDownLoadTask() {
if (mDownloadTask != null) {
mDownloadTask.cancel(true);
}
mDownloadTask = new DownloadTask();
mDownloadTask.execute("https://dl.google.com/android/adt/adt-bundle-windows-x86-20131030.zip"); //for debug
showDialog(Dialog_Offline_Download);
}
#Override
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
switch (id) {
case Dialog_Offline_Check_HaveUpdate:
builder.setTitle("Check Update").setPositiveButton("Download Now", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
startDownLoadTask();
}
}).setNegativeButton("Download Later", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
}).setMessage("Latest Data avaiable!");
return builder.create();
case Dialog_Offline_Download:
mDownloadProgressDialog = new ProgressDialog(this);
mDownloadProgressDialog.setTitle("Download Latest Data");
mDownloadProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDownloadProgressDialog.setMax(100);
mDownloadProgressDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Do it in Background", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
mDownloadProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if (mDownloadTask != null)
mDownloadTask.cancel(true);
}
});
mDownloadProgressDialog.setMessage("");
return mDownloadProgressDialog;
}
return null;
}
#Override
protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
switch (id) {
case Dialog_Offline_Check_HaveUpdate:
String msgg;
AppData appData1 = (AppData) args.getSerializable("data");
if (appData1 != null) {
msgg = String.format("%s\n%s: %s \n%s: %s\n%s: %s", "New Data Avaiable",
"Name", appData1.name,
"Size", makeFileSizeReadable(appData1.size),
"Last Update Time", appData1.lastModifiedTime);
} else {
msgg = "";
}
((AlertDialog) dialog).setMessage(msgg);
break;
}
}
private String makeFileSizeReadable(long size) {
double value;
String unit;
if (size < 1024) {
// < 1k
value = size;
unit = "Byte";
} else if (size < 1024 * 1024) {
// 1k,1M
value = size / 1024d;
unit = "Kb";
} else {
value = size / 1024d / 1024d;
unit = "Mb";
}
return String.format("%s %s", format.format(value), unit);
}
class CheckTask extends AsyncTask<String, Void, AppData> {
private String errorMsg;
private boolean cancel = false;
#Override
protected AppData doInBackground(String... urls) {
String url = urls[0];
//for debug
String response = String.format("{\"name\":\"%s\",\"size\":222222,\"lastModifiedTime\":\"2014-1-5\",\"hasUpdate\":true}", "New Data");
Log.d("map.setting", String.format("start parse result: [%s]", response));
AppData md = null;
try {
md = buildMapData(response);
} catch (JSONException e) {
e.printStackTrace();
Log.e("map.setting", "error when parse:" + e.getMessage());
}
Log.d("map.setting", "get md:" + md);
return md;
}
#Override
protected void onPreExecute() {
mCheckProgressDialog.setMessage("Checking...");
mCheckProgressDialog.show();
}
#Override
protected void onPostExecute(AppData appData) {
mCheckProgressDialog.dismiss();
if (appData == null) {
return;
}
if (appData.hasUpdate) {
Bundle bd = new Bundle();
bd.putSerializable("data", appData);
showDialog(Dialog_Offline_Check_HaveUpdate, bd);
} else {
Toast.makeText(MyActivity.this, "Your data is the latest!", Toast.LENGTH_SHORT).show();
}
}
}
private AppData buildMapData(String response) throws JSONException {
JSONObject root = new JSONObject(response);
String name = root.getString("name");
long size = root.getLong("size");
String lastModifiedTime = root.getString("lastModifiedTime");
boolean hasUpdate = root.getBoolean("hasUpdate");
AppData md = new AppData();
md.name = name;
md.lastModifiedTime = lastModifiedTime;
md.size = size;
md.hasUpdate = hasUpdate;
return md;
}
class DownloadTask extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
try {
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 null;
}
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(Environment.getExternalStorageDirectory() + "/tmp.data", false);
byte data[] = new byte[4096];
int total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
if (fileLength > 0)
publishProgress(total * 100 / fileLength, total, fileLength);
output.write(data, 0, count);
}
} catch (Exception e) {
return null;
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
} finally {
// wl.release();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
//progress current total
if (mDownloadProgressDialog != null) {
mDownloadProgressDialog.setProgress(values[0]);
String msg = String.format("Progress:%s/%s", makeFileSizeReadable(values[1]), makeFileSizeReadable(values[2]));
mDownloadProgressDialog.setMessage(msg);
}
}
#Override
protected void onPostExecute(String res) {
//map file downloaded replace the old file
}
#Override
protected void onCancelled() {
super.onCancelled();
}
}
}
class AppData implements Serializable {
public String name;
public String lastModifiedTime;
public long size;
public boolean hasUpdate;
}
Anyone can find what is the problem?
Is that you encounter AsynTask's bug after HONEYCOMB?
Order of execution
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.
In our project we use AsynTask like this:
public void executeParallelly(Params... params) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
task.execute(params);
} else {
task.executeOnExecutor(AsynTask.THREAD_POOL_EXECUTOR, params);
}
}