从 Activity 之外的 Webview 显示 AlertDialog [英] Showing an AlertDialog from a Webview outside of an Activity

查看:22
本文介绍了从 Activity 之外的 Webview 显示 AlertDialog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发一个类似于 Facebook 聊天头的功能 - 即使用户离开我们的应用去查看电子邮件等,该功能也需要为我们的用户激活.它需要能够通过 javascript 创建 AlertDialogs- 来自当用户在我们的应用程序内切换活动时不受影响的地方.当用户离开应用程序做其他事情时关闭/隐藏该功能是可以的 - 但是当他们回来时它必须仍然存在.

除了使用服务之外,我想不出另一种方式让用户在他们不在做其他事情时与我们互动.当我使用服务通过 WindowManager 创建 webview 时,webview 的 JsDialogHelper 检测到上下文不是活动并阻止它显示 AlertDialogs.

任何想法都会对完成这项工作最有帮助.我们需要允许 AlertDialogs 弹出并进行交互才能使此功能有所帮助.我们需要 webview 在活动转换之间停留.

是否可以扩展 JsDialogHelper 以便我可以使用我的代码?有没有更好的方法在我还没有想到的 android 应用程序中使用 webviews 来拥有像 facebook 聊天头一样的功能?如果它获得了我正在寻找的用户体验,我愿意完成重写.

解决方案

您可以通过将窗口类型设置为 TYPE_SYSTEM_ALERT 来显示来自服务的 Dialog.请记住使用传递给 onJsAlertJsResult 实例来传达用户采取的操作.

//维护对传递给 onJsAlert 的 JsResult 实例的引用,按顺序//传达回用户采取的行动.私人 JsResult mResult;webView.setWebChromeClient(new WebChromeClient() {@覆盖public boolean onJsAlert(WebView view, String url, String message, JsResult result) {mResult = 结果;AlertDialog 对话框 = new AlertDialog.Builder(MyService.this).setTitle("自定义对话框").setMessage("这是我们的自定义对话框,不是由 JsDialogHelper 提供的对话框").setOnCancelListener(new CancelListener()).setNegativeButton("取消", new CancelListener()).setPositiveButton("OK", new PositiveListener()).创建();dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);对话框显示();返回真;}});私有类 CancelListener 实现了 DialogInterface.OnCancelListener,DialogInterface.OnClickListener {@覆盖public void onCancel(DialogInterface dialogInterface) {mResult.cancel();}@覆盖public void onClick(DialogInterface dialogInterface, int i) {mResult.cancel();}}私有类 PositiveListener 实现 DialogInterface.OnClickListener {@覆盖public void onClick(DialogInterface dialogInterface, int i) {mResult.confirm();}}

向清单文件添加所需的权限:

替代解决方案:如果可以针对 android webview 构建 Web 应用程序,那么您可以创建 Javascript 接口,这将允许 Javascript 代码直接调用 Android 代码,从而为您显示对话框.这避免了 JsDialogHelper 路由.

  1. 定义一个 javascript 接口:

<块引用>

public class WebAppInterface {上下文上下文;WebAppInterface(上下文c){上下文 = c;}//api >= 17 需要注解@JavascriptInterface公共无效showDialog(){AlertDialog 对话框 = 新的 AlertDialog.Builder(context).setTitle("自定义对话框").setMessage("这是我们的自定义对话框,不是由 JsDialogHelper 提供的对话框").创建();dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);对话框显示();}}

  1. 绑定Javascript和Android代码之间的接口,使用addJavascriptInterface.

<块引用>

webView.addJavascriptInterface(new WebAppInterface(this), "Android");

  1. 在 Javascript 代码中使用接口.

<块引用>

<脚本>函数显示对话框(){//alert("Javascript 对话框");Android.showDialog();}</输入>

I've been working on a feature similar to Facebook's chat heads - a feature which needs to be active for our users even if they leave our app to go check email, etc. It needs to be able to create AlertDialogs via javascript - from a place that isn't impacted when the user switches Activities inside our app. It's OK for the feature to close/hide when the user leaves the app to do something else - however it must still be present when they come back.

Other than using a Service I haven't been able to think of another way to let users interact with us while they're off doing other things. When I use a service to create the webview via WindowManager the webview's JsDialogHelper detects that the context is not an activity and prevents it from showing AlertDialogs.

Any ideas would be most helpful around making this work. We need to allow AlertDialogs to pop up and be interactive for this feature to be helpful. We need the webview to stick around between activity transitions.

Is it possible to extend JsDialogHelper so I can get it to work with my code? Is there a better way to have a facebook chat heads like feature using webviews in an android app that I haven't thought of yet? I'm open to complete rewrites if it gets the user experience I'm looking for.

解决方案

You can display the Dialog from the service, by setting the window type as TYPE_SYSTEM_ALERT. Remember to communicate back the action taken by the user using the JsResult instance passed to onJsAlert.

    // maintain reference to JsResult instance passed to onJsAlert, in order
    // communicate back the action taken by the user.
    private JsResult mResult; 

    webView.setWebChromeClient(new WebChromeClient() {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            mResult = result;
            AlertDialog dialog = new AlertDialog.Builder(MyService.this)
                    .setTitle("Custom Dialog")
                    .setMessage("This is our custom dialog, not the one served by JsDialogHelper")
                    .setOnCancelListener(new CancelListener())
                    .setNegativeButton("Cancel", new CancelListener())
                    .setPositiveButton("Ok", new PositiveListener())
                    .create();
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            dialog.show();

            return true;
        }
    });

    private class CancelListener implements DialogInterface.OnCancelListener,
        DialogInterface.OnClickListener {

        @Override
        public void onCancel(DialogInterface dialogInterface) {
            mResult.cancel();
        }

        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            mResult.cancel();
        }
    }

    private class PositiveListener implements DialogInterface.OnClickListener {

        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            mResult.confirm();
        }
    }

Add the required permissions to the manifest file:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Alternate solution: If the web application can be built specific to android webview, then you can create Javascript interfaces which will allow Javascript code to directly invoke the Android code which in turn displays the dialog for you. This avoids the JsDialogHelper route.

  1. Define a javascript interface:

public class WebAppInterface {
    Context context;

    WebAppInterface(Context c) {
        context = c;
    }

    // Annotation required for api >= 17
    @JavascriptInterface
    public void showDialog() {
        AlertDialog dialog = new AlertDialog.Builder(context)
                .setTitle("Custom Dialog")
                .setMessage("This is our custom dialog, not the one served by JsDialogHelper")
                .create();
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        dialog.show();
    }
}

  1. Bind the interface between Javascript and Android code, using addJavascriptInterface.

webView.addJavascriptInterface(new WebAppInterface(this), "Android");

  1. Use the interface in Javascript code.

<input type="button" value="Display dialog" onClick="displayDialog()" />
    <script>
        function displayDialog() {
            //alert("Javascript Dialog");
            Android.showDialog();
        }
    </script>
</input>

这篇关于从 Activity 之外的 Webview 显示 AlertDialog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