I'm working on a POST API using okhttp library. Everything is working fine except I'm unable to find a way to show a simple toast message on it's success callback. How can I call a toast message to the user so he knows wether data is posted on server or not in the success and failure callbacks?
P.S the code below is in a different class not in a activity class.
This is my code:
public DataSource(Context context) {
this.mContext = context;
mDbHelper = new DBHelper(mContext);
mDatabase = mDbHelper.getWritableDatabase();
}
post(URL, jsonData, new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.i("FAILED", "onFailure: Failed to upload data to server");
//here I want to show toast message
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i("SUCCESSFUL", "onSuccess: data uploaded");
//here I want to show toast message
} else {
Log.i("UN SUCCESSFUL", "onFailure: Failed to upload data to server");
//here I want to show toast message
}
}
});
Every app has its own special thread that runs UI objects such as View objects; this thread is called the UI thread. Only objects running on the UI thread have access to other objects on that thread. Because tasks that you run on a thread from a thread pool aren't running on your UI thread, they don't have access to UI objects. To move data from a background thread to the UI thread, use a Handler that's running on the UI thread or can use android implementation for the same as shown here.
- Case 1
MyActivity.this.runOnUiThread(new Runnable() {
#Override
void run() {
Toast.makeText(MyActivity.this,
"message", Toast.LENGTH_LONG).show();
});
- Case 2
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyActivity.this,
"message", Toast.LENGTH_LONG).show();
}
});
Had it been Main thread you would have used it directly like
Toast.makeText(MyActivity.this,
"message", Toast.LENGTH_LONG).show();
This callback is an asynchronous function, and you can change View just in UI-thread, so Handler will be helpd for you.
....
private final static int MSG_SUCCESS = 0x0001;
private final static int MSG_FAIL = 0x0002;
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
switch(msg.what){
case MSG_SUCCESS:
//Toast success
break;
case MSG_FAIL:
//Toast fail
break;
default:
break;
}
}
};
......
......
if (response.isSuccessful()) {
Log.i("SUCCESSFUL", "onSuccess: data uploaded");
handler.sendEmptyMessage(MSG_SUCCESS);
} else {
Log.i("UN SUCCESSFUL", "onFailure: Failed to upload data to server");
handler.sendEmptyMessage(MSG_FAIL);
}
......
You are getting error
java.lang.RuntimeException: Can't create handler inside thread that
has not called Looper.prepare()
Because you're calling it from a worker thread. You need to call Toast.makeText() (and most other functions dealing with the UI) from within the main thread. You could use a handler,
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i("SUCCESSFUL", "onSuccess: data uploaded");
context.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(context, "SUCCESSFUL", Toast.LENGTH_SHORT).show();
}
});
}
Just send the context of your activity while calling this method:
void methodName(Context c){
post(URL, jsonData, new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.i("FAILED", "onFailure: Failed to upload data to server");
//here I want to show toast message
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i("SUCCESSFUL", "onSuccess: data uploaded");
Toast.makeText(c,"message",Toast.LENGTH_SHORT).show();
//here I want to show toast message
} else {
Log.i("UN SUCCESSFUL", "onFailure: Failed to upload data to server");
//here I want to show toast message
}
}
});
}
Try this
TaskActivity.this.runOnUiThread(new Runnable() {
#Override
void run() {
Toast msg = Toast.makeText(TaskActivity.this,
"message", Toast.LENGTH_LONG);
msg.show();
});
Try this
Toast.makeText(YourActivity.this, "Your Message", Toast.LENGTH_SHORT).show();
Activity
post(URL, jsonData, new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.i("FAILED", "onFailure: Failed to upload data to server");
//here I want to show toast message
Toast.makeText(YourActivity.this, "Your Message", Toast.LENGTH_SHORT).show();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i("SUCCESSFUL", "onSuccess: data uploaded");
//here I want to show toast message
Toast.makeText(YourActivity.this, "Your Message", Toast.LENGTH_SHORT).show();
} else {
Log.i("UN SUCCESSFUL", "onFailure: Failed to upload data to server");
//here I want to show toast message
Toast.makeText(YourActivity.this, "Your Message", Toast.LENGTH_SHORT).show();
}
}
});
Fragment
post(URL, jsonData, new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.i("FAILED", "onFailure: Failed to upload data to server");
//here I want to show toast message
Toast.makeText(getActivity(), "Your Message", Toast.LENGTH_SHORT).show();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.i("SUCCESSFUL", "onSuccess: data uploaded");
//here I want to show toast message
Toast.makeText(getActivity(), "Your Message", Toast.LENGTH_SHORT).show();
} else {
Log.i("UN SUCCESSFUL", "onFailure: Failed to upload data to server");
//here I want to show toast message
Toast.makeText(getActivity(), "Your Message", Toast.LENGTH_SHORT).show();
}
}
});
Edit
Handler handler = new Handler();
handler.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(mContext, "Your Message", Toast.LENGTH_SHORT).show();
}
});
Related
I am trying to create basic WebSocket server with this library.
I want to make a toast message when a message is received.
In onMessage() function below I have implemented that. But no toast message is happening.
But Received message is printed on console.
WebSocketServer ws = new WebSocketServer(new InetSocketAddress(3000)) {
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conn.send("Hello world");
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
}
#Override
public void onMessage(WebSocket conn, String message) {
System.out.println("Recieved: "+message);
Toast.makeText(MainActivity.this, "Recieved: " + message, Toast.LENGTH_SHORT).show();
}
#Override
public void onError(WebSocket conn, Exception ex) {
}
#Override
public void onStart() {
}
};
ws.start();
}
I think you have to switch to the UI thread to show the Toast.
You can try using a Handler:
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Received: " + message, Toast.LENGTH_SHORT).show();
}
});
Or calling runOnUiThread:
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "Received: " + message, Toast.LENGTH_SHORT).show();
}
});
Or broadcasting the message:
#Override
public void onMessage(WebSocket conn, String message) {
System.out.println("Recieved: "+message);
Intent intent = new Intent("msgReceived");
intent.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
And registering a BroadcastReceiver in your Activity:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getExtras().getString("message");
Toast.makeText(MainActivity.this, "Received: " + message, Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("msgReceived"));
#Override
protected void onStop() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onStop();
}
I want to make a toast but the Toast doesn't get printed
Request r = new Request.Builder().url(url).build();
client.newCall(r).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Toast.makeText(Login.this, "password wrong", Toast.LENGTH_LONG).show();
}
Every UI update in android has to be executed in UI thread:
Run the following code in onFailure
Login.this.runOnUiThread(new Runnable() {
#Override
public void run() { Toast.makeText(Login.this, "password wrong", Toast.LENGTH_LONG).show();
}
});
I want to dial and get the dialed USSD code response. Here is my code. but when I run it doesn't show any response on the toast.
private void ussdResponse(String completeCode) {
TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED || checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, requestCode);
ActivityCompat.requestPermissions(MainActivity.this , new String[]{Manifest.permission.READ_PHONE_STATE},requestCode);
return;
}
manager.sendUssdRequest(completeCode, new TelephonyManager.UssdResponseCallback() {
#Override
public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
super.onReceiveUssdResponse(telephonyManager, request, response);
Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "USSD Result"+response.toString(), Toast.LENGTH_LONG).show();
}
#Override
public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode);
Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "USSD Response Failed.", Toast.LENGTH_SHORT).show();
}
}, new Handler());
}
compleCode contains the USSD Code. But the Toast shows Nothing.
can any one please find me the solution.? Or is there any other way to get the dialed USSD response in my app?
I found the answer myself. I Used this Api to resolve the problem.
https://github.com/romellfudi/VoIpUSSD
Here is my code:
HashMap map = new HashMap<>();
map.put("KEY_LOGIN",new HashSet<>(Arrays.asList("espere", "waiting", "loading", "esperando")));
map.put("KEY_ERROR",new HashSet<>(Arrays.asList("problema", "problem", "error", "null")));
final USSDApi ussdApi = USSDController.getInstance(MainActivity.this);
ussdApi.callUSSDInvoke("*786#", map, new USSDController.CallbackInvoke() {
#Override
public void responseInvoke(String message) {
// message has the response string data
String dataToSend = "data";// <- send "data" into USSD's input text
ussdApi.send(dataToSend,new USSDController.CallbackMessage(){
#Override
public void responseMessage(String message) {
// message has the response string data from USSD
Log.d("message", message);
}
});
}
#Override
public void over(String message) {
// message has the response string data from USSD or error
// response no have input text, NOT SEND ANY DATA
}
});
I have two class. One is my SettingsActivity and a class where my volley does the work. In my web service it has a lot of data where it needed to be converted to an ArrayList and will be saved to my Database; I have a two web service to be call after the first one is done before the second one will start it is delayed 1 second. After those things it in my Log it always displays the following
I/Choreographer: Skipped 226 frames! The application may be doing too much work on its main thread.
V/RenderScript: 0x5595d9d0e0 Launching thread(s), CPUs 8
W/art: Suspending all threads took: 20.500ms
W/SQLiteConnectionPool: A SQLiteConnection object for database '/data/data/com.app.myapp/databases/myDB.sqlite' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
I/art: Background partial concurrent mark sweep GC freed 38249(2025KB) AllocSpace objects, 2(968KB) LOS objects, 40% free, 16MB/26MB, paused 569us total 130.628ms
I/Choreographer: Skipped 1528 frames! The application may be doing too much work on its main thread.
I already check if my database is close after using and all of it is closed. But I'm still having the database is leaked message and Skipped xxx frames. I already tried to create a new thread where I call my class in my SettingsActivity when calling the class for my Volley like
btnSync.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
Thread thread = new Thread(new Runnable(){
#Override
public void run(){
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});
}
});
After trying this I encounter Can't create handler inside thread that has not called Looper.prepare()
Then also tried using this
runOnUiThread(new Runnable() {
#Override
public void run() {
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});
But this I'm having an the message Skipped frames. How to solve it? Thank you so much in advance for the help.
In my Paramater class I'm also calling ProgressDialog.
Here's my code for Paramter.parameterOneVolley
public static void parameterOneVolley(final Activity activity, final Context context) {
final ProgressDialog pd = new ProgressDialog(activity);
pd.setMessage("Fetching data....");
pd.show();
initializeDatabase(context);
sqLiteAdapter = new SQLiteAdapter(activity);
regionList = new ArrayList<Region>();
divisionList = new ArrayList<Division>();
final Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray regionArr = response.getJSONArray("Region");
JSONArray divisionArr = response.getJSONArray("Division");
sqLiteAdapter.openToRead();
for(int i = 0; i < regionArr.length(); i++){
JSONObject regionObj = (JSONObject) regionArr.get(i);
Region region = new Region(regionObj.getInt("RegionId"),regionObj.getString("Region"));
regionList.add(region);
if(regionList.size()!=0) {
sqLiteAdapter.insertOrReplaceRegion(regionList);
}
}
for(int i = 0; i < divisionArr.length(); i++){
JSONObject divisionObj = (JSONObject) divisionArr.get(i);
Division division = new Division(divisionObj.getInt("RegionId"),divisionObj.getInt("DivisionId"),divisionObj.getString("Division"));
divisionList.add(division);
if(divisionList.size()!=0) { sqLiteAdapter.insertOrReplaceDivision(divisionList);
}
}
sqLiteAdapter.close();
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
sqLiteAdapter.close();
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
Toast.makeText(context,
e.getMessage(), Toast.LENGTH_SHORT).show();
}
Toast.makeText(context, "Successfully synced.", Toast.LENGTH_SHORT).show();
//call next web service
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
parameterTwoVolley(activity, context);
}
}, 1000);
}
};
final Response.ErrorListener errorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
if (error.networkResponse != null) {
Log.d(TAG, "Error Response code: " + error.networkResponse.statusCode);
Toast.makeText(context, error.networkResponse.statusCode, Toast.LENGTH_SHORT).show();
}
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Log.d(TAG, "Error Response code: Timeout/NoConnection");
Toast.makeText(context, "Timeout/NoConnection", Toast.LENGTH_SHORT).show();
} else if (error instanceof AuthFailureError) {
Log.d(TAG, "Error Response code: AuthFailureError");
Toast.makeText(context, "AuthFailureError", Toast.LENGTH_SHORT).show();
} else if (error instanceof ServerError) {
Log.d(TAG, "Error Response code: ServerError");
Toast.makeText(context, "ServerError", Toast.LENGTH_SHORT).show();
} else if (error instanceof NetworkError) {
Log.d(TAG, "Error Response code: NetworkError");
Toast.makeText(context, "NetworkError", Toast.LENGTH_SHORT).show();
} else if (error instanceof ParseError) {
Log.d(TAG, "Error Response code: ParseError");
Toast.makeText(context, "ParseError", Toast.LENGTH_SHORT).show();
}
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
}
};
}
I tried adding
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
pd = new ProgressDialog(activity);
pd.setMessage("Fetching data....");
pd.show();
}
}
});
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
if(pd != null && pd.isShowing()) {
pd.dismiss();
}
Toast.makeText(context, "Successfully synced.", Toast.LENGTH_SHORT).show();
}
});
every time I'm using Progress Dialog and Toast but I still encountering Skipped frames
Also tried using ProgressBar instead and show and hide it but still encountering skipped frames
In Android, only the Main thread (also called the UI thread) can update views. This is because in Android the UI toolkit s not thread safe.
When you try to update the UI from a worker thread Android throws this exception. If you want to update the UI from another Thread use Handler.
final Handler handler=new Handler();
new Thread(new Runnable() {
#Override
public void run() {
//your code
handler.post(new Runnable() {
#Override
public void run() {
Parameter.parameterOneVolley(SettingsActivity.this, getApplicationContext());
}
});
}
}).start();
I have done the task on "Inviting users to the app using facebook" in android, used the below codes as a result if i send the invitation, the invite message rarely delivers after many hours and or else not getting delivered, do anybody know the solution for this?
final ImageView facebook1 = (ImageView) findViewById(R.id.facebook1);
facebook1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
Facebook mFacebook = new Facebook( APP_ID );
Bundle params = new Bundle();
params.putString("message", "Prova ");
mFacebook.dialog(Singlemenuitem.this, "apprequests", params, new DialogListener() {
public void onComplete(Bundle values) {
Toast toast = Toast.makeText(getApplicationContext(), "Done",
Toast.LENGTH_SHORT);
toast.show();
}
public void onFacebookError(FacebookError error) {
Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
Toast.LENGTH_SHORT).show();
}
public void onCancel() {
Toast toast = Toast.makeText(getApplicationContext(), "App request cancelled",
Toast.LENGTH_SHORT);
toast.show();
}
public void onError(DialogError e) {
// TODO Auto-generated method stub
}
});
} });