How to show an alert dialog anywhere in my application? - java

I have an android application where on BaseActivity, I need to check for some logic and trigger to show an alert dialog irrespective of the Activity opened. It means, no matter which activity class I am in, the alert dialog should show up on top of that activity.
Making sure that, all my activities extends BaseActivity.
Below, is my function to show alert dialog
if (activity != null && !activity.isFinishing()) {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext(), R.style.Theme_AppCompat)
.setCancelable(false)
.setMessage("There is some unsynced data. Please connect it to internet and sync it. The user will be logged out if data is not synced for 72 hours")
.setTitle("Attention")
.setPositiveButton("OK", listener);
Dialog dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
dialog.show();
}
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3822)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3854)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:798)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:329)
at com.gmp_manage_v2.ui.activities.BasePrinterActivity.showAlertToSyncData(BasePrinterActivity.java:463)
at com.gmp_manage_v2.ui.activities.BasePrinterActivity.onResume(BasePrinterActivity.java:304)
at com.gmp_manage_v2.ui.activities.ActiveSessionListActivity.onResume(ActiveSessionListActivity.java:470)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1412)
at android.app.Activity.performResume(Activity.java:7300)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3814)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3854) 
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51) 
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:193) 
at android.app.ActivityThread.main(ActivityThread.java:6718) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

You should use current activity context rather than Application context.
Change
new AlertDialog.Builder(getApplicationContext(), R.style.Theme_AppCompat)
to
new AlertDialog.Builder(activity, R.style.Theme_AppCompat)
getApplicationContext() can be used only if you are using dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT) with permission <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Related

App crashes when I call a constructor in an Activity

I am new to android studio and I am trying to build a Notepad app.
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String title = findViewById(R.id.textView3).toString();
String note_content = findViewById(R.id.textView).toString();
FileOutputStream outputStream;
try
{
outputStream = openFileOutput(title, Context.MODE_PRIVATE);
outputStream.write(note_content.getBytes());
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
MainActivity mainActivity = new MainActivity(title);
}
});
This is the button a user clicks to save the note. Once the code saves the note, it should send the Title to MainActivity so that it can be sent to Recycleview Adapter - this will display it in viewholder as a text.
Presently, when I run the code, it crashes - however, when I remove the constructor, the app works fine.
( MainActivity mainActivity = new MainActivity(title);)
Error:
10-02 02:39:13.822 27279-27279/? D/AndroidRuntime: Shutting down VM
10-02 02:39:13.824 27279-27279/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.quicknote, PID: 27279
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.quicknote/com.example.quicknote.MainActivity}: java.lang.InstantiationException: java.lang.Class<com.example.quicknote.MainActivity> has no zero argument constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2337)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.quicknote.MainActivity> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5443) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
10-02 02:39:20.081 27279-27279/com.example.quicknote I/Process: Sending signal. PID: 27279 SIG: 9
As per the error message:
java.lang.InstantiationException: java.lang.Class has no zero argument constructor
A zero argument constructor is required for the Android system to instantiate an Activity. You should never be manually calling an Activity constructor yourself since only the system can properly create an Activity.
The Parcelables and Bundles documentation details the correct way of sending information to an Activity using the extras Bundle.
Unable to instantiate activity. Because you can't start an activity like this. You have to use intent to start activity. To sent "title" use intent extra.
Intent intent=new Intent(CurrentActivity.this, NewActivty.this);
intent.putExtra("title", title);
startActivty(intent);
Is your Activity in your AndroidManifest.xml?
If it is, you have to retrieve the title from your extras from onCreate() of MainActivity instead from the constructor.
Something like that:
//that code instead of your MainActivity mainActivity = new MainActivity(title); line
Intent intent = new Intent(YourActualActivity.this, MainActivity.class);
intent.putExtra("title", title);
startActivity(intent);
//That code in the onCreate method of your MainActivity
Bundle extras = getIntent().getExtras();
if (extras != null) {
String title = extras.getString("title");
}

