ProgressDialog not showing - java

I'm trying to show a ProgressDialog while I'm processing some data on background.
I call the method show() before starting the Thread, and it doesn't show, but when i call inside the Thread the method dismiss(), it appears and desapears in a flash.
I read some about using an Async Task, but I really don't want to show a progress, just the spinning that ads the user that the app is loading.
How can I solved this?
Some of my code:
// When clicking a button a call this method to start the thread
public void onClick(View v) {
// Here, doesn't show the spinning wheel
progress = ProgressDialog.show(this,
"Wait please …",
"Scanning …",
true);
Thread scan = new Thread(new Runnable() {
#Override
public void run() {
runOnUiThread(new Scanner());
progress.dismiss();
}
});
scan.start();
}
I declared the progress var like this:
private ProgressDialog progress;
public void onCreate(Bundle savedInstanceState) {
//[...]
progress = new ProgressDialog(this);
//[...]
}
The Scanner class code:
private class Scanner implements Runnable {
private final String TAG = "SCANNER-->";
public void run() {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
for (int i = 0; i < 10; i++) {
wifiManager.startScan();
List<ScanResult> results = wifiManager.getScanResults();
if (results != null) {
final int size = results.size();
if (size == 0) {
adapter.clear();
adapter.add("No access points in range");
break;
}
else {
txt.setText("Number of results: " + results.size());
Log.d(TAG,"Number of results: " + results.size());
for (ScanResult result : results) {
if (adapter.getPosition(result.SSID) == -1) {
adapter.add(result.SSID);
}
}
}
}
else {
adapter.clear();
adapter.add("No results. Check wireless is on");
break;
}
adapter.notifyDataSetChanged();
Log.d(TAG,"sistema avisado de cambios");
// Refresh information each 0.5 second
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progress.dismiss();
}
}
How you can see I'm refreshing a List with nearly networks.

Try this:
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
See documentation - static show(...) methods.
http://developer.android.com/reference/android/app/ProgressDialog.html

Related

Exit activity after killing all threads android

I am trying to play with progress bars. I have this (below) simple activity which runs a progress bar N times one after the other, when I call Progress(N). It is working great but the problem I am facing is, if I press back button. I get into the mainActivity but the progress bars (the threads) are still running in background one after the other. As soon as they finish N loops, the intent is called and whatever I would be doing would be interrupted by this LOOP_OVER activity.
I tried solving this by my own. I tried using variable of Thread class (before I was directly doing it). And tried to interrupt() it at onDestroy() or even just before the intent is called but its not helping. How should I go about it?
public class Loop extends Activity {
private ProgressBar progressBar;
private CircleProgress circleProgress;
private int progressStatus = 0;
private Handler handler = new Handler();
private TextView myView;
private int started = 0, doneLoop=0;
private Thread th;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loop);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
circleProgress = (CircleProgress) findViewById(R.id.circle_progress);
myView = (TextView) findViewById(R.id.instruction);
progressBar.setScaleY(3f);
// Start long running operation in a background thread
Progress(3);
}
#Override
public void onDestroy() {
// Below, everything I am just
th.interrupt();
Loop.this.finish();
Thread.currentThread().interrupt();
super.onDestroy();
}
public void Progress(final int numberOfRuns){
// QueView.setText(Que);
if(numberOfRuns == 0){
th.interrupt();
Intent myIntent = new Intent(Loop.this, LOOP_OVER.class);
startActivity(myIntent);
super.onDestroy();
finish();
}
th = new Thread(new Runnable() {
public void run() {
genNextSet();
while (progressStatus < 100) {
progressStatus += 1;
// Update the progress bar and display the
//current value in the text view
handler.post(new Runnable() {
public void run() {
circleProgress.setProgress(progressStatus);
progressBar.setProgress(progressStatus);
textView.setText(progressStatus+"/"+progressBar.getMax());
}
});
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
myView.setText(Que);
}
});
// Sleep for 200 milliseconds.
//Just to display the progress slowly
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progressStatus = 0;
Progress(numberOfRuns - 1);
}
});
th.start();
}
private void genNextSet() {
// so some cool here!
}
}
You can think of a class variable that is shared among all threads.
Try to add something like this:
private Boolean LOOP = true;
then
while (progressStatus < 100 && LOOP) {
and
#Override
public void onBackPressed() {
LOOP = false
}
also
if(LOOP == true){
// call intent
}
finish();
Your activity does not get destroyed, if you press the "Back"-key, thus onDestroy() will not be called.I'd override onBackPressed(), if I where you.Alternatively, you could try to put it into the onPause()-method.
You haven't override the back button pressed..try this
#Override
public void onBackPressed() {
th.interrupt();
Loop.this.finish();
Thread.currentThread().interrupt();
super.onBackPressed();
// add finish() if you want to kill current activity
}

trying to setimagebitmap after progress bar finished result in error

It is my first time implement horizontal progress bar in my application
The goal is after the progress bar finish, the application show toast message and image bitmap
the toast message is doing fine but the image make the application to force close
this is my code:
Button buttonProceed = (Button) findViewById(R.id.buttonProceed);
buttonProceed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(true);
progressBar.setMessage("Processing");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
progressBarStatus = 0;
fileProcess = 0;
String toastMessage = "Citra host berhasil ditanam citra watermark dan disimpan di internal storage";
final Toast toast = Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0);
final ImageView resultImageView = (ImageView) findViewById(R.id.viewResult);
new Thread(new Runnable() {
public void run() {
while (progressBarStatus < 100) {
progressBarStatus = progressMarker();
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBarHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressBarStatus);
}
});
}
if (progressBarStatus >= 100) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.dismiss();
toast.show();
//the resultBitmap variable is declared in global
resultImageView.setImageBitmap(resultBitmap);
}
}
}).start();
}
});
}
So, could someone help me figure what wrong in my code?
Regard!
The problem is that you aren't allowed to change UI in new Thread. For this purpose you could use AsyncTask instead of Thread.
Here is some example: How to use asynctask to display a progress bar that counts down?
You should call progressBar.setProgress(progressBarStatus); in onProgressUpdate(String... progress) of AsyncTask.
And this code should be called in onPostExecute(String result):
progressBar.dismiss();
toast.show();
//the resultBitmap variable is declared in global
resultImageView.setImageBitmap(resultBitmap);
Because code in onPostExecute is called on main UI Thread.

