首页 > 解决方案 > 一个 webview 应用程序获得了权限,但每当你使用它们时就会崩溃

问题描述

我目前正在 Android Studio 中开发 webview 应用程序,但我是一名网络开发人员,当然有点迷路。这个应用程序需要访问相机、定位电话和其他功能,所以在研究后我设法通过弹出窗口声明并要求它们,但即使用户授予它们,只要你点击按钮,应用程序就会崩溃对于相机或电话,我无法弄清楚问题出在哪里。这不会发生在 PC 浏览器甚至手机浏览器中。

首先我了解到权限需要在 AndroidManifest.xml 中声明,所以我把它们写下来。然后我读到我必须编写函数来实际请求这些权限,经过几天的搜索,我只能找到一种我理解的方法,但是这样用户会在开始时收到所有弹出窗口的提示执行。这至少有效,因为我能够检查应用程序信息并确认它,但毕竟,每当按下执行操作的按钮之一时,整个应用程序就会崩溃,现在我不知道该怎么办。

这是我声明权限的 AndroidManifest.xml:

    <!-- Internet --> 
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Storage--> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
    <!-- Camera-->
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <!-- Location-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- Phone-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
    <uses-permission android:name="android.permission.ADD_VOICEMAIL" />
    <uses-permission android:name="android.permission.USE_SIP" />
    <!-- Calendar--> 
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    <!-- Contacts--> 
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- SMS--> 
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
    <uses-permission android:name="android.permission.RECEIVE_MMS" />

然后这就是我在 MainActivity.java 上所做的,首先是我的 onCreate 方法:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Código agregado
        mWebView = (WebView) findViewById(R.id.activity_main_webview);
        // Activamos jаvascript
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        // Activamos el LocalStorage
        webSettings.setDomStorageEnabled(true);
        // Activamos el focus tactil
        mWebView.setFocusable(true);
        mWebView.setFocusableInTouchMode(true);
        // Configuraciones varias
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        mWebView.getSettings().setDatabaseEnabled(true);
        mWebView.getSettings().setAppCacheEnabled(true);
        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        // Url que carga la app (webview)
        mWebView.loadUrl("http://reclamador.globalten.es");
        // Forzamos el webview para que abra los enlaces internos dentro de la la APP
        mWebView.setWebViewClient(new WebViewClient());
        // Forzamos el webview para que abra los enlaces externos en el navegador
        mWebView.setWebViewClient(new MyAppWebViewClient());
        // Permite inspeccionar el codigo a traves de chrome
        mWebView.setWebContentsDebuggingEnabled(true);
        // Fin del código agregado

        // Código añadido
        int Permission_All = 1;

        String[] Permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.MEDIA_CONTENT_CONTROL, Manifest.permission.CAMERA, Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_PHONE_NUMBERS, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        if(!hasPermissions(this, Permissions)){
            ActivityCompat.requestPermissions(this, Permissions, Permission_All);
        }
        // Fin del código añadido
    }

然后检查它们是否已被授予的方法:

// Codigo añadido
    public static boolean hasPermissions(Context context, String... permissions){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M && context!=null && permissions!=null){
            for(String permission: permissions){
                if(ActivityCompat.checkSelfPermission(context, permission) !=PackageManager.PERMISSION_GRANTED){
                    return false;
                }
            }
        }
        return true;
    }
    // Fin del código añadido

正如我所说,这是一个 web 应用程序,所以我不知道如何将按钮与弹出窗口连接起来,我看到的每个教程都向您展示了如何在 AndroidStudio 上创建一个按钮,但就我而言,它是一个完全开发的网络。网络内的电话按钮是一个标签 邮件还有另一个标签,但我没有看到与此案例相关的任何许可 还有一些画廊图片或使用相机的输入也不起作用,我刚刚完成学生网络开发所以不要对我太苛刻,谢谢你的时间和帮助!

编辑

我设法通过更改 MyAppWebViewClient 类 (MyAppWebViewClient.java) 中的方法来解决 tel: 和 mailto: 问题

// Código agregado
public class MyAppWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // Url base de la APP (al salir de esta url, abre el navegador) poner como se muestra, sin https://
        if(Uri.parse(url).getHost().endsWith("reclamador.globalten.es")) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
    }
}
// Fin del código agregado*/

对此:

public class MyAppWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("tel:") || url.startsWith("sms:") || url.startsWith("smsto:") || url.startsWith("mailto:") || url.startsWith("mms:") || url.startsWith("mmsto:") || url.startsWith("market:")) {
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            view.getContext().startActivity(intent);
            return true;
        } else {
            view.loadUrl(url);
            return true;
        }
    }
}

现在我只有可以访问画廊或拍照上传的文件输入的问题,所以任何进一步的建议将不胜感激!

标签: javaandroidwebviewpermissionscrash

解决方案


推荐阅读