Требуется ли android.permission.INTERNET снова с API 28?

После попытки обновить уровень admob и API до API 28 я получаю это предупреждение Lint:

Missing permissions required by MobileAds.initialize: android.permission.INTERNET

при вызове этих функций:

MobileAds.initialize(context, context.getString(R.string.app_id));
mInterstitialAd.loadAd(new AdRequest.Builder().build());

Как это возможно?

Я помню, что android.permission.INTERNET не требовалось много лет назад. Приложения могут получить доступ к Интернету без использования этого разрешения. Даже в этом приложении у меня есть некоторые подключения к Интернету, и они успешно работают. Я получаю данные, и они работают, и даже реклама отображается. И все без разрешения, заявленного в манифесте.

Почему Lint отображает это предупреждение?


person NullPointerException    schedule 02.05.2019    source источник
comment
Я не знаю ни одного документа, указывающего, что разрешение на Интернет не требуется. Вы должны иметь android.permission.INTERNET в манифесте, если вы получаете доступ к Интернету.. Если у вас есть какой-либо документ, указывающий на это, разместите его здесь.   -  person ADM    schedule 02.05.2019
comment
Если у вас нет этого разрешения и вы можете использовать Интернет, это может быть связано с тем, что какая-то библиотека в вашем проекте уже имеет его, и, поскольку это не разрешение времени выполнения, оно будет автоматически разрешено.   -  person ADM    schedule 02.05.2019


Ответы (4)


С тех пор требуется разрешение android.permission.INTERNET.

Но возможно, что uses-permission был объявлен включенной вами зависимостью, и теперь его больше нет, либо потому, что вы удалили эту зависимость, либо в ее обновленной версии она больше не требуется. Итак, теперь вы должны запросить разрешение явно в своем манифесте.

person Floern    schedule 02.05.2019
comment
Чтобы проверить, откуда исходит разрешение, вы можете выбрать вкладку Объединенный манифест при редактировании манифеста вашего приложения. - person Xavier Rubio Jansana; 02.05.2019

android.permission.INTERNET необходимо объявить в манифесте, но он имеет уровень защиты нормальный (т.е. не опасен). Обычные разрешения не должны запрашивать доступ к пользователю, как опасные, но должны быть объявлены. См. обзор разрешений (выделение добавлено):

Если приложение заявляет в своем манифесте, что ему требуется обычное разрешение, система автоматически предоставляет приложению это разрешение во время установки. Система не предлагает пользователю предоставлять обычные разрешения, и пользователи не могут отозвать эти разрешения.

person Xavier Rubio Jansana    schedule 02.05.2019

Приложения могут получить доступ к Интернету без использования этого разрешения

Нет, они не.

Разрешение не было предоставлено пользователю в течение некоторого времени, оно было предоставлено автоматически, даже до того, как Android 6.0 автоматически предоставил все normal разрешения. Тем не менее, это все еще необходимое разрешение для сетевого ввода-вывода, исходящего от вашего процесса.

Например, я создал ненужный проект Kotlin с сопрограммами и изменил MainActivity на:

package com.commonsware.android.myapplication

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedInputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    GlobalScope.launch(Dispatchers.Main) {
      doTheDownload()
      Toast.makeText(this@MainActivity, "Done!", Toast.LENGTH_LONG).show()
    }
  }

  private suspend fun doTheDownload() {
    withContext(Dispatchers.IO) {
      val url = URL("https://commonsware.com")
      val urlConnection = url.openConnection() as HttpURLConnection

      try {
        val content =
          InputStreamReader(BufferedInputStream(urlConnection.inputStream)).use {
            it.readText()
          }

        Log.d("This was fun!", content)
      } finally {
        urlConnection.disconnect()
      }
    }
  }
}

Без разрешения INTERNET я вылетаю с:

java.lang.SecurityException: Permission denied (missing INTERNET permission?)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:151)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
    at java.net.InetAddress.getAllByName(InetAddress.java:1154)
    at com.android.okhttp.Dns$1.lookup(Dns.java:39)
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:244)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26)
    at com.commonsware.android.myapplication.MainActivity$doTheDownload$2.invokeSuspend(MainActivity.kt:35)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
 Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
    at libcore.io.Linux.android_getaddrinfo(Native Method)
    at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:172)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:137)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105) 
    at java.net.InetAddress.getAllByName(InetAddress.java:1154) 
    at com.android.okhttp.Dns$1.lookup(Dns.java:39) 
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175) 
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141) 
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83) 
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174) 
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126) 
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95) 
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281) 
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224) 
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461) 
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407) 
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:244) 
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210) 
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26) 
    at com.commonsware.android.myapplication.MainActivity$doTheDownload$2.invokeSuspend(MainActivity.kt:35) 
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) 
 Caused by: android.system.ErrnoException: android_getaddrinfo failed: EACCES (Permission denied)
    at libcore.io.Linux.android_getaddrinfo(Native Method) 
    at libcore.io.BlockGuardOs.android_getaddrinfo(BlockGuardOs.java:172) 
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:137) 
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105) 
    at java.net.InetAddress.getAllByName(InetAddress.java:1154) 
    at com.android.okhttp.Dns$1.lookup(Dns.java:39) 
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175) 
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141) 
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83) 
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174) 
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126) 
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95) 
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281) 
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224) 
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461) 
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407) 
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:244) 
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210) 
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:26) 
    at com.commonsware.android.myapplication.MainActivity$doTheDownload$2.invokeSuspend(MainActivity.kt:35) 
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) 
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) 
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) 

С разрешением INTERNET приложение отлично загружает контент. Оба теста были на Android 9.0.

И все без разрешения, заявленного в манифесте.

Возможно, вы получаете это разрешение от библиотеки, хотя это не объясняет замешательства AdMob.

person CommonsWare    schedule 02.05.2019

MobileAds.initialize() имеет аннотацию @RequiresPermission("android.permission.INTERNET").

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

person laalto    schedule 02.05.2019