Progress Bar loading according to timer

Am using a timer to record video in my App and it is based on JavaCvRecorder app.
When I press the screen the recording starts and we are able to see the time in leftside of screen.
Now instead of showing the timer I have to show a progress bar to load according to the time can any one help me on this as i don't know where to show the progress bar. The below is code for showing time while recording video. Please help me friends
private void initiateRecording(boolean isActionDown) {
isRecordingStarted = true;
firstTime = System.currentTimeMillis();
recording = true;
totalPauseTime = 0;
pausedTime = 0;
txtTimer.setVisibility(View.VISIBLE);
// Handler to show recoding duration after recording starts
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
btnRecorderControl.setVisibility(View.VISIBLE);
btnRecorderControl.setText(getResources().getString(R.string.stop));
}
Use AsynkcTask method
private void call_timerprogressbar() { //......call this method first
try {
callprogressbar sessionrunner = new callprogressbar(getActivityTaskHandler);
sessionrunner.execute();
} catch (Exception ex) {
}
}
public class callprogressbar extends AsyncTask<String, String, String> {
Handler statushandler;
public callprogressbar(Handler getActivityTaskHandler) {
statushandler = getActivityTaskHandler;
}
#Override
protected String doInBackground(String... params) {
//........call your timer function
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setMessage("Please wait... ");
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.setIndeterminate(true);
progressBar.setCanceledOnTouchOutside(false);
progressBar.setTitle(" ");
progressBar.setCancelable(false);
progressBar.show();
}
#Override
protected void onPostExecute(String result) {
try
{
super.onPostExecute(result);
Message msg = new Message();
msg.obj = result;
statushandler.sendMessage(msg);
progressBar.dismiss();
}catch(Exception ex){
}
}
}
public Handler getActivityTaskHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressBar.dismiss();
}
};

Android application structure: Scheduled Threads

