Nano Hash - криптовалюты, майнинг, программирование

нет всплывающего окна для веб-просмотра Android для загрузки файлов или открытия камеры

Я не мог получить всплывающее окно для своего приложения для веб-просмотра Android, я перепробовал все возможное, может кто-нибудь помочь мне, пожалуйста, вот мой код mainActivity.

Что я пытаюсь сделать, так это загрузить свой веб-просмотр, который я получаю успешно, но есть личная страница, где, если пользователь нажимает на изображение профиля, он должен предложить либо открыть камеру, либо загрузить изображение из галереи, и снова есть вариант загрузки, если нажать то же самое должно произойти либо для загрузки фотографий, либо для открытия камеры. Она отлично работает, если я делаю это из своего браузера, но не из моего приложения для Android в веб-браузере.

public class MainActivity extends AppCompatActivity {



private static final int MY_BLINK_ID_REQUEST_CODE = 0x101;
public static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 101;
private static final int REQUEST_WEBFORM = 300;
public static final int REQUEST_SELECT_FILE = 100;

private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> uploadMessageLP;
private Uri directUploadImageUri;


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

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

    setupToolbar();

    loadHtml();
}




public void cancelFileUpload() {
    if (mUploadMessage != null) {
        mUploadMessage.onReceiveValue(null);
        mUploadMessage = null;
    }

    if (uploadMessageLP != null) {
        uploadMessageLP.onReceiveValue(null);
        uploadMessageLP = null;
    }

    this.directUploadImageUri = null;
}



public void setUploadMessageLP(ValueCallback<Uri[]> uploadMessageLP) {
    this.uploadMessageLP = uploadMessageLP;
}





/**
 * setup toolbar
 */
private void setupToolbar() {
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    //change title color
    toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.white));
    //set title
    getSupportActionBar().setTitle(getString(R.string.app_name));

}

