首页 > 解决方案 > Android webview 摄像头和麦克风权限

问题描述

在此处输入图像描述

在此处输入图像描述

您好,虽然我已从 Android 授予摄像头和麦克风权限,但我的视频和语音在 webrtc 应用程序中不可见。当我退出应用程序并再次来到这个页面时,图像就会出现。当 Android 请求我的许可时,我希望我的视频和音频能够听到我的视频和音频,而无需打开和关闭应用程序,我该怎么办?

//我的代码

package com.mobile.evdekiokulum;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.webkit.MimeTypeMap;
import android.webkit.PermissionRequest;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.net.MailTo;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.viewpager.widget.ViewPager;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
//import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
import com.karumi.dexter.listener.single.PermissionListener;

import java.io.File;
import java.io.IOException;
import java.net.CookieManager;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private CustomWebViewClient webViewClient;
    private String Url = "https://development.evdekiokulum.com";
    ProgressDialog mProgressDialog;
    RelativeLayout relativeLayout;
    Button btnNoInternetConnections;
    public Context context;

    private static final String TAG = MainActivity.class.getSimpleName();

    private static final int FILECHOOSER_RESULTCODE = 1;
    private ValueCallback<Uri> mUploadMessage;
    private Uri mCapturedImageURI = null;

    // the same for Android 5.0 methods only
    private ValueCallback<Uri[]> mFilePathCallback;
    private String mCameraPhotoPath;
    ProgressBar progressBarWeb;
    private String sURL,sFileName,sUser;


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    @SuppressLint({"WrongViewCast", "SetJavaScriptEnabled"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mProgressDialog = new ProgressDialog(this);//ProgressDialog objesi oluşturuyoruz
        mProgressDialog.setMessage("Yükleniyor...");//ProgressDialog Yükleniyor yazısı


        btnNoInternetConnections = (Button) findViewById(R.id.noConnectionInternet);
        relativeLayout = (RelativeLayout) findViewById(R.id.relativelayout);

        webViewClient = new CustomWebViewClient();//CustomWebViewClient classdan webViewClient objesi oluşturuyoruz
        webView = (WebView) findViewById(R.id.webview);//webview mızı xml anasayfa.xml deki webview bağlıyoruz
        progressBarWeb = (ProgressBar) findViewById(R.id.progressBar);


        if (savedInstanceState !=null){
            webView.restoreState(savedInstanceState);
        }
        else {
            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
            webView.getSettings().setAllowFileAccess(true);
            webView.getSettings().setDomStorageEnabled(true);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
            webView.setWebViewClient(webViewClient); //oluşturduğumuz webViewClient objesini webViewımıza set ediyoruz
            checkConnections();
        }

        //webView.getSettings().setBuiltInZoomControls(true); //zoom yapılmasına izin verir



        //Chrome WebClient Olayları
        webView.setWebChromeClient(new WebChromeClient(){



            public void onProgressChanged(WebView view, int progress)
            {
               progressBarWeb.setVisibility(View.VISIBLE);
               progressBarWeb.setProgress(progress);
               if (progress==100){
                   progressBarWeb.setVisibility(View.GONE);
               }
                //Make the bar disappear after URL is loaded, and changes string to Loading...
                setTitle("Yükleniyor...");
                setProgress(progress * 100); //Make the bar disappear after URL is loaded

                // Return the app name after finish loading
                if(progress == 100)
                    setTitle(R.string.app_name);
            }


            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            public void onPermissionRequest(final PermissionRequest request) {

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    request.grant(request.getResources());
                }
                Dexter.withContext(MainActivity.this)
                        .withPermissions(
                                Manifest.permission.CAMERA,
                                Manifest.permission.RECORD_AUDIO
                        ).withListener(new MultiplePermissionsListener() {


                    @Override
                    public void onPermissionsChecked(MultiplePermissionsReport multiplePermissionsReport) {
                        Toast.makeText(MainActivity.this, "Kamera ve Mikrofon izni alındı.Görüntünüz gelmiyorsa lütfen Sayfayı Yenileyiniz.", Toast.LENGTH_LONG).show();


                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(List<com.karumi.dexter.listener.PermissionRequest> list, PermissionToken permissionToken) {
                        Toast.makeText(MainActivity.this, "Kamera ve Mikrofon izni alınamadı.", Toast.LENGTH_SHORT).show();
                    }
                }).check();


                //webView.reload();

            }


     //Resim upload etme
            // for Lollipop, all in one
            public boolean onShowFileChooser(
                    WebView webView, ValueCallback<Uri[]> filePathCallback,
                    WebChromeClient.FileChooserParams fileChooserParams) {
                if (mFilePathCallback != null) {
                    mFilePathCallback.onReceiveValue(null);
                }
                mFilePathCallback = filePathCallback;

                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

                    // create the file where the photo should go
                    File photoFile = null;
                    try {
                        photoFile = createImageFile();
                        takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
                    } catch (IOException ex) {
                        // Error occurred while creating the File
                        Log.e(TAG, "Unable to create Image File", ex);
                    }

                    // continue only if the file was successfully created
                    if (photoFile != null) {
                        mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                                Uri.fromFile(photoFile));
                    } else {
                        takePictureIntent = null;
                    }
                }

                Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                contentSelectionIntent.setType("image/*");

                Intent[] intentArray;
                if (takePictureIntent != null) {
                    intentArray = new Intent[]{takePictureIntent};
                } else {
                    intentArray = new Intent[0];
                }

                Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                chooserIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.image_chooser));
                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

                startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);

                return true;
            }

            // creating image files (Lollipop only)
            private File createImageFile() throws IOException {

                File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DirectoryNameHere");

                if (!imageStorageDir.exists()) {
                    imageStorageDir.mkdirs();
                }

                // create an image file name
                imageStorageDir = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
                return imageStorageDir;
            }

            // openFileChooser for Android 3.0+
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
                mUploadMessage = uploadMsg;

                try {
                    File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DirectoryNameHere");

                    if (!imageStorageDir.exists()) {
                        imageStorageDir.mkdirs();
                    }

                    File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");

                    mCapturedImageURI = Uri.fromFile(file); // save to the private variable

                    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
                    // captureIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("image/*");

                    Intent chooserIntent = Intent.createChooser(i, getString(R.string.image_chooser));
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});

                    startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
                } catch (Exception e) {
                    Toast.makeText(getBaseContext(), "Camera Exception:" + e, Toast.LENGTH_LONG).show();
                }

            }

            // openFileChooser for Android < 3.0
            public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                openFileChooser(uploadMsg, "");
            }

            // openFileChooser for other Android versions
            /* may not work on KitKat due to lack of implementation of openFileChooser() or onShowFileChooser()
               https://code.google.com/p/android/issues/detail?id=62220
               however newer versions of KitKat fixed it on some devices */
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                openFileChooser(uploadMsg, acceptType);
            }




        });
        //Resim upload etme


        //Dosya indirme izinleri ve olayları
        webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long l) {
             String filename =URLUtil.guessFileName(url,contentDisposition,getFileType(url));
             sFileName = filename;
             sURL = url;
             sUser= userAgent;
             if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
                 if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED){
                     downloadFile(filename,url,userAgent);

                 }
                 else
                 {
                     requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}
                     ,1001);
                 }
             }
             else {
                 downloadFile(filename,url,userAgent);
             }

            }
        });
        //Dosya indirme izinleri ve olayları



        //webView.loadUrl(Url);
        btnNoInternetConnections.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkConnections();
            }
        });

    }
    private void downloadFile(String filename,String url,String userAgent){

        try {
          DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
          DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
          String cookie = android.webkit.CookieManager.getInstance().getCookie(url);

          request.setTitle(filename)
                  .setDescription("Dosya İndiriliyor...")
                  .addRequestHeader("cookie",cookie)
                  .addRequestHeader("User-Agent",userAgent)
                  .setMimeType(getFileType(url))
                  .setAllowedOverMetered(true)
                  .setAllowedOverRoaming(true)
                  .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE|DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                  downloadManager.enqueue(request);
                  sURL="";
                  sUser = "";
                  sFileName="";
               Toast.makeText(this,"Dosya İndiriliyor...",Toast.LENGTH_SHORT).show();

        } catch (Exception ignored) {
            Toast.makeText(this,"Hata"+ignored,Toast.LENGTH_SHORT).show();
        }
    }

    public String getFileType(String url){
        ContentResolver contentResolver = getContentResolver();
        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
        return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(Uri.parse(url)));
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode==1001){
            if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                if (!sURL.equals("")&&!sFileName.equals("")&&!sUser.equals("")){
                    downloadFile(sFileName,sURL,sUser);
                }
            }
        }
    }

    private class CustomWebViewClient extends WebViewClient {
        //Alttaki methodların hepsini kullanmak zorunda deilsiniz
        //Hangisi işinize yarıyorsa onu kullanabilirsiniz.

       /* @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) { //Sayfa yüklenirken çalışır
            super.onPageStarted(view, url, favicon);

            if(!mProgressDialog.isShowing())//mProgressDialog açık mı kontrol ediliyor
            {

                mProgressDialog.show();//mProgressDialog açık değilse açılıyor yani gösteriliyor ve yükleniyor yazısı çıkıyor
            }

        }

        */

        @Override
        public void onPageFinished(WebView view, String url) {//sayfamız yüklendiğinde çalışıyor.
            super.onPageFinished(view, url);

            if(mProgressDialog.isShowing()){//mProgressDialog açık mı kontrol
                mProgressDialog.dismiss();//mProgressDialog açıksa kapatılıyor
            }
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Log.e("url adresi",url);
            if (url.startsWith("intent://")) {
                try {
                    Context context = view.getContext();
                    Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);

                    if (intent != null) {
                        view.stopLoading();
                        PackageManager packageManager = context.getPackageManager();
                        ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
                        if (info==null){
                            Toast.makeText(getApplicationContext(), "Uygulama Bulunamadı. Lütfen Yükleyin.", Toast.LENGTH_LONG).show();
                        }
                        if (info != null) {
                            context.startActivity(intent);
                        } else {
                            String fallbackUrl = intent.getStringExtra("browser_fallback_url");
                            view.loadUrl(fallbackUrl);

                            // or call external broswer
//                    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(fallbackUrl));
//                    context.startActivity(browserIntent);
                        }

                        return true;
                    }
                } catch (URISyntaxException e) {
                    Log.e("", String.valueOf(e));
                }
            }

            return false;
        }
            // Bu method açılan sayfa içinden başka linklere tıklandığında açılmasına yarıyor.
            //Bu methodu override etmez yada edip içini boş bırakırsanız ilk url den açılan sayfa dışında başka sayfaya geçiş yapamaz

            //view.loadUrl(url);//yeni tıklanan url i açıyor




        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error ) {
            checkConnections();
            //BU method webview yüklenirken herhangi bir hatayla karşilaşilırsa hata kodu dönüyor.
            //Dönen hata koduna göre kullanıcıyı bilgilendirebilir yada gerekli işlemleri yapabilirsiniz
            //errorCode ile hatayı alabilirsiniz
            //  if(errorCode==-8){
            //      Timeout
            //  } şeklinde kullanabilirsiniz

            //Hata Kodları aşağıdadır...

            /*
             *  /** Generic error
            public static final int ERROR_UNKNOWN = -1;
            /** Server or proxy hostname lookup failed
            public static final int ERROR_HOST_LOOKUP = -2;
            /** Unsupported authentication scheme (not basic or digest)
            public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
            /** User authentication failed on server
            public static final int ERROR_AUTHENTICATION = -4;
            /** User authentication failed on proxy
            public static final int ERROR_PROXY_AUTHENTICATION = -5;
            /** Failed to connect to the server
            public static final int ERROR_CONNECT = -6;
            /** Failed to read or write to the server
            public static final int ERROR_IO = -7;
            /** Connection timed out
            public static final int ERROR_TIMEOUT = -8;
            /** Too many redirects
            public static final int ERROR_REDIRECT_LOOP = -9;
            /** Unsupported URI scheme
            public static final int ERROR_UNSUPPORTED_SCHEME = -10;
            /** Failed to perform SSL handshake
            public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
            /** Malformed URL
            public static final int ERROR_BAD_URL = -12;
            /** Generic file error
            public static final int ERROR_FILE = -13;
            /** File not found
            public static final int ERROR_FILE_NOT_FOUND = -14;
            /** Too many requests during this load
            public static final int ERROR_TOO_MANY_REQUESTS = -15;
            */

        }
    }



    // return here when file selected from camera or from SD Card
    //Resim upload etme
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        // code for all versions except of Lollipop
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {

            if (requestCode == FILECHOOSER_RESULTCODE) {
                if (null == this.mUploadMessage) {
                    return;
                }

                Uri result = null;

                try {
                    if (resultCode != RESULT_OK) {
                        result = null;
                    } else {
                        // retrieve from the private variable if the intent is null
                        result = data == null ? mCapturedImageURI : data.getData();
                    }
                } catch (Exception e) {
                    Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
                }

                mUploadMessage.onReceiveValue(result);
                mUploadMessage = null;
            }

        } // end of code for all versions except of Lollipop

        // start of code for Lollipop only
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            if (requestCode != FILECHOOSER_RESULTCODE || mFilePathCallback == null) {
                super.onActivityResult(requestCode, resultCode, data);
                return;
            }

            Uri[] results = null;

            // check that the response is a good one
            if (resultCode == Activity.RESULT_OK) {
                if (data == null || data.getData() == null) {
                    // if there is not data, then we may have taken a photo
                    if (mCameraPhotoPath != null) {
                        results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                    }
                } else {
                    String dataString = data.getDataString();
                    if (dataString != null) {
                        results = new Uri[]{Uri.parse(dataString)};
                    }
                }
            }

            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;

        } // end of code for Lollipop only
    }
    //Resim upload etme


    public void onBackPressed() //Android Back Buttonunu Handle ettik. Back butonu bir önceki sayfaya geri dönecek
    {
        if(webView.canGoBack()){//eğer varsa bir önceki sayfaya gidecek
            Toast.makeText(getApplicationContext(),"Geriye Gidiliyor...",Toast.LENGTH_LONG).show();
            webView.goBack();
        }
        else{
            AlertDialog.Builder buider = new AlertDialog.Builder(this);
            buider.setMessage("Çıkmak için eminmisiniz?")
                  .setNegativeButton("Hayır",null)
                  .setPositiveButton("Evet", new DialogInterface.OnClickListener(){
                      @Override
                      public void onClick(DialogInterface dialogInterface, int i) {
                       finishAffinity();
                      }
                  }).show();
            //Toast.makeText(getApplicationContext(),"Sayfanın Sonundasınız...",Toast.LENGTH_LONG).show();
            //super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu,menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case R.id.nav_pre:
                onBackPressed();
                break;
            case R.id.nav_next:
                if(webView.canGoForward()){
                    Toast.makeText(getApplicationContext(),"İleriye Gidiliyor...",Toast.LENGTH_LONG).show();
                    webView.goForward();
                }
                break;
            case R.id.nav_reload:
                Toast.makeText(getApplicationContext(),"Sayfa Yenileniyor...",Toast.LENGTH_LONG).show();
                webView.reload();
                break;

        }
        return super.onOptionsItemSelected(item);
    }

    public void checkConnections(){
        ConnectivityManager connectivityManager = (ConnectivityManager)
                this.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        NetworkInfo mobileNetwork = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        if (wifi.isConnected()){
            webView.loadUrl(Url);
            webView.setVisibility(View.VISIBLE);
            relativeLayout.setVisibility(View.GONE);
        }
        else if (mobileNetwork.isConnected()){
            webView.loadUrl(Url);
            webView.setVisibility(View.VISIBLE);
            relativeLayout.setVisibility(View.GONE);
        }
        else if (connectivityManager.getActiveNetworkInfo()==null){
            webView.setVisibility(View.GONE);
            relativeLayout.setVisibility(View.VISIBLE);
        }

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }



}

标签: androidandroid-studioandroid-webview

解决方案


推荐阅读