I'm having trouble with my app. What I want is:
MainActivity launches & creates a scheduled thread which periodically checks whether the WiFi service is enabled. If it IS, go to a new activity. If it ISN'T then launch a warning & take the user to the WiFi settings page.
When the user comes back to the Main Activity, the MainActivity code will now sense the WiFi service is enabled & send them to the second activity.
I have this working. Here's the code:
#Override
protected void onResume()
{
super.onResume();
ScheduledExecutorService oScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
try
{
oScheduledExecutor.scheduleAtFixedRate({RUNNABLE HERE}, 0, 5, TimeUnit.SECONDS);
}
catch (Exception e)
{
System.out.println("(MainActivity) Caught Exception here. #1");
System.out.println("(MainActivity) Error: " + e.getMessage() + " Cause: " + e.getCause());
e.printStackTrace();
}
}
#Override
protected void onStart()
{
super.onStart();
// Assign WifiManager to System service
oWiFiManager = (WifiManager) getSystemService(WIFI_SERVICE);
// Create Runnable
oWiFiUpdater = new Runnable() {
#Override
public void run()
{
// If we should show WiFi Disabled
if (shouldShowWiFiAlert())
{
runOnUiThread(new Runnable() {
#Override
public void run() {
launchWiFiDisabledAlert();
}
});
}
Intent oAPListIntent = new Intent(getApplicationContext(), APList.class);
startActivity(oAPListIntent);
}
}
};
However when we are on the second activity, the first thread is still running. I thought that when the Activity is removed from View, all threads cease running??
I want the executor to only run when the Activity is viewable! Any ideas!?
EDIT: Answer thanks to inspiration from njzk2
#Override
protected void onResume()
{
super.onResume();
createWiFiAlertDialog();
boolean bWiFiEnabling = wifiEnabling();
while (bWiFiEnabling)
{
try
{
doSyncedWait(500);
}
catch (Exception e)
{
System.out.println("(MainActivity) Exception caught waiting. " + e.getMessage());
}
bWiFiEnabling = wifiEnabling();
}
boolean bWiFiEnabled = wifiReady();
if (!bWiFiEnabled)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
AlertDialog oAlertDialog = m_oAlertDialog;
oAlertDialog.show();
}
});
}
else
{
Intent oIntent = new Intent(this,APList.class);
startActivity(oIntent);
}
}
private boolean wifiEnabling()
{
WifiManager oWiFiManager = m_oWiFiManager;
if (oWiFiManager == null) return false;
if (oWiFiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING) return true;
return false;
}
private boolean wifiReady()
{
WifiManager oWiFiManager = m_oWiFiManager;
if (oWiFiManager == null) return false;
// If the WiFi state is anything other than enabled, then wait.
if (oWiFiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) return true;
return false;
}
If you give your runnable a reference to the activity, and set a boolean to true in onResume() and false in onPause(), you should be able to reference the boolean from your runnable and then use a if statement to only run if the boolean is set to true.

Update GUI after purchase of an IAP is complete, IAPv3 - Android

