Как я могу открыть URL в веб-браузере Android из моего приложения?


1346

Как открыть URL из кода во встроенном веб-браузере, а не в моем приложении?

Я попробовал это:

try {
    Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(download_link));
    startActivity(myIntent);
} catch (ActivityNotFoundException e) {
    Toast.makeText(this, "No application can handle this request."
        + " Please install a webbrowser",  Toast.LENGTH_LONG).show();
    e.printStackTrace();
}

но я получил исключение:

No activity found to handle Intent{action=android.intent.action.VIEW data =www.google.com

6
Я думаю , что из - за этого: android-developers.blogspot.com/2009/12/...
Арут

1
Почему это не работает на некоторых устройствах? даже если есть веб-браузер, он переходит в ActivityNotFoundException.

Я вижу ту же проблему, что и @Manu. Базовая установка на Nexus 6, имеет хром, но ссылки вызывают исключение.
Брилл Паппин

Ответы:


2459

Попробуй это:

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browserIntent);

Это прекрасно работает для меня.

Что касается отсутствующего "http: //", я бы просто сделал что-то вроде этого:

if (!url.startsWith("http://") && !url.startsWith("https://"))
   url = "http://" + url;

Я бы также, вероятно, предварительно заполнил ваш EditText, чтобы пользователь вводил URL с помощью «http: //».


2
За исключением того, что ваш код и mbaird не совпадают, насколько я могу судить по тому, что опубликовано. Убедитесь, что ваш URL имеет http://схему - показанное исключение предполагает, что вашему URL не хватает схемы.
CommonsWare

5
Да ! Он пропустил http: //! URL вводится пользователем, есть ли способ автоматического форматирования?
Арута

4
URLUtil - отличный способ проверить введенные пользователем строки "url"
Dan

90
if (!url.startsWith("http://") && !url.startsWith("https://"))Это распространенная ошибка, которая может привести к URL-адресам, таким как file: // и нарушить некоторые хорошие примеры использования. Попробуйте проанализировать URI с помощью класса URI и проверьте, есть ли схема. Если нет, добавьте «http: //»;)
tuxSlayer

22
Вам нужно проверить NULL с resolveCheck. См. Официальные документы : Внимание! Если на устройстве нет приложений, которые могут получить неявное намерение, ваше приложение будет аварийно завершено при вызове startActivity (). Чтобы сначала убедиться, что приложение существует для получения намерения, вызовите resolActivity () для объекта Intent.
кендзю

91

Распространенный способ добиться этого с помощью следующего кода:

String url = "http://www.stackoverflow.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url)); 
startActivity(i); 

это может быть изменено на короткую версию кода ...

Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("http://www.stackoverflow.com"));      
startActivity(intent); 

или :

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.stackoverflow.com")); 
startActivity(intent);

кратчайший! :

startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.stackoverflow.com")));

Удачного кодирования!


58

В 2.3 мне повезло больше

final Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url));
activity.startActivity(intent);

Разница заключается в использовании, Intent.ACTION_VIEWа не строки"android.intent.action.VIEW"


1
что это другое?
user1324936

1
Этот ответ мне очень помог. Я не знаю, в чем была разница, но у нас была проблема с 2.3, что это решило. Кто-нибудь знает в чем разница в реализации?
Innova

2
По словам разработчика Android: этот ответ - «Создать намерение с заданным действием. Все остальные поля (данные, тип, класс) являются пустыми». и принятый ответ - «Создать намерение с заданным действием и для заданного URL-адреса данных».
Тео Инке

58

Простой ответ

Вы можете увидеть официальный образец от Android Developer .

/**
 * Open a web page of a specified URL
 *
 * @param url URL to open
 */
public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Как это работает

Пожалуйста, посмотрите на конструктор Intent:

public Intent (String action, Uri uri)

Вы можете пройти android.net.Uri экземпляр второму параметру, и на основе заданного URL-адреса данных создается новое намерение.

А затем просто позвоните, startActivity(Intent intent)чтобы начать новое действие, которое связано с намерением с данным URL.

Нужен ли мне ifчек?

Да. документах говорят:

Если на устройстве нет приложений, которые могут получить неявное намерение, ваше приложение будет аварийно завершено при вызове startActivity (). Чтобы сначала убедиться, что приложение существует для получения намерения, вызовите resolActivity () для объекта Intent. Если результат не нулевой, есть хотя бы одно приложение, которое может обработать намерение, и безопасно вызывать startActivity (). Если результат нулевой, вы не должны использовать намерение и, если возможно, вы должны отключить функцию, которая вызывает намерение.

бонус

Вы можете написать в одну строку при создании экземпляра Intent, как показано ниже:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));

3
Это предполагает, что в указанном URL-адресе содержится http .
Игорь Ганапольский

30

Попробуй это:

Uri uri = Uri.parse("https://www.google.com");
startActivity(new Intent(Intent.ACTION_VIEW, uri));

или если вы хотите, чтобы веб-браузер открывался в вашей активности, сделайте так:

WebView webView = (WebView) findViewById(R.id.webView1);
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
webView.loadUrl(URL);

и если вы хотите использовать управление масштабированием в вашем браузере, то вы можете использовать:

settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);

4
Обратите внимание, что плагины и тому подобное отключены в WebView, и что для этого потребуются разрешения ИНТЕРНЕТ. ( ссылка )

22

Если вы хотите показать пользователю диалог со всем списком браузеров, чтобы он мог выбрать предпочтительный, вот пример кода:

private static final String HTTPS = "https://";
private static final String HTTP = "http://";

public static void openBrowser(final Context context, String url) {

     if (!url.startsWith(HTTP) && !url.startsWith(HTTPS)) {
            url = HTTP + url;
     }

     Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
     context.startActivity(Intent.createChooser(intent, "Choose browser"));// Choose browser is arbitrary :)

}

5
если есть несколько приложений, которые могут обработать намерение, система автоматически предоставит выбор, верно?
Джеффри Блатман

@ xmen-wk, потому что url может запускать эфир с помощью httpили https, а в java хорошей практикой является объявление «магических строк» ​​в качестве констант.
Дмитрий Данилик

спасибо, не знал о context.startActivity. Очень полезно при вызове из внешнего класса
WuerfelDev

18

Как и решения, написанные другими (которые отлично работают), я хотел бы ответить на то же самое, но с подсказкой, которую, я думаю, большинство предпочло бы использовать.

Если вы хотите, чтобы приложение, которое вы начали открывать в новой задаче, независимо от вас, вместо того, чтобы оставаться в одном стеке, вы можете использовать этот код:

final Intent intent=new Intent(Intent.ACTION_VIEW,Uri.parse(url));
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY|Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET|Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);

Существует также способ открыть URL-адрес в пользовательских вкладках Chrome . Пример в Котлине:

@JvmStatic
fun openWebsite(activity: Activity, websiteUrl: String, useWebBrowserAppAsFallbackIfPossible: Boolean) {
    var websiteUrl = websiteUrl
    if (TextUtils.isEmpty(websiteUrl))
        return
    if (websiteUrl.startsWith("www"))
        websiteUrl = "http://$websiteUrl"
    else if (!websiteUrl.startsWith("http"))
        websiteUrl = "http://www.$websiteUrl"
    val finalWebsiteUrl = websiteUrl
    //https://github.com/GoogleChrome/custom-tabs-client
    val webviewFallback = object : CustomTabActivityHelper.CustomTabFallback {
        override fun openUri(activity: Activity, uri: Uri?) {
            var intent: Intent
            if (useWebBrowserAppAsFallbackIfPossible) {
                intent = Intent(Intent.ACTION_VIEW, Uri.parse(finalWebsiteUrl))
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_HISTORY
                        or Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
                if (!CollectionUtil.isEmpty(activity.packageManager.queryIntentActivities(intent, 0))) {
                    activity.startActivity(intent)
                    return
                }
            }
            // open our own Activity to show the URL
            intent = Intent(activity, WebViewActivity::class.java)
            WebViewActivity.prepareIntent(intent, finalWebsiteUrl)
            activity.startActivity(intent)
        }
    }
    val uri = Uri.parse(finalWebsiteUrl)
    val intentBuilder = CustomTabsIntent.Builder()
    val customTabsIntent = intentBuilder.build()
    customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NO_HISTORY
            or Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
    CustomTabActivityHelper.openCustomTab(activity, customTabsIntent, uri, webviewFallback)
}