Why does the notification not show up in API 28?

I have looked at android documentation and I have seen all the answers in StackOverflow, however, I cannot seem to understand why the notification I am trying to show not show up. Whenever I click the button, instead of notification showing up, the app crashes, can someone please give me insight as to why this is occurring?
notify_me.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("miscellaneous", "Hello World", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Hello Brothers and Sisters");
NotificationManager noti = getSystemService(NotificationManager.class);
noti.createNotificationChannel(channel);
}
}
}
);
Here is the stack trace
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test, PID: 27996
java.lang.IllegalArgumentException: Reserved id
at android.os.Parcel.createException(Parcel.java:1970)
at android.os.Parcel.readException(Parcel.java:1934)
at android.os.Parcel.readException(Parcel.java:1884)
at android.app.INotificationManager$Stub$Proxy.createNotificationChannels(INotificationManager.java:1888)
at android.app.NotificationManager.createNotificationChannels(NotificationManager.java:577)
at android.app.NotificationManager.createNotificationChannel(NotificationManager.java:565)
at com.example.test.Main4Activity$1.onClick(Main4Activity.java:44)
at android.view.View.performClick(View.java:7352)
at android.widget.TextView.performClick(TextView.java:14177)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27800)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.notification.RankingHelper.createNotificationChannel(RankingHelper.java:641)
at com.android.server.notification.NotificationManagerService$12.createNotificationChannelsImpl(NotificationManagerService.java:2585)
at com.android.server.notification.NotificationManagerService$12.createNotificationChannels(NotificationManagerService.java:2600)
at android.app.INotificationManager$Stub.onTransact(INotificationManager.java:292)
at android.os.Binder.execTransact(Binder.java:739)
As per the error message, you cannot use "miscellaneous" as the ID of your notification channel - that name is reserved specifically for apps that don't target API 26 or higher for posting all notifications that don't have a channel attached to them.
You can use any other id string for your channel.

How to fix error in Dialog after dismiss and click again?

I'm developing webview app, the problem in OnJsAlert that when i click on the Dialog it opens after dismiss it and click again it stop my app, for sorry i can't get the problem from debugging.
This is my MainActivity.class
#Override
public boolean onJsAlert(WebView view, String url, final String alertSource, final JsResult alertResult) {
alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
alertDialog.setContentView(R.layout.activity_alert);
alertDialog.setCancelable(true);
TextView alertMessage = alertDialog.findViewById(R.id.alert_text);
alertMessage.setText(alertSource);
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
alertResult.cancel();
}
});
alertDialog.show();
return true;
}
Edited : Log
W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.
E/ViewRootImpl: sendUserActionEvent() mView == null
W/System.err: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
W/System.err: at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:331)
at android.app.Dialog.requestWindowFeature(Dialog.java:1057)
at com.xcoder.stepview.MainActivity$4.onJsAlert(MainActivity.java:285)
at com.android.webview.chromium.WebViewContentsClientAdapter.handleJsAlert(WebViewContentsClientAdapter.java:606)
at com.android.org.chromium.android_webview.AwContentsClientBridge.handleJsAlert(AwContentsClientBridge.java:73)
at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5641)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1288)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104)
at dalvik.system.NativeStart.main(Native Method)
A/libc: Fatal signal 6 (SIGABRT) at 0x00002c6d (code=-6), thread 11373 (xcoder.stepview)
Application terminated.
Your alertDialog is created before public boolean onJsAlert(...) method called and when it's called second time you got AndroidRuntimeException: requestFeature() must be called before adding content because of you can't use requestWindowFeature() with created dialog. You have to create new instance of dialog in this method or reuse global defined dialog.

How to fix Unable to add window when use Dialog in Android [duplicate]