I finally figured out how to consume an IAP in v3 of the InAppBilling API. The user can now constantly consume as many products as they please.
Now I want the GUI for the user to be updated once the purchase is confirmed complete. I have put Toasts all over the below code to try and find out where to update the GUI at but I have yet to have a Toast appear yet. But remember that the consuming of the IAPs work.
I have identified in my code below the snippet that updates the GUI for the user. That snippet of code is what I want run AFTER a successful purchase is complete.
So my question is where to put that snippet of code so that the GUI is updated for the user after a successful purchase.
public class Levels extends SwarmActivity {
//static final String SKU_BUYLIVES = "buy5lives";
static final String SKU_BUYLIVES = "android.test.purchased";
IabHelper mHelper;
IInAppBillingService mService;
#Override
public void onCreate(Bundle savedInstanceState) {
moreLives = (Button)findViewById(R.id.moreLives);
moreLives.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
buyLives();
}
});
}
public void buyLives() {
final Dialog dialog = new Dialog(c);
dialog.setContentView(R.layout.buylives);
String base64EncodedPublicKey = a + b + d + e + f + g + h + i + j + k;
TextView title = (TextView)dialog.findViewById(R.id.question);
Button no = (Button)dialog.findViewById(R.id.no);
Button yes = (Button)dialog.findViewById(R.id.yes);
title.setText(c.getResources().getString(R.string.buyLivesQuestion));
no.setText(c.getResources().getString(R.string.maybelater));
yes.setText(c.getResources().getString(R.string.buy));
// Create the helper, passing it our context and the public key to verify signatures with
mHelper = new IabHelper(Levels.this, base64EncodedPublicKey);
// start setup. this is asynchronous and the specified listener will be called once setup completes.
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// there was a problem.
complain("An error has occurred. We apologize for the inconvenience. " + c.getResources().getString(R.string.problem1) + " " + result);
return;
}
// IAB is fully set up. Now, let's get an inventory of stuff we own.
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
yes.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
mHelper.launchPurchaseFlow(Levels.this, SKU_BUYLIVES, 10001, mPurchaseFinishedListener, "payload");
dialog.dismiss();
// the below ~14 lines is the code that I want to call to update the GUI for the user. this block of code has been all over the place. this is just the last spot I tested it at.
SharedPreferences settings = getSharedPreferences("level_SP", 0);
livesCount = settings.getInt("livesTotal1", 0);
remainderTimeStamp = settings.getLong("remainderTimeStamp1", 0);
livesCount = 5;
remainderTimeStamp = 0;
SharedPreferences.Editor editor = settings.edit();
editor.putInt("livesTotal1", livesCount);
editor.putLong("remainderTimeStamp1", remainderTimeStamp);
editor.commit();
livesCountTV.setText(c.getResources().getString(R.string.livesCount) + " " + livesCount);
livesCounterTV.setText(c.getResources().getString(R.string.livesCounter) + " FULL!");
}
});
no.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
dialog.dismiss();
}
});
dialog.show();
}
// listener that's called when we finish querying the items and subscriptions we own.
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if(result.isFailure()) {
complain(c.getResources().getString(R.string.sorryerror) + c.getResources().getString(R.string.failedtoquery) + " " + result);
return;
} else if(inventory.hasPurchase(SKU_BUYLIVES)) {
mHelper.consumeAsync(inventory.getPurchase(SKU_BUYLIVES), null);
}
}
};
// callback for when a purchase is finished
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
// this appears to the user immediately after purchasing.
if(result.isFailure()) {
complain(c.getResources().getString(R.string.sorryerror) + result);
} else if(purchase.getSku().equals(SKU_BUYLIVES)) {
alert(c.getResources().getString(R.string.livesbought));
try {
Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
// success
Toast.makeText(Levels.this, "SUCCESS", Toast.LENGTH_LONG).show();
try {
mService.consumePurchase(3, getPackageName(), SKU_BUYLIVES);
// this Toast is never seen.
Toast t = Toast.makeText(Levels.this, "PURCHASE CONSUMED", Toast.LENGTH_LONG);
t.setGravity(Gravity.CENTER, 0, 0);
t.show();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
// error
// this Toast is never seen.
Toast.makeText(Levels.this, "ERROR", Toast.LENGTH_LONG).show();
}
} catch (RemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return;
}
};
void complain(String message) {
alert("Error: " + message);
}
void alert(String message) {
AlertDialog.Builder bld = new AlertDialog.Builder(this);
bld.setMessage(message);
bld.setNeutralButton("OK", null);
bld.create().show();
}
#Override
public void onDestroy() {
super.onDestroy();
if(mHelper != null) mHelper.dispose();
mHelper = null;
}
}
To open Google Play purchase dialog you should have used startIntentSenderForResult() method with your purchase intent. Once user is done with this dialog, onActivityResult() gets called on your activity. This is the place where you should verify the purchase and update GUI if needed.
This is an example of how you open purchase dialog.
public void buyProduct() {
PendingIntent buyIntent = ... // create your intent here
IntentSender sender = buyIntent.getIntentSender();
try {
startIntentSenderForResult(sender, REQ_BUY_PRODUCT, new Intent(), 0, 0, 0);
} catch (SendIntentException e) {
Log.e(TAG, "", e);
}
}
This is example of how to handle purchase intent
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_BUY_PRODUCT && resultCode == Activity.RESULT_OK) {
// here you verify data intent and update your GUI
...
return;
}
}
Both methods belong to your activity.

Categories

Resources