Будет ли выполнение новой задачи защищать исходное приложение от ошибок и сбоев в случае проблем с веб-браузером?
Оригинальный Android

@TheOriginalAndroid Я не понимаю, какое это имеет отношение к сбоям и веб-браузеру. Пожалуйста, объясните, что вы пытаетесь сделать.
Android-разработчик

Спасибо за ваш ответ. Ваш пост интересен. В чем выгода открытия новой задачи, особенно для запуска в Интернете?
Оригинальный Android

2
@TheOriginalAndroid Просто для того, чтобы пользователь мог переключиться обратно на ваше приложение, а затем снова вернуться в веб-браузер. Если вы откроете экран недавних задач, вы увидите 2 задачи вместо одной. Кроме того, вместо того, чтобы видеть миниатюру веб-браузера в одной задаче (которая относится к задаче вашего приложения), вы увидите 2: одно ваше приложение, а другое - веб-браузер. Я думаю, это менее запутанно.
Android-разработчик

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESETустарела
Пратик Бутани

17

другой вариант в URL загрузки в том же приложении, используя Webview

webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://www.google.com");

Обратите внимание, что плагины и тому подобное отключены в WebView, и что для этого потребуются разрешения ИНТЕРНЕТ. ( ссылка )

12

Вы также можете пойти по этому пути

В xml:

<?xml version="1.0" encoding="utf-8"?>
<WebView  
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

В коде Java:

public class WebViewActivity extends Activity {

private WebView webView;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.webview);

    webView = (WebView) findViewById(R.id.webView1);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.loadUrl("http://www.google.com");

 }

}

В Manifest не забудьте добавить интернет-разрешение ...


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

9

Webview может быть использован для загрузки URL в вашем приложении. URL может быть предоставлен от пользователя в текстовом представлении, или вы можете жестко его кодировать.

Также не забывайте интернет-разрешения в AndroidManifest.

String url="http://developer.android.com/index.html"

WebView wv=(WebView)findViewById(R.id.webView);
wv.setWebViewClient(new MyBrowser());
wv.getSettings().setLoadsImagesAutomatically(true);
wv.getSettings().setJavaScriptEnabled(true);
wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
wv.loadUrl(url);

private class MyBrowser extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
}

1
Это исправило мою проблему с видео: github.com/CrandellWS/VideoEnabledWebView/blob/master/app/src/…
CrandellWS

6

Краткая версия кода ...

 if (!strUrl.startsWith("http://") && !strUrl.startsWith("https://")){
     strUrl= "http://" + strUrl;
 }


 startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(strUrl)));

6

В своем блоке try вставьте следующий код. Android Intent напрямую использует ссылку в фигурных скобках URI (Uniform Resource Identifier), чтобы определить местоположение вашей ссылки.

Вы можете попробовать это:

Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(myIntent);

5

Простая и лучшая практика

Способ 1:

String intentUrl="www.google.com";
Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(intentUrl));
    if(webIntent.resolveActivity(getPackageManager())!=null){
        startActivity(webIntent);    
    }else{
      /*show Error Toast 
              or 
        Open play store to download browser*/
            }

Способ 2:

try{
    String intentUrl="www.google.com";
    Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(intentUrl));
        startActivity(webIntent);
    }catch (ActivityNotFoundException e){
                /*show Error Toast
                        or
                  Open play store to download browser*/
    }

Используйте context!!.packageManagerвместо getPackageManager()в Fragment.
CoolMind


3
Intent getWebPage = new Intent(Intent.ACTION_VIEW, Uri.parse(MyLink));          
startActivity(getWebPage);

Добро пожаловать, новичок. пожалуйста, сделайте ответ более полным, объявив переменные, которые не существуют в исходном коде.
Тони Гил

3

Ответ MarkB правильный. В моем случае я использую Xamarin, и код для использования с C # и Xamarin:

var uri = Android.Net.Uri.Parse ("http://www.xamarin.com");
var intent = new Intent (Intent.ActionView, uri);
StartActivity (intent);

