I have an issue similar to Toast from FileObserver. However, I do not understand how to properly implement the Handler.
Currently, I have a FileObserver-class and I am passing it context and a handler (context comes from getApplicationContext() from the service I call the FileObserver-class from). The handler I pass in (handle) is defined and created in the service. In the onEvent() of the FileObserver-class, I have:
handle.post(new Runnable() {
public void run() {
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
});
But, I end up with a java.lang.NullPointerException.
How do I properly make the toast notification show up when I send it from the onEvent() of the FileObserver-class?
Related
I am trying to make a simple android app in which there is a toast message containing the number of the incoming call. I have stored the number in a string variable. When I display just the toast, it works fine but before the toast, if I add a simple if condition comparing the number to another string, the app quits. The required permissions are given. Can someone help me?
This Works:
public void onReceive(Context context, Intent intent) {
String incomingNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, incomingNumber, Toast.LENGTH_LONG).show();
}
This Does not Work (App quits)
public void onReceive(Context context, Intent intent) {
String incomingNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(incomingNumber.equals("+919999999999"))
{
Toast.makeText(context, "Call from Mom", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(context, incomingNumber, Toast.LENGTH_LONG).show();
}
}
It sounds a little silly but I just wrapped my "if" condition in a try-catch block and it solved the problem. I am not used to programming in JAVA so it took me a lot to figure out this simple thing. Thank You All for providing me with suggestions :)
I made a method to make sure my toast messages will be displayed immediately, without having to wait the previous toast to dissapear. The method :
public void myToaster(String message){
if(mToast!=null){
mToast.cancel();
}
mToast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
I'm using Android Studio with API23.
mToast is never assigned/reassigned . This
mToast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
should be
mToast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
mToast.show();
Toast.cancel doesn't remove the current Toast immediately. The fade out animation takes place nevertheless
So my goal is to only have a toast message shown to the user if there is no toast message showing or if the message showing is NOT the same as the message I want to send. If the message IS the same as the one being shown to the user, I don't want the message to go through (because that is pointless).
To work towards this goal, I found this post on how to only show a toast if none are being shown.
I have modified the code to fit both requirements.
private Toast toast;
public void showAToast (String st, boolean isLong){
try{
toast.getView().isShown();
String text = ((TextView)((LinearLayout)toast.getView()).getChildAt(0)).getText().toString();
if(!text.equalsIgnoreCase(st)){
//New message, show it after
if(isLong){
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_LONG);
} else {
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_SHORT);
}
toast.show();
}
} catch (Exception e) {
//New message
if(isLong){
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_LONG);
} else {
toast = Toast.makeText(getApplicationContext(), st, Toast.LENGTH_SHORT);
}
toast.show();
}
}
My issue is that any message will not go through if the last toast message was the same as the message that wants to go through.
Not sure exactly why this occurs, but I put some debugging messages in the method to figure out what the issue was.
The messages say that toast.getView().isShown() does not throw the exception (suppose to mean no toast is shown) if any toast message has been sent in the app's lifetime.
So my question is, how can I work around this? Surely there must be a way to achieve this desired functionality.
I saw this before in stackoverflow, but it's not nearly as clean as I would have liked. We implemented a dual toast approach, where it alternates between two toasts. First we define the toasts for the activity prior to the OnCreate:
Toast toast0;
Toast toast1;
private static boolean lastToast0 = true;
In the OnCreate:
toast0 = new Toast(getApplicationContext());
toast0.cancel();
toast1 = new Toast(getApplicationContext());
toast1.cancel();
//And finally, when I need to display the toast and cancel the prior toast at the same time I use something similar to:
if (lastToast0) {
toast0.cancel();
toast1.setDuration(Toast.LENGTH_LONG);
toast1.setText("new message");
toast1.show();
lastToast0 = false;
} else {
toast1.cancel();
toast0.setDuration(Toast.LENGTH_LONG);
toast0.setText("new message");
toast0.show();
lastToast0 = true;
}
// If you need to just cancel an existing toast (before it times out) use:
toast0.cancel();
toast1.cancel();
Quotation
You can use the same Toast instance to show message. If the message is same, the toast will no show twice time, otherwise the text will simple change to the latest one.
Toast mToast;
public void showToast(CharSequence message, int during){
if (mToast == null) {
mToast = Toast.makeText(getApplicationContext(), message, during);
} else {
mToast.setText(message);
}
mToast.show();
}
--↓---↓----↓---update--↓----↓---↓--↓
Sorry about that I miss your point above.
I read the source of Toast that we cannot get the view status since the view had been add to the WindownManager.So far, I cannot find out a method to point whether the Toast is shown.
But you can achieve your own Toast use Service,which likes a toast shown above the application. it may be easier.
i was trying the NotificationListener to get the coming notifications. Two days ago my class was an activity and everything works fine. The service started and the notification came up in my view with the title, icon and the description of it. Yesterday i implemented the new Navigation View, so, i changed the activity to fragment. After that the notification not showing up. The service starts but if i try to debug the Broadcastreceiver (that is inside the fragment) doesn't work. If i try to create some log inside it they not works. I suppose that the Broadcastreceiver not starts at this point! This is the Broadcastreceiver
/**
* Broadcast receiver notifications
***/
private BroadcastReceiver onNotice= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String pack = intent.getStringExtra("package");
String title = intent.getStringExtra("title");
String text = intent.getStringExtra("text");
if(!pack.equals("") || !title.equals("") || !text.equals("")) {
notificationLayout.setVisibility(View.VISIBLE);
notificationTitle.setText(title);
notificationDescription.setText(text);
try {
icon = getActivity().getPackageManager().getApplicationIcon(pack);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
notificationImage.setImageDrawable(icon);
} else {
notificationLayout.setVisibility(View.INVISIBLE);
}
}
};
and in my onResume() method of the fragment i wrote this:
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onNotice, new IntentFilter("Msg"));
I don't know if the change of the class type is the reason of this issue but it's the only change i made.
AlertDialog from within BroadcastReceiver? Can it be done? I am working on a app that will pop up a Dialog box if I get SMS message. I am trying to code this within a BroadcaseReceiver. But I cant use this line of code AlertDialog.Builder builder = new AlertDialog.Builder(this);. Can someone please help me with a hint!
public class SMSPopUpReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "SMSReceiver";
public static final int NOTIFICATION_ID_RECEIVED = 0x1221;
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
public void onReceive(Context context, Intent intent) {
Log.i(LOG_TAG, "onReceive");
if (intent.getAction().equals(SMSPopUpReceiver.ACTION)) {
StringBuilder sb = new StringBuilder();
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
for (Object pdu : pdus){
SmsMessage messages =
SmsMessage.createFromPdu((byte[]) pdu);
sb.append("Received SMS\nFrom: ");
sb.append(messages.getDisplayOriginatingAddress());
sb.append("\n----Message----\n");
sb.append( messages.getDisplayMessageBody());
}
}
Log.i(SMSPopUpReceiver.LOG_TAG,
"[SMSApp] onReceiveIntent: " + sb);
Toast.makeText
(context, sb.toString(), Toast.LENGTH_LONG).show();
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
}
}
Principal issue: try to avoid placing time consuming functionalities into BroadcastReceiver. It should just receive and initiate further processing in bound Activity/Service.
UPDATE:
Please check following sources that might be helpful:
Similar questions on StackOverflow:
How to send data from BroadcastReceiver to an Activity in android?
Android SMS receiver not working
Android SDK demo example:
android-sdk-windows\samples\android-8\ApiDemos\src\com\example\android\apis\os\SmsMessagingDemo.java
And of course standard Android API documentation: http://developer.android.com/reference/android/content/BroadcastReceiver.html
UPDATE2:
Added app skeleton as it should look. Please note that no content view is defined. It is because your app will have transparent screen. To achieve that
#android:style/Theme.Translucent
is entered under Theme tag for this activity in AndroidManifest.xml.
public class NotifySMSReceived extends Activity
{
private static final String LOG_TAG = "SMSReceiver";
public static final int NOTIFICATION_ID_RECEIVED = 0x1221;
static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION);
this.registerReceiver(mReceivedSMSReceiver, filter);
}
private void displayAlert()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?").setCancelable(
false).setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
}).setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private final BroadcastReceiver mReceivedSMSReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION.equals(action))
{
//your SMS processing code
displayAlert();
}
}
};
}
I've been looking into it and the documentation of the BroadcastReceiver actually says:
public abstract void onReceive
(Context context, Intent intent)
Since: API Level 1 This method is
called when the BroadcastReceiver is
receiving an Intent broadcast. During
this time you can use the other
methods on BroadcastReceiver to
view/modify the current result values.
The function is normally called within
the main thread of its process, so you
should never perform long-running
operations in it (there is a timeout
of 10 seconds that the system allows
before considering the receiver to be
blocked and a candidate to be killed).
You cannot launch a popup dialog in
your implementation of onReceive().
You cannot launch a popup dialog in
your implementation of onReceive()
So it seems it is not possible
This is late but this may help someone.
You cannot use alert dialog inside broadcast receiver, we can use this only in activity or service. Try like this
In your onReceive method of broadcastreceiver add
Intent i = new Intent(context, yourclass.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
and in yourclass set your dialog message, so that it will appear when you trigger the receiver event. I tried this and it worked me. Hope this may help some one :-)
you can create a new transparent activity and then create Alert Dialog in that activity, whenever your alert is to be displayed call that activity from your broadcast reciever ,this could work, not tested
replace the word "this" inside the AlertDilaog with "context" -- the first parameter on you onRecieve method.
public void onReceive(Context context, Intent intent)