I am using dronekit-android packages that can successfully connect to PX4 board. However, I try to receive the mavlink message in a while 1 thread, the receive API addMavlinkObserver causes the system crash.
After the drone is connected, I simply call this function upon pressing a button and it crashes.
this.drone.addMavlinkObserver(new MavlinkObserver() {
#Override
public void onMavlinkMessageReceived(MavlinkMessageWrapper mavlinkMessageWrapper) {
//Log.d("Received Mavlinks:", mavlinkMessageWrapper.getMavLinkMessage().toString());
Toast.makeText(getApplicationContext(), "MAV receive " + mavlinkMessageWrapper.getMavLinkMessage().toString(),Toast.LENGTH_LONG).show();
}
})
Does anyone have any idea?
I use Toast to indicate my app's state. And I use the following code in order to control toast showing time.
Toast noCardDetectedToast=null;
void setVisibilityNoCardDetectedToast(boolean visible)
{
if(visible)
{
if(noCardDetectedToast==null)
noCardDetectedToast = Toast.makeText(this, R.string.msg_no_card_detected, Toast.LENGTH_SHORT);
noCardDetectedToast.show();
}
else
{
if(noCardDetectedToast!=null)
{
noCardDetectedToast.cancel();
noCardDetectedToast=null;
}
}
}
When it's necessary to show this Toast, the application starts invoking setVisibilityNoCardDetectedToast(true) several times per second.
And when the application doesn't need this toast any more, it invokes setVisibilityNoCardDetectedToast(false).
Everything works fine, but my android device does not fall asleep, as long as the toast is visible.(I tested my application on Android 4.x and 5.0)
This behaviour looks strange for me. What do I do wrong here?
I have Button.When the user click the button, there are some condition, that condition is not satisfy then need to display Toast but not showing Toast Message...
Code: Edited
Button addMe = (Button)findViewById(R.id.addMe);
addMe.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(selectedReason.equals("--Select--")){
Log.i("TAG","-----");
Toast.makeText(getBaseContext(), "Reason can not be blank", Toast.LENGTH_SHORT).show();
}else if(selectedType.equals("--Select--")){
Toast.makeText(getParent(), "Discount type can not be blank", Toast.LENGTH_SHORT).show();
}else{
if(selectedType.equals("Value")){
if(spc_amount.getText().toString().equals("")){
Log.i("TAG","-----");
Toast.makeText(getBaseContext(), "Discount type can not be blank", Toast.LENGTH_SHORT).show();
}else{
if(Double.parseDouble(spc_amount.getText().toString()) > invoiceValue){
Toast.makeText(getBaseContext(), "Amonut can not be grater than invoice", Toast.LENGTH_SHORT).show();
}else{
Discount dis = new Discount();
dis.setCriteriaName(selectedReason);
dis.setDiscountValue(Double.parseDouble(spc_amount.getText().toString()));
spDisList.put(1,dis);
tl.removeAllViews();
loadTableLayout();
}
}
}
}
}
});
I have tried context with getParent() , getApplicationContext() , SpecialDiscountActivity.this & getBaseContext() but not working....
This Toast message coming under the Tab Activity Group
Try:
Toast.makeText(getBaseContext(), "Reason can not be blank", Toast.LENGTH_SHORT).show();
It's the .show() that you've omitted everywhere that causes all your toasts to instatiate, but never execute.
Please excuse me if this isn't the solution to your problem, but I accidentally unchecked the 'Show notification' setting of the application once. It may be an idea go into your device settings/application/manager and check this setting.
I think you are missing .show();
It should be...
Toast.makeText(getBaseContext(), "Amount can not be grater than invoice",
Toast.LENGTH_SHORT).show();
Just restart your device! It solved my problem.
Maybe you are not in the UI thread? Try this: http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29
If Toast is not showing that means either you have not called show() method or you are not on UI thread
Ideally, you should create a helper method to show Toast like this on UI thread
/** Execute Toast on UI thread **/
private fun showToast(message: String) {
Handler(Looper.getMainLooper()).post {
// Code here will run in UI thread
Toast.makeText(
this,
message,
Toast.LENGTH_LONG
).show()
}
}
I did like this
Toast.makeText(SalesActivityGroup.group.getParent(), "Amount can not be
grater than invoice", Toast.LENGTH_SHORT).show();
Just bumped across this issue and was wondering how a simple Toast is not appearing. After few trials it struck me to check the notification setting of the app and Voila.
I switched the notification setting ON and it started showing up. I searched and came across the below link, which talks about the same:
https://code.google.com/p/android/issues/detail?id=35013
There could be two possibilities:
1 - You have not append .show(); at the very end of Toast.makeText(getActivity(), "Hi", Toast.LENGTH_SHORT).
2 - There could be situation you are not passing right context
For that try passing getActivity().getApplicationContext();
which in my case resolved the issue.
Good luck :)
Some times Emulator is hanging so restarting the emulator fixes the issue.
Simply restart your emulator not fixed my problem.
Close emulator
Tools -> Avd Manager
In the device list click on "drop-down icon" under "Action" column.
Cold boot now
Now reinstalling the app it will work.
You can use the context of the Activity
like,
Toast.makeText(ActivityName.this,"Reason can not be blank", Toast.LENGTH_SHORT).show()
if this is not working, please put a log.i(); in your each condition may be its going to the last else and you are not getting the Toast.
In my case it was because I wasn't running from Main thread, this fixed it:
val mainActivity = (tabHostActivity.activityContext() as MainActivity)
mainActivity.lifecycleScope.launch{ //Dispatchers.Main, follows lifecycle
Toast.makeText(mainActivity, "my awesome message", Toast.LENGTH_LONG).show()
}
Just Cold boot your device!
It can solve the problem.
Sometimes there may be an error or nullPointerException in the message that we want to print with Toast message. If this error occured then app will simply ignore the Toast message. I had the same issue. I printed the message in Log and found the error, after that I changed the message in Toast. And it worked as I wanted. Try it!!
Android throttles toats so if you send to many they just stop showing up, instead you can use Snackbar:
Snackbar.make(myView, "This is a snack.", Snackbar.LENGTH_SHORT).show();
Try:
Toast.makeText(v.getContext(), "Reason can not be blank", Toast.LENGTH_SHORT).show();
Complimer checks all the code and if there is a critical error, it ignores even the lines before the error section and therfore you will not see the "Toast".
Simply, comment the lines which error happens in them (you can find the error lines in Logcat)
Now you can see the "Toast" and can analyze your problem.
I'm trying to get my user interface to react to events (like button presses, thread completions, etc.) in real time in Android (obviously).
I have a button layout, and one of the buttons is used to copy an unknown number of files from a remote computer using FTP. The FTP part of all this is working very well, but I just cannot find a way to let the user know the state of things:
The states, as I see them are:
1) Selected "Download Files" from "normal" menu.
2) Pressed Confirm (the download process may be quite lengthy and perhaps I don't want to select it by mistake -- however now it's a separate thread so may need to re-think that.
3) Downloading
4) Download complete, restore normal menu
One of the things I hoped would work would be to run the FTP code in a separate thread, and by using the thread.isAlive() construction, wait for the thread to complete and change the display accordingly.
The only thing I haven't been able to do is display that files are downloading. Regardless of what I try, the display jumps from the "Confirm Download" view to the "Normal Menu" view. (Please note, these are not Views as Android defines them in any way.)
Code follows:
Btn.setOnClickListener (new View.OnClickListener()
{
#Override
public void onClick (View v)
{
hideTempWidgets();
Btn01.setVisibility (View.GONE);
Btn02.setVisibility (View.GONE);
Btn03.setVisibility (View.GONE);
verfBtn.setVisibility (View.VISIBLE);
verfBtn.setText ("Press to Verify");
verfBtn.setOnClickListener (null);
verfBtn.setOnClickListener (new View.OnClickListener()
{
#Override
public void onClick (View v)
{
runOnUiThread (new Runnable()
{
public void run()
{
verfBtn.setText ("Downloading...");
}
});
Thread temp = new Thread (new Runnable()
{
public void run()
{
try
{
FileTransfer.getFiles (getAddr().trim());
}
catch (SQLException e)
{ }
}
}, "ftp");
temp.start();
while (temp.isAlive());
verfBtn.setVisibility (View.GONE);
Btn01.setVisibility (View.VISIBLE);
Btn02.setVisibility (View.VISIBLE);
Btn03.setVisibility (View.VISIBLE);
alert (true, VIBE_BLIP);
}
});
}
});
Has anybody faced this and come up with a decent solution??
What's not happening is the setText to "Downloading...", or at least, if it does, not when I want it to and too fast to see... Finally, what's especially frustrating is that that command does work properly when I remove the code to run the FTP thread.
Thanks,
R.
This task seems to be perfect for Async Task. Basically Async Task is a Thread with a built in, thread safe component to allow you to publish updates to the UI and notify when the task is complete.
A popular idea is to show a spinner or progress bar, until the AsyncTask is complete, then dismiss it.
For more information about Async Task see: http://developer.android.com/reference/android/os/AsyncTask.html
I think your mistake is here:
temp.start();
while (temp.isAlive());
The code inside onClick() is already running on graphical Thread, so there is no need for a runOnUIThread() method and you should not block it with the while() statement, which in fact is blocking the UI thread till the Thread completes.
My advice: you can start an AsyncTask instead and update the UI accordingly.
Since it is a very long file transfer, I'd suggest you consider a service to do the work. If you use thread, user will be bound to keep your application on top of others. Otherwise your thread can be just killed. Worst of all, there is not much you can do to prevent user from going to home screen or other application (some tricks are possible but user will be pissed).
If you use service, you can always use notification to show progress and go back to your application.
I am currently trying to integrate a live search functionality in android. I use a customized Autocomplete widget. The widget itself provides me with a threshold to only start a query after a certain amount of characters have been typed in. But what I also want is that a query only starts, say if a user has stopped typing for 2 seconds.
As I load my contents with a AsyncTask I tried blocking the doInBackground function by calling Thread.sleep() right at the beginning. If the user would then continue typing the program would look after an existing task, cancel it and start a new one. This was my idea. But it doesn't quite work the way I expected. Sometimes it sends out queries even if the user is still typing, sometimes queries are canceled after the users stopped typing.
Do you have any ideas on this or maybe a better way to solve this?
Here are the code snippets:
1. The function that is called on text changes:
public void afterTextChanged(Editable s) {
if(mWidget.enoughToFilter()) {
if(mTask != null && mTask.getStatus() != Status.FINISHED) {
mTask.cancel(true);
}
mTask = new KeywordSearchLoader(mActivity,
mItems);
mTask.execute(s.toString());
}
}
2. doInBrackground
try {
Thread.sleep(Properties.ASYNC_SEARCH_DELAY);
} catch (InterruptedException e) {
Log.e(TAG, "the process was interrupted while sleeping");
Log.w(TAG, e);
}
Thanks
Phil
Create a Handler and use .postDelayed(..) to run a background task after some delay.
If user presses the key then call handler.removeCallback(..) and then again .postDelayed(..) to add a new delayed callback.