Эта информация взята из: https://developer.xamarin.com/recipes/android/fundamentals/intent/open_a_webpage_in_the_browser_application/


3

Пользовательские вкладки Chrome теперь доступны:

Первым шагом является добавление библиотеки поддержки пользовательских вкладок в файл build.gradle:

dependencies {
    ...
    compile 'com.android.support:customtabs:24.2.0'
}

А затем, чтобы открыть пользовательскую вкладку Chrome:

String url = "https://www.google.pt/";
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(this, Uri.parse(url));

Для получения дополнительной информации: https://developer.chrome.com/multidevice/android/customtabs


2

Основываясь на ответе Марка Б и комментариях ниже:

protected void launchUrl(String url) {
    Uri uri = Uri.parse(url);

    if (uri.getScheme() == null || uri.getScheme().isEmpty()) {
        uri = Uri.parse("http://" + url);
    }

    Intent browserIntent = new Intent(Intent.ACTION_VIEW, uri);

    if (browserIntent.resolveActivity(getPackageManager()) != null) {
        startActivity(browserIntent);
    }
}

2

android.webkit.URLUtilметод guessUrl(String)работает отлично (даже с file://или data://) с тех пор Api level 1(Android 1.0). Использовать как:

String url = URLUtil.guessUrl(link);

// url.com            ->  http://url.com/     (adds http://)
// http://url         ->  http://url.com/     (adds .com)
// https://url        ->  https://url.com/    (adds .com)
// url                ->  http://www.url.com/ (adds http://www. and .com)
// http://www.url.com ->  http://www.url.com/ 
// https://url.com    ->  https://url.com/
// file://dir/to/file ->  file://dir/to/file
// data://dataline    ->  data://dataline
// content://test     ->  content://test

В разделе Активность звоните:

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(URLUtil.guessUrl(download_link)));

if (intent.resolveActivity(getPackageManager()) != null)
    startActivity(intent);

Проверьте полный guessUrlкод для получения дополнительной информации.


2

Хорошо, я проверил каждый ответ, но какое приложение имеет глубокие ссылки с тем же URL, который пользователь хочет использовать?

Сегодня я получил это дело, и ответ browserIntent.setPackage("browser_package_name");

например:

   Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
    browserIntent.setPackage("com.android.chrome"); // Whatever browser you are using
    startActivity(browserIntent);

Спасибо!


Хороший ответ. В нем объясняется, как открыть намеренный URL в конкретном браузере (напрямую), а не полагаться на то, что система выбирает браузер.
Mr-IDE

2

Простой, просмотр сайта через намерение,

Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse("http://www.yoursite.in"));
startActivity(viewIntent);  

Используйте этот простой код для просмотра вашего сайта в приложении для Android.

Добавить интернет-разрешение в файле манифеста,

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

2
String url = "https://www.thandroid-mania.com/";
if (url.startsWith("https://") || url.startsWith("http://")) {
    Uri uri = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
}else{
    Toast.makeText(mContext, "Invalid Url", Toast.LENGTH_SHORT).show();
}

Эта ошибка произошла из-за неверного URL, Android OS не может найти представление действий для ваших данных. Таким образом, вы подтвердили, что URL действителен или нет.


1

Я думаю это лучшее

openBrowser(context, "http://www.google.com")

Поместите код ниже в глобальный класс

    public static void openBrowser(Context context, String url) {

        if (!url.startsWith("http://") && !url.startsWith("https://"))
            url = "http://" + url;

        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        context.startActivity(browserIntent);
    }

1

Этот способ использует метод, позволяющий вам вводить любую строку вместо фиксированного ввода. Это сохраняет некоторые строки кода, если их использовать многократно, поскольку для вызова метода нужно всего три строки.

public Intent getWebIntent(String url) {
    //Make sure it is a valid URL before parsing the URL.
    if(!url.contains("http://") && !url.contains("https://")){
        //If it isn't, just add the HTTP protocol at the start of the URL.
        url = "http://" + url;
    }
    //create the intent
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)/*And parse the valid URL. It doesn't need to be changed at this point, it we don't create an instance for it*/);
    if (intent.resolveActivity(getPackageManager()) != null) {
        //Make sure there is an app to handle this intent
        return intent;
    }
    //If there is no app, return null.
    return null;
}