This question already has answers here:
Unable to add window -- token null is not valid; is your activity running?
(10 answers)
WindowManagerBadTokenException unable to add window
(1 answer)
Closed 4 years ago.
In my application I want use dialog and for this I should set custom view to dialog.
I write below codes, but when running application show me ForceClose error on LogCat.
My Codes :
if (!isPremium) {
count = prefsUtils.getFromShared_INT(PrefsKeys.TRIAL_COUNT.name());
prefsUtils.setToShared_INT(PrefsKeys.TRIAL_COUNT.name(), count + 1);
if (count > 10) {
final Dialog dialog = new Dialog(getApplicationContext());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_end_trial);
TextView dialogEndCount_premiumTxt = dialog.findViewById(R.id.dialogEndCount_premiumTxt);
dialogEndCount_premiumTxt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(mContext, MainActivity2.class);
startActivity(intent);
finish();
dialog.dismiss();
}
});
dialog.show();
}
}
Error message on LogCat :
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:702)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
at android.app.Dialog.show(Dialog.java:337)
at com.mcc.wpnews.activity.PostDetailsActivity.initView(PostDetailsActivity.java:176)
at com.mcc.wpnews.activity.PostDetailsActivity.onCreate(PostDetailsActivity.java:104)
at android.app.Activity.performCreate(Activity.java:6754)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2787) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1504) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6247) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762) 
How can I fix it?
Do not use getApplicationContext() unless you know why you are using getApplicationContext().
You cannot show a Dialog using the Application. So, replace new Dialog(getApplicationContext()) with new Dialog(this), and you should have better luck.
See this classic blog post from Dave Smith for more about when to use different types of Context.

Android - java.lang.RuntimeException: Could not read input channel file descriptors from parcel

I'm getting a FATAL EXCEPTION: main when I run the app. It run first but for a few seconds it crash.
Here is my Logcat :
java.lang.RuntimeException: Could not read input channel file descriptors from parcel.
at android.view.InputChannel.nativeReadFromParcel(Native Method)
at android.view.InputChannel.readFromParcel(InputChannel.java:148)
at android.view.IWindowSession$Stub$Proxy.addToDisplay(IWindowSession.java:752)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:527)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:282)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:298)
at android.app.AlertDialog$Builder.show(AlertDialog.java:993)
at com.mobext.shakeys.ActivityMain$ProcessData.onPostExecute(ActivityMain.java:545)
at com.mobext.shakeys.ActivityMain$ProcessData.onPostExecute(ActivityMain.java:212)
at android.os.AsyncTask.finish(AsyncTask.java:636)
at android.os.AsyncTask.access$500(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Inside my ActivityMain.java:542 in alrt.show() this is where the logcat point it:
#Override
protected void onPostExecute(Boolean result) {
Log.i(TAG, "onPostExecute");
super.onPostExecute(result);
if(result){
Log.i(TAG, "TASK IS DONE");
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
app.saveToLastPref(ActivityMain.this, app.PREFS_PREV_VERSION, pInfo.versionName);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), ActivityMenuPage.class);
startActivity(intent);
finish();
}else{
ActivityMain.this.deleteDatabase("DBSHAKEYS");
Builder alrt = new AlertDialog.Builder(mcontext);
alrt.setMessage("Update failed. Please check your internet connection and try again.");
alrt.setPositiveButton("Okay", new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alrt.show();
}
}
}
And in ActivityMain.java:212 :
public class ProcessData extends AsyncTask<Void, Void, Boolean>
I think Builder is your custom class that you are using now to show the AlertDialog.
Here is what may happened
The onPostExecute() method was called automatically after your some background process was finished executing. And then It tried to use the Builder class which may be currently being used by another process and still running in the memory.
How can it be solved then ?
Review your code and see if the dialog is already being shown using
Builder class.
Simply change this line
Builder alrt = new AlertDialog.Builder(mcontext); to normally AlertDialog.Builder alrt = new AlertDialog.Builder(mcontext);
and see if this works.

Categories