I have the following problem: My app uses a function which executes all HTTP calls. As a quick fix I'd like to show the user a toast message whenever there is an ConnectionTimeout.
The problem is that this executeHttp() is called from several AsyncTasks and I can't figure out how to get the required context.
I read something about runOnUiThread but this also didn't seem to work for me...
Any ideas?
Thanks!
Update:
I'd like to have a solution which I can use in my executeHttp() function because else I have do add this code in 100 different places... Is this possible?
First, implement a Method to show a Toast to your activity:
class MyActivity extends Activity {
// some stuff
public void showToast(String text, int duration) {
Toast toast = Toast.makeText(this.getBaseContext(), text, duration);
toast.show();
}
}
The let your AsyncTask hold a reference to the activty which can then be called in the onProgressUpdate Method:
class MyAsyncTask extends AsyncTask {
MyActivity activity;
public MyAsyncTask(MyActivity a)
this.activity = a;
}
#Override
protected Object doInBackground(String... params) {
try {
// do your stuff here
} catch (ConnectionTimeoutException e) {
publishProgress("timeout");
}
#Override
protected void onProgressUpdate(String... values) {
if(values[0].equals("timeout")
activity.showToast("Ups, we have a timeout!", Toast.LENGTH_LONG); }
}
}
}
EDIT ------------
If you want it in your executeHttp() method, you have to pass the Context to it in order to show a Toast:
public ReturnValue executeHttp(Context context) {
try {
// ...
} catch(ConnectionTimeoutException e) {
Toast t = Toast.makeToast(context, message, duration);
t.show();
}
}
summary: no available context -> no toast
Related
I'm trying to take some action after a TextToSpeech object in my Android app finishes speaking a sentence, but my UtteranceProgressListener.onDone() method is never called. I tried many things, including the suggestions from this post, but nothing has worked. Relevant code from my app is posted below. The TextToSpeech object correctly speaks the sentence I give it, but none of the callback functions in UtteranceProgressListener are called. Can someone please help me identify what's wrong? For example, should the utterance ID I provide to the TextToSpeech.speak() function need to be in some special format that I'm missing?
mtts = new TextToSpeech(myAct, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
mtts.setLanguage(Locale.US);
}
}
});
mtts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onDone(String utteranceId) {
Toast.makeText(myAct, "OnDone called", Toast.LENGTH_LONG).show();
}
#Override
public void onError(String utteranceId) {
Toast.makeText(myAct, "OnError called", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(String utteranceId) {
Toast.makeText(myAct, "OnStart called", Toast.LENGTH_LONG).show();
}
});
Bundle params = new Bundle();
params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
myAct.mtts.speak(myText, TextToSpeech.QUEUE_FLUSH, params, "MyID");
Look at logcat, your code has probably fired: android.view.ViewRootImpl$CalledFromWrongThreadException
If you want to do some GUI-thread stuff, use handler and runnable like this:
public void onDone(String utteranceId) {
Log.v(TAG, "Speaking done"); // this is OK
// This is GUI-thread part
final View v = findViewById(R.id.txtStatus);
v.getHandler().post(new Runnable() {
#Override
public void run() {
txtStatus.setText("Speaking done");
}
});
}
And to start TTS speaking:
tts.speak("bla bla bla", TextToSpeech.QUEUE_FLUSH, null, "1");
If you want to add the call back UtteranceProgressListener, you have to give TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID as the utteranceId
It would look like this:
myAct.mtts.speak(myText, TextToSpeech.QUEUE_FLUSH, null, TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID);
See this post:
UtteranceProgressListener does not return error message
and check the engine web site: TTS Engine
I've created a simple class for my Android application called coreTuts. I'm done with tying it in to my MainActivity.java, activity_main.xml, and so on, like this:
MainActivity.java
coreTuts tuts = new coreTuts();
public void displayToast(View view)
{
tuts.sampleToast();
}
This is what my coreTuts.java looks like:
coreTuts.java
public class coreTuts{
//Do a toast notification
public void sampleToast()
{
Toast toast = Toast.makeText(getActivity().getApplicationContext(),
"This is a message displayed in a Toast",
Toast.LENGTH_SHORT);
toast.show();
}
}
I couldn't decide whether I should usegetActivity().getApplicationContext()or just getApplicationContext() on my Toast because either code doesn't work.
In fact, these are my questions:
I understand contexts in Android are kinda like habitats to animals. Am I right if I look at getActivity() and getApplicationContext() that way?
How do I make getApplicationContext() work in another class so that I can run my toast, or is that even allowed?
Thank you!
your coreTuts should be like below
public class coreTuts{
//Do a toast notification
public void sampleToast(Context context)
{
Toast toast = Toast.makeText(context,
"This is a message displayed in a Toast",
Toast.LENGTH_SHORT);
toast.show();
}
}
and you can invoke it like below,
coreTuts tuts = new coreTuts();
public void displayToast(View view)
{
tuts.sampleToast(view.getContext());
}
Note: view cannot be null
As your class CoreTuts is not inheriting from Activity nor any other Context subclass (Activity is a child of Context) you can't access to your context the way you are trying to. You need to explicitly pass it to your sampleToast method, like this:
public class coreTuts{
//Do a toast notification
public void sampleToast(Context context) {
Toast toast = Toast.makeText(context,
"This is a message displayed in a Toast",
Toast.LENGTH_SHORT);
toast.show();
}
}
And in your activity:
coreTuts tuts = new coreTuts();
public void displayToast(View view) {
// Pass your activity as the context
tuts.sampleToast(this);
}
Pass a context to your coretuts class when you're creating it's object. Your coretuts class would look like this.
public class coreTuts{
private Context mContext;
public coreTuts(Context context) {
mContext = context;
}
//Do a toast notification
public void sampleToast()
{
Toast toast = Toast.makeText(mContext,
"This is a message displayed in a Toast",
Toast.LENGTH_SHORT);
toast.show();
}
}
Now, when you're creating an object of this class inside your MainActivity, simply pass the context
// Pass your context. You can also use getApplicationContext() instead of MainActivity.this
coreTuts tuts = new coreTuts(MainActivity.this);
// You don't really need a view argument for this method.
// It could just be public void displayToast() {...}
public void displayToast(View view)
{
tuts.sampleToast();
}
Excuse me if my question is similar to others, but i have not got the solution.
I have two classes, MainActivity and SMSMonitorService.
AsyncTask is an inner class of MainActivity.
I want get the onPostExecute result and send it by SMS. The method sendReplySMS is on SMSMonitorService.
MainActivity.java
public class MainActivity extends ActionBarActivity {
//some code...
public class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
//Extract String between two delimiters
String finalResult = StringUtils.substringBetween(result, "extract\":\"", "\"}}}}");
String finalResponse = StringEscapeUtils.unescapeJava(finalResult);
textView.setText(finalResponse);
SMSMonitorService.sendReplySMS(SMSMonitorService.number, finalResponse); //sendReplySMS and number are declared static
}
}
SMSMonitorService.java
public class SMSMonitorService extends Service {
//some code...
public static void sendReplySMS(String number, String responseText) {
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(number, null, responseText, null, null);
}
//some code..
The SMS never send.
How i can send a SMS what contain onPostExecute result?
Thank you very much for your help.
SMSMonitorService is a Service not a normal java class so you need to use startService method to start service for sending sms. do it as :
Prepare Intent in onPostExecute method for sending all values to SMSMonitorService :
#Override
protected void onPostExecute(String result) {
//....your code
Intent intent = new Intent(CurrentActivity.this,SMSMonitorService.class);
intent.putExtra("finalResponse", finalResponse);
startService(intent);
}
and in SMSMonitorService Service use
#Override
public int onStartCommand( Intent intent , int flags , int startId )
{
super.onStartCommand(intent, flags , startId);
String finalResponse = intent.getStringExtra("finalResponse");
if( extras != null )
sendReplySMS(SMSMonitorService.number, finalResponse);
return START_REDELIVER_INTENT;
}
Make sure you have added SMSMonitorService Service in AndroidManifest.xml
NOTE: Use IntentService instead of Service because IntentService stop self when task done. for more information see IntentService
I am encountering a problem in my Android application. I am creating a currency converter. I need to create a progressdialog that appears when you convert a value from one currency to another.
Here is part of my code:
if (text1.equals("US Dollar - USD") && text2.equals("Euro - EUR") && edittextdollars.length() > 0 && edittexteuros.length()==0) {
dialog1 = ProgressDialog.show(getActivity(), "", "Calculating...");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try{
convertvalues("USD", "EUR");
handler.sendEmptyMessage(0);
}
catch (Exception e) {
edittexteuros.setText("Error");
}
}
});
thread.start();
}
private Handler handler = new Handler () {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
dialog1.dismiss();
break;
}
}
};
The progressdialog comes up and goes away, but nothing happens in the background. Here are a few pics of what my app looks like:
This is before the progressdialog comes.
When I press calculate:
After the progressdialog finishes:
As you can see, after the progressdialog goes away, my values don't convert.
In my code,
convertvalues("USD", "EUR");
just gets actual currency value from the internet and multiplies it with the value in my edittext. There is nothing wrong with it and it worked without the progressdialog. I have tested it many times myself.
What am I doing wrong here? I have checked Google for over a week, but I could not find a single solution. Any help regarding this problem is greatly appreciated.
Just like how you update your progressdialog in a handler, you must also update EditTexts in the handler (as it must run on the UI thread). So ideally you would return the result from convertvalues and then pass it to the handler via a message.
From what I can see, your code is fine but you aren't updating the TextView/EditText values when you dismiss the dialog. This means that although it looks like nothing is happening, it actually is - you just aren't updating to see the results.
So, assuming convertvalues() has the converted values stored somewhere, before you call dismiss() you should set your TextViews based on those values.
you can use asynctask in android
see following code may be it will help you..
private class asyncTask extends AsyncTask<Void, Void, Boolean>
{
Context context;
ProgressDialog pd;
asyncTask(Context context)
{
this.context = context;
pd = new ProgressDialog(activityContext);
}
protected void onPreExecute()
{
pd.setTitle("Loading..");
pd.setMessage("Please wait ...");
pd.setCancelable(false);
pd.show();
}
protected void onPostExecute(Boolean result)
{
if(pd.isShowing()) pd.dismiss();
}
#Override
protected Boolean doInBackground(Void... params)
{
convertvalues();
return boolean_value;
}
}
And Just Call this asynctask with
new asyncTask(Your_Context).execute();
Please see this before for context: Anonymous Uploading File object to Imgur API (JSON) gives Authentication Error 401 (it has the code for doInBackground() method in case anyone is interested)
Using an AsyncTask class, I am uploading an image to Imgur. The uploading process is done within doInBackground() method. It returns String link to onPostExecute which should display the link in the form of a Toast message.
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), "Uploaded! Link: " + result, Toast.LENGTH_SHORT).show();
}
However, doing this gives the following error:
The method getApplicationContext() is undefined for the type UploadToImgurTask
Trying to copy the return string to the clipboard gives a similar issue.
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", "Text to copy");
clipboard.setPrimaryClip(clip);
}
The method getSystemService(String) is undefined for the type UploadToImgurTask
#Raghunandan is right. So, inside your UploadToImgurTask class you can have:
private Context context;
//in constructor:
public UploadToImgurTask(Context context){
this.context=context;
}
Then in onPostExecute you can simply use:
Toast.makeText(context, "Uploaded! Link: " + result, Toast.LENGTH_SHORT).show();
Hope this helps you.
In place of getApplicationContext(), use AsyncTask's Parent class name with ".this" like MyActivity.this if it extends from Activity
Otherwise use getActivity(). Hoping your problem will be solved with this
try this code
public static void pushprofList(Activity context){
static Context = mConext;
protected void onPostExecute(String result) {
Toast toast=Toast.makeText(mConext,"Succefully Updated Profile",Toast.LENGTH_LONG);
toast.show();
}
}
this working completely and display toast message.