Использование этого метода делает его универсальным для использования. ИТ не нужно помещать в конкретную деятельность, так как вы можете использовать это следующим образом:

Intent i = getWebIntent("google.com");
if(i != null)
    startActivity();

Или, если вы хотите запустить его вне действия, просто вызовите startActivity для экземпляра действия:

Intent i = getWebIntent("google.com");
if(i != null)
    activityInstance.startActivity(i);

Как видно из обоих этих блоков кода, есть нулевая проверка. Это как он возвращает ноль, если нет приложения для обработки намерения.

Этот метод по умолчанию использует HTTP, если протокол не определен, так как есть сайты, у которых нет SSL-сертификата (что вам нужно для подключения HTTPS), и они перестанут работать, если вы попытаетесь использовать HTTPS, а его там нет. , Любой веб-сайт все еще может перейти на HTTPS, так что эти стороны в любом случае приводят вас к HTTPS.


Поскольку этот метод использует внешние ресурсы для отображения страницы, вам не нужно объявлять разрешение INternet. Приложение, которое отображает веб-страницу, должно сделать это


1

// OnClick Listener

  @Override
      public void onClick(View v) {
        String webUrl = news.getNewsURL();
        if(webUrl!="")
        Utils.intentWebURL(mContext, webUrl);
      }

// Ваш Util Method

public static void intentWebURL(Context context, String url) {
        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            url = "http://" + url;
        }
        boolean flag = isURL(url);
        if (flag) {
            Intent browserIntent = new Intent(Intent.ACTION_VIEW,
                    Uri.parse(url));
            context.startActivity(browserIntent);
        }

    }

Где определяется «isURL»?
Cabuxa.Mapache

1

Просто перейдите с коротким, чтобы открыть свой URL в браузере:

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("YourUrlHere"));
startActivity(browserIntent);

1

Котлин ответ:

val browserIntent = Intent(Intent.ACTION_VIEW, uri)
ContextCompat.startActivity(context, browserIntent, null)

Я добавил расширение, Uriчтобы сделать это еще проще

fun Uri?.openInBrowser(context: Context) {
    this ?: return // Do nothing if uri is null

    val browserIntent = Intent(Intent.ACTION_VIEW, this)
    ContextCompat.startActivity(context, browserIntent, null)
}

В качестве бонуса, здесь есть простая функция расширения для безопасного преобразования строки в Uri.

fun String?.asUri(): Uri? {
    try {
        return Uri.parse(this)
    } catch (e: Exception) {}
    return null
}

1

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

Мне наконец-то удалось это сделать:

// gathering the default browser
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
final ResolveInfo resolveInfo = context.getPackageManager()
    .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
String defaultBrowserPackageName = resolveInfo.activityInfo.packageName;


final Intent intent2 = new Intent(Intent.ACTION_VIEW);
intent2.setData(Uri.parse(url));

if (!defaultBrowserPackageName.equals("android") {
    // android = no default browser is set 
    // (android < 6 or fresh browser install or simply no default set)
    // if it's the case (not in this block), it will just use normal way.
    intent2.setPackage(defaultBrowserPackageName);
}

context.startActivity(intent2);

Кстати, вы можете заметить. contextЧто угодно , потому что я использовал это для статического метода утилит, если вы делаете это в деятельности, это не нужно.



0

Попробуйте это .. Работал для меня!

    public void webLaunch(View view) {
            WebView myWebView = (WebView) findViewById(R.id.webview);
            myWebView.setVisibility(View.VISIBLE);
            View view1=findViewById(R.id.recharge);
            view1.setVisibility(View.GONE);
            myWebView.getSettings().setJavaScriptEnabled(true);
            myWebView.loadUrl("<your link>");

        }

XML-код: -

 <WebView  xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/webview"
        android:visibility="gone"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />

--------- ИЛИ------------------

String url = "";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);

Для большинства приложений добавить WebView - трудный способ сделать это. Проще открыть URL в браузере.
Зоя
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.