I'm trying to make an activity that is asked for some result. This result is normally returned instantly (in the onCreate), however, sometimes it is nesesary to wait for some internet-content to download which causes the "loader"-activity to show. What I want is that the loader-activity don't display anything more than a progressdialog (and that you can still se the old activity calling the loader-activity in the background) and I'm wondering wheather or not this is possible.
The code I'm using as of now is:
//ListComicsActivity.java
public class ListComicsActivity extends Activity
{
private static final int REQUEST_COMICS = 1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list_comics);
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intents.ACTION_GET_COMICS);
startActivityForResult(intent, REQUEST_COMICS);
}
});
}
/** Called when an activity called by using startActivityForResult finishes. */
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
Toast toast = Toast.makeText(this, "The activity finnished", Toast.LENGTH_SHORT);
toast.show();
}
}
//LoaderActivity.java (answers to Intents.ACTION_GET_COMICS action-filter)
public class LoaderActivity extends Activity
{
private Intent result = null;
private ProgressDialog pg = null;
private Runnable returner = new Runnable()
{
public void run()
{
if(pg != null)
pg.dismiss();
LoaderActivity.this.setResult(Activity.RESULT_OK, result);
LoaderActivity.this.finish();
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
String action = getIntent().getAction();
if(action.equals(Intents.ACTION_GET_COMICS))
{
Runnable loader = new Runnable()
{
public void run()
{
WebProvider.DownloadComicList();
Intent intent = new Intent();
intent.setDataAndType(ComicContentProvider.COMIC_URI, "vnd.android.cursor.dir/vnd.mymir.comic");
returnResult(intent);
}
};
pg = ProgressDialog.show(this, "Downloading", "Please wait, retrieving data....");
Thread thread = new Thread(null, loader, "LoadComicList");
thread.start();
}
else
{
setResult(Activity.RESULT_CANCELED);
finish();
}
}
private void returnResult(Intent intent)
{
result = intent;
runOnUiThread(returner);
}
}
It turns out you can do this by setting the activitys theme-attribute to #android:style/Theme.Dialog and calling this.setVisible(false); in the onCreate-method of the activity.
Related
I want to show a ProgressDialog while jumping from my LoginActivity to my HomeActivity, basically while HomeActivity is loading.
I am using a separate thread to call the intent of the HomeActivity while I am showing the ProgressDialog from the main thread in LoginActivity.
Everything seems to be working fine, it is just that the ProgressDialog is displayed but there is no animated spinner.
I am wondering if i am doing this correctly.
Here the relevant code from LoginActivity:
public class LoginActivity extends AppCompatActivity {
private EditText userID, userPass;
private ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
userID = (EditText) findViewById(R.id.edtX_srcLogin_userID);
userPass = (EditText) findViewById(R.id.edtX_srcLogin_userpass);
final Button bt_submit = (Button) findViewById(R.id.bT_scrLogin_submit);
bt_submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
parseUserCredentials(userID.getText().toString(), userID.getText().toString());
}
});
}
private void parseUserCredentials(String userId, String userPassword) {
if ( userId.equals("userid") && userPassword.equals("1234") ) {
dialog = ProgressDialog.show(LoginActivity.this, "Checking credentials",
"Please wait...", true, false);
newThreadLoadActivity();
}else {
userID.setText("");
userPass.setText("");
userID.requestFocus();
dialog.cancel();
}
}
private void newThreadLoadActivity(){
new Thread() {
public void run() {
startActivity(new Intent(LoginActivity.this, HomeActivity.class));
}
}.start();
}
#Override
protected void onStop() {
super.onStop();
dialog.cancel();
}
}
EDIT
The main idea is to show the ProgressDialog whileHomeActivity loads, and cancel the ProgressDialog when HomeActivity is ready to be displayed.
Use the below code.It will make the delay for 10sec while moving to the next activity so your progress bar make be visible.
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
dialog.cancel();
startActivity(new Intent(LoginActivity.this, HomeActivity.class));
}
}, 10000);
Everything is working fine, and the second Activity is running but My progress Dialog doesn't appear when I using Intent.
Is there an error in the code? , I can't find stack.
an idea ???
Please help me , Thanks!
public class StartActivity extends AppCompatActivity {
private Intent mIntent;
private final int totalProgressTime = 100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
}
public void onClick(View view) {
new DownloadTask().execute();
mIntent = new Intent(this, MainActivity.class);
startActivity(mIntent);
}
private class DownloadTask extends AsyncTask<String,Void,Object>{
ProgressDialog mIndicator = new ProgressDialog(StartActivity.this);
#Override
protected void onPreExecute() {
super.onPreExecute();
mIndicator.setMessage("Wait..");
mIndicator.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mIndicator.setProgress(0);
mIndicator.setMax(totalProgressTime );
mIndicator.show();
new Thread(new Runnable() {
#Override
public void run(){
int counter = 0;
while(counter < totalProgressTime ){
try {
Thread.sleep(300);
counter ++;
mIndicator.setProgress(counter);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mIndicator.dismiss();
}
}).start();
}
#Override
protected Object doInBackground(String... params) {
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
mIndicator.dismiss();
}
}
}
Let's not talk about how wrong is to use AsyncTask as you used it here. I suppose you have some bigger picture, and this is just some test snippet.
So with
new DownloadTask().execute();
you started AsyncTask.
And just after that you started new activity:
mIntent = new Intent(this,MainActivity.class);
startActivity(mIntent);
So, AsyncTask continue to work in separate thread, but StartActivity is no longer active (probably not even visible), because MainActivity is in foreground now.
So, you want to see ProgressBar in StartActivity, but you are in MainActivity.
Try to wait AsyncTask to finish, than start MainActivity.
#Override
protected void onPostExecute(Object o) {
mIndicator.dismiss();
mIntent = new Intent(this, MainActivity.class);
startActivity(mIntent);
}
I have two activities the first one load url(simple webview) and the second one get the id for url from listview then call back the first activity to load the url.
I'm use onActivityResult() method in the first activity to get the extra data(url id).
My problem is when I want to show the ProgressDialog in the first Activity in method onActivityResult() after choose item from ListView in second activity I got a ProgressDialog but it just shows for seconds (very quickly) then disappear before complete the load for url(WebView)
This is the code for the tow activities I hope help me.
public class LibActivity extends Activity {
private ImageButton btnCategoriesList;
public static final int BOOK_CATEGORY_REQUEST_CODE = 1;
private WebView webView;
public ProgressDialog dialog;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lib);
handler = new Handler();
dialog = ProgressDialog.show(this, "Loading", "Please wait", true, false);
DisplayMetrics displaymetrics = new DisplayMetrics();
webView = (WebView) findViewById(R.id.categoryWebView);
webView.setWebViewClient(new CategoryItemWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://maktabati.mobi/V3/store.php?catid=" + "91");
btnCategoriesList = (ImageButton) findViewById(R.id.btn_category_list);
btnCategoriesList.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showBooksCategories();
}
});
}
/**
*
*/
protected void showBooksCategories() {
Intent intent = new Intent(getApplicationContext(), BooksCategoriesActivity.class);
startActivityForResult(intent, BOOK_CATEGORY_REQUEST_CODE);
}
/**
*
* #author Jamil
*
*/
private class CategoryItemWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("book")) {
String bookId = url.substring(12);
Intent intent = new Intent(getApplicationContext(), BookDetailActivity.class);
intent.putExtra("BOOK_ID", bookId);
startActivity(intent);
view.stopLoading();
}
return super.shouldOverrideUrlLoading(view, url);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
dialog.dismiss();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
if (requestCode == BOOK_CATEGORY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
dialog = ProgressDialog.show(this, "Loading", "Please wait", true);
new Thread() {
public void run() {
webView.loadUrl("http://maktabati.mobi/V3/store.php?catid=" + data.getStringExtra("CATEGORY_ID"));
handler.post(new Runnable() {
#Override
public void run() {
dialog.dismiss();
}
});
}
}.start();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
the second activity
public class BooksCategoriesActivity extends Activity {
ItemsCategoriesAdapter adapter;
ArrayList<Category> lstCategory;
Handler handlerProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.books_categories_list);
handlerProgressDialog = new Handler();
CategoryHandler handler = new CategoryHandler();
ParserCreater parserCreater = new ParserCreater(handler);
parserCreater.parse("http://maktabati.mobi/V3/getCategories.php");
lstCategory = handler.getLstCategory();
final ListView listView = (ListView) findViewById(R.id.categories_list);
adapter = new ItemsCategoriesAdapter(lstCategory);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, final int position, long arg3) {
Intent intent = new Intent(getApplicationContext(), LibActivity.class);
intent.putExtra("CATEGORY_ID", lstCategory.get(position).getId());
BooksCategoriesActivity.this.setResult(RESULT_OK, intent);
finish();
}
});
}
Thanks
Please try what happens if you remove the following code from the onActivityResult function:
handler.post(new Runnable() {
#Override
public void run() {
dialog.dismiss();
}
});
The onPageFinished() function should be called after webView.loadUrl().
The method loadUrl() is not a blocking call, so you don't need to call it from a background thread. If you want to capture the point at which the page is finished loading, you can set a WebviewClient object on your WebView to handle a series of callbacks in this regard.
Also, since that call does not block, it returns immediately and your dismiss() method is called almost as soon as show(), which is why you see it display only briefly.
HTH
I feel kind of dumb asking this question because I have another app that this works for fine or at least I think it is the same. I definitely need another set of eyes on this because to me, it looks like it should work. My code is below:
public class InventorySystemActivity extends Activity {
private EditText barcode;
private EditText proddesc;
private EditText quantity;
public String scan_result;
public int which;
private InventorySystemDB db;
public Item singleItem;
public Item[] itemList;
private Thread t;
Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
barcode.setText(scan_result);
proddesc.setText(singleItem.name);
quantity.setText(singleItem.quantity);
break;
case 3:
updateUI();
pd.dismiss();
}
}
};
public static Intent in = new Intent("com.google.zxing.client.android.SCAN");
private ProgressDialog pd;
private Thread dbt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.db = new InventorySystemDB(this);
try {
this.db.createDataBase();
this.db.openDataBase();
} catch (Exception e) {
e.printStackTrace();
}
this.dbt = new Thread(this.db);
setContentView(R.layout.main);
Button scan = (Button) findViewById(R.id.scan);
scan.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
startActivityForResult(in, 0);
}
});
Button search = (Button) findViewById(R.id.searchbutton);
search.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
pd.show();
which = 1;
scan_result = barcode.getText().toString();
dbt.start();
}
});
barcode = (EditText) findViewById(R.id.barcodenum);
proddesc = (EditText) findViewById(R.id.proddesc);
quantity = (EditText) findViewById(R.id.prodquantity);
pd = new ProgressDialog(this);
pd.setMessage("Loading data...");
}
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
scan_result = intent.getStringExtra("SCAN_RESULT");
barcode.setText(scan_result);
} else if (resultCode == RESULT_CANCELED) {
}
}
}
private void updateUI() {
barcode.setText(singleItem.upc);
proddesc.setText(singleItem.name);
quantity.setText("0");
}
}
All my thread does is it takes the UPC number and pulls up info from a couple websites. The code sends the message to the handler just fine and I've made a few apps like this using threads and handlers, not sure why I have this issue now. Anyway, I can dismiss the ProgressDialog, but I am unable to update any UI objects. It all looks fine to me, so I really need some more sets of eyes on this. Thanks guys.
You need to do UI changes in runOnUIThread()
I have a program that starts on one activity goes to the next and their is button to click, after a certain amount of time it goes back to the starting page and reports the number of clicks.
Here's my code: clickcount is the first activity
public class ClickCountActivity extends Activity {
/** Called when the activity is first created. */
Button next;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
next=(Button) findViewById(R.id.NextButton);
//---------------------------------------------------------------
next.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(ClickCountActivity.this, startClickActivity.class);
i.putExtra("comingFrom", "come");
final int result=1;
startActivityForResult(i,result);
}
});
//---------------------------------------------------------------------------
}
}
public class startClickActivity extends Activity {
/** Called when the activity is first created. */
Button clicker;
int counter ;
Timer timer = new Timer(); // use timer to start a new task
MyTimerTask task = new MyTimerTask();
final long seconds = 3;
Intent p = getIntent();
String answer = p.getStringExtra("comingFrom");
class MyTimerTask extends TimerTask {
public void run()
//override run method
{
Intent x = new Intent(startClickActivity.this, ClickCountActivity.class);
x.putExtra("returnStr", answer);
setResult(RESULT_OK,x);
startActivity(x);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action);
clicker=(Button) findViewById(R.id.Clicker);
//---------------------------------------------------------------
clicker.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
counter++; // counts number of clicks
task.cancel(); // cancels current task
task = new MyTimerTask(); //create new task
timer.schedule(task,seconds*1000L); // start a new timer task in 5seconds (timertask, seconds(long))
// System.out.println(counter);
}
});
}
}
Your code in run method should be this:
Intent x = new Intent(startClickActivity.this, ClickCountActivity.class);
x.putExtra("returnStr", counter);
setResult(RESULT_OK,x);
finish();
You need to pass the no. of counts i.e. counter in intent and collect it from onActivityResult(int requestCode, int resultCode, Intent data) method of ClickCountActivity class. The value is passed in the data intent and can be queried using int counterValue = data.getIntegerExtra("returnStr", 0);