private void loadHtml() {
    mWebView = (WebView) findViewById(R.id.wv);
    mWebView.setWebViewClient(new WebViewClient());

    WebSettings settings = mWebView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setLoadWithOverviewMode(true);
    settings.setUseWideViewPort(true);
    settings.setAllowContentAccess(true);
    settings.setAllowFileAccess(true);
    settings.setAllowFileAccessFromFileURLs(true);
    settings.setAllowUniversalAccessFromFileURLs(true);
    // Render the HTML file on WebView
    mWebView.loadUrl("http://new.techyardnepal.com");

}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                if (mWebView.canGoBack()) {
                    mWebView.goBack();
                } else {
                    finish();
                }
                return true;
        }

    }
    return super.onKeyDown(keyCode, event);
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_favorite) {
        startOCRScan();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

/**
 * start ocr on scan id click
 */
private void startOCRScan() {
    // Intent for MyScanActivity
    Intent intent = new Intent(this, MRPScanActivity.class);
    startActivityForResult(intent, MY_BLINK_ID_REQUEST_CODE);

}

/**
 * This method is called whenever control is returned from activity started with
 * startActivityForResult.
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // onActivityResult is called whenever we are returned from activity started
    // with startActivityForResult. We need to check request code to determine
    // that we have really returned from BlinkID activity.
    if (requestCode == MY_BLINK_ID_REQUEST_CODE) {
        if (resultCode == MRPScanActivity.RESULT_OK && data != null) {

            // depending on settings, we may have multiple scan results.
            // we first need to obtain recognition results
            RecognitionResults results = data.getParcelableExtra(ScanActivity.EXTRAS_RECOGNITION_RESULTS);
            BaseRecognitionResult[] resArray = null;
            if (results != null) {
                // get array of recognition results
                resArray = results.getRecognitionResults();
            }
            if (resArray != null) {
                Log.i(TAG, "Data count: " + resArray.length);
                int i = 1;

                for (BaseRecognitionResult res : resArray) {
                    Log.i(TAG, "Data #" + Integer.valueOf(i++).toString());

                    // Each element in resultArray inherits BaseRecognitionResult class and
                    // represents the scan result of one of activated recognizers that have
                    // been set up.

                    res.log();
                }

            } else {
                Log.e(TAG, "Unable to retrieve recognition data!");
            }

            data.setComponent(new ComponentName(this, ResultActivity.class));
            startActivity(data);
        }
    }
    if (data != null && data.getBooleanExtra("exit", false))
        finish();





    if (requestCode == REQUEST_SELECT_FILE) {
        if (resultCode != RESULT_OK) {
            cancelFileUpload();
            return;
        }

        // from documents (and video camera)
        if (data != null && data.getData() != null) {
            if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue(data.getData());
                mUploadMessage = null;
            }


            return;
        }

        // we may get clip data for multi-select documents
        if (data != null && data.getClipData() != null) {
            ClipData clipData = data.getClipData();
            ArrayList<Uri> files = new ArrayList<>(clipData.getItemCount());
            for (int i = 0; i < clipData.getItemCount(); i++) {
                ClipData.Item item = clipData.getItemAt(i);
                if (item.getUri() != null) {
                    files.add(item.getUri());
                }
            }

            if (mUploadMessage != null) {
                // shouldn never happen, but just in case, send the first item
                if (files.size() > 0) {
                    mUploadMessage.onReceiveValue(files.get(0));
                } else {
                    mUploadMessage.onReceiveValue(null);
                }
                mUploadMessage = null;
            }

            if (uploadMessageLP != null) {
                uploadMessageLP.onReceiveValue(files.toArray(new Uri[files.size()]));
                uploadMessageLP = null;
            }

            return;
        }

        // from camera
        if (this.directUploadImageUri != null) {
            // check if we have external storage permissions
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) !=
                    PackageManager.PERMISSION_GRANTED) {


                ActivityCompat.requestPermissions(this,
                        new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_PERMISSION_READ_EXTERNAL_STORAGE);
                // wait for the onRequestPermissionsResult callback
                return;
            }


            if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue(this.directUploadImageUri);
                mUploadMessage = null;
            }
            if (uploadMessageLP != null) {
                uploadMessageLP.onReceiveValue(new Uri[]{this.directUploadImageUri});
                uploadMessageLP = null;
            }
            this.directUploadImageUri = null;

            return;
        }

        // Should not reach here.
        cancelFileUpload();
    }
}

}


  • ты меняешь setWebViewClient на setWebChromeClient 03.02.2018

Ответы:


1

Попробуйте этот код:

public class MainActivity extends Activity {

private RelativeLayout mLayout;
private ProgressBar progressBar;
private WebView webView;
String loadUrl;

private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private WebSettings webSettings;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
ValueCallback<Uri[]> chooserPathUri;

public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;

WebView chooserWV;
WebChromeClient.FileChooserParams chooserParams;

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

    loadUrl = "https:google.com";

    mLayout = (RelativeLayout) findViewById(R.id.activity_main);
    progressBar = (ProgressBar)findViewById(R.id.indicator);
    webView = (WebView) findViewById(R.id.webView);
    webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setLoadWithOverviewMode(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setUseWideViewPort(true);
    webSettings.setLoadWithOverviewMode(true);
    webSettings.setAllowFileAccess(true);
    if (Build.VERSION.SDK_INT >= 19) {
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
    }
    else if(Build.VERSION.SDK_INT >=11 && Build.VERSION.SDK_INT < 19) {
        webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }
    webView.setWebChromeClient(new ChromeClient());
    webView.loadUrl(loadUrl); //change with your website

    this.webView.setWebViewClient(new WebViewClient(){
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            progressBar.setVisibility(View.INVISIBLE);

        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            progressBar.setVisibility(View.VISIBLE);
        }

        @SuppressWarnings("deprecation")
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return handleUrl(url);
        }

        @TargetApi(Build.VERSION_CODES.N)
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            final Uri uri = request.getUrl();
            return handleUrl(request.getUrl().toString());
        }
    });
}

public boolean handleUrl(String url){

    if (url.startsWith("geo:") || url.startsWith("mailto:") || url.startsWith("tel:") || url.startsWith("sms:")) {
        Intent searchAddress = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(searchAddress);
    }else
        webView.loadUrl(url);
    return true;
}

private  boolean checkAndRequestPermissions() {
    int permissionCamera = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
    int permissionStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    List<String> listPermissionsNeeded = new ArrayList<>();
    if (permissionStorage != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }
    if (permissionCamera != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.CAMERA);
    }
    if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
        Log.e(TAG, "Returned falseeeee-------");
        return false;
    }
    Log.d(TAG, "Permission returned trueeeee-------");
    return true;

}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    Log.d(TAG, "Permission callback called-------");
    switch (requestCode) {
        case REQUEST_ID_MULTIPLE_PERMISSIONS: {

            Map<String, Integer> perms = new HashMap<>();
            // Initialize the map with both permissions
            perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
            // Fill with actual results from user
            if (grantResults.length > 0) {
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);
                // Check for both permissions
                if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "camera & Storage permission granted");
                    Toast.makeText(this, "Permissions granted! Try now.", Toast.LENGTH_SHORT).show();
                    //chromClt.openChooser(chooserWV, chooserPathUri, chooserParams);
                    // process the normal flow
                    //else any one or both the permissions are not granted
                } else {
                    Log.d(TAG, "Some permissions are not granted ask again ");
                    //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
                    // shouldShowRequestPermissionRationale will return true
                    //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
                    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        showDialogOK("Camera and Storage Permission required for this app",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        switch (which) {
                                            case DialogInterface.BUTTON_POSITIVE:
                                                checkAndRequestPermissions();
                                                break;
                                            case DialogInterface.BUTTON_NEGATIVE:
                                                // proceed with logic by disabling the related features or quit the app.
                                                break;
                                        }
                                    }
                                });
                    }
                    //permission is denied (and never ask again is  checked)
                    //shouldShowRequestPermissionRationale will return false
                    else {
                        Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG).show();
                        //                            //proceed with logic by disabling the related features or quit the app.
                    }
                }
            }
            break;
        }
    }

}

private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(this)
            .setMessage(message)
            .setPositiveButton("OK", okListener)
            .setNegativeButton("Cancel", okListener)
            .create()
            .show();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (requestCode != INPUT_FILE_REQUEST_CODE || 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) {
                // 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)};
                }else {
                    if (Build.VERSION.SDK_INT >= 16) {
                        if (data.getClipData() != null) {
                            final int numSelectedFiles = data.getClipData().getItemCount();

                            results = new Uri[numSelectedFiles];

                            for (int i = 0; i < numSelectedFiles; i++) {
                                results[i] = data.getClipData().getItemAt(i).getUri();
                            }
                        }
                    }
                }
            }
        }
        mFilePathCallback.onReceiveValue(results);
        mFilePathCallback = null;
    } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
        if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }
        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;
        }
    }
    return;
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File imageFile = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    return imageFile;
}

public class ChromeClient extends WebChromeClient {

    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        // callback.invoke(String origin, boolean allow, boolean remember);
        Log.e(TAG, "onGeolocationPermissionsShowPrompt: " );
        callback.invoke(origin, true, false);
    }

    // For Android 5.0
    public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {

        chooserWV = view;
        chooserPathUri = filePath;
        chooserParams = fileChooserParams;

        if(checkAndRequestPermissions()){
            openChooser(chooserWV, chooserPathUri, chooserParams);

            return true;
        }else {
            return false;
        }

    }


    public void openChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams){

        // Double check that we don't have any existing callbacks
        if (mFilePathCallback != null) {
            mFilePathCallback.onReceiveValue(null);
        }
        mFilePathCallback = filePath;
        Intent takePictureIntent;

        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);
        if (Build.VERSION.SDK_INT >= 18) {
            contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
        }
        contentSelectionIntent.setType("*/*");
        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, "Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
        startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
    }

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

        mUploadMessage = uploadMsg;
        // Create AndroidExampleFolder at sdcard
        // Create AndroidExampleFolder at sdcard
        File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES)
                , "AndroidExampleFolder");
        if (!imageStorageDir.exists()) {
            // Create AndroidExampleFolder at sdcard
            imageStorageDir.mkdirs();
        }
        // Create camera captured image file path and name
        File file = new File(
                imageStorageDir + File.separator + "IMG_"
                        + String.valueOf(System.currentTimeMillis())
                        + ".jpg");
        mCapturedImageURI = Uri.fromFile(file);
        // Camera capture image intent
        final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        // Create file chooser intent
        Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
        // Set camera intent to file chooser
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
        // On select image call onActivityResult method of activity

        chooserIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
        startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
    }

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

    //openFileChooser for other Android versions
    public void openFileChooser(ValueCallback<Uri> uploadMsg,
                                String acceptType,
                                String capture) {
        openFileChooser(uploadMsg, acceptType);
    }

}



@SuppressLint("NewApi")
@Override
protected void onResume() {
    super.onResume();
    webView.onResume();
    // ...
}

@SuppressLint("NewApi")
@Override
protected void onPause() {
    webView.onPause();
    // ...
    super.onPause();
}

int mExit = 0;

@Override
public void onBackPressed() {
    if(webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed();
    }

}

Не забудьте добавить разрешения в манифест:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
03.02.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..