java.net.socketexception: socket failed: eperm (operation not permitted)java.net.socketexception: socket failed: eperm (operation not permitted)と言うエラーが出たときの対処法

Android開発を行っていると、以下の様なエラーが出たので対処法を紹介していきます。

java.net.SocketException: socket failed: EPERM (Operation not permitted)

解決策1:Manifest.xmlにpermissionを追加する

一番最初にやるべきことは、AndroidManifest.xmlに以下の2行を追加することです。


<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> // 以下を追加 <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

詳細は、公式ページ「 ネットワークに接続する | Android Developers 」を見ると良いです。

解決策2:android:usesCleartextTraffic="true"を追加する

大抵の場合は解決策1を行う事で、上記のエラーは解決できると思います。

もし、現在のAndroid Studioで使っているエミュレータがAndroid9以上(API 28以上)でかつ、HTTPSではなくHTTPで通信を行っている場合は、AndroidManifest.xmlに以下のコードを追加しましょう。


// AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" // これを追加 android:usesCleartextTraffic="true" >

android:usesCleartextTrafficとは、HTTP通信を許可するかどうかを示したプロパティです。

API27以下ではデフォルトでtrue(HTTP通信を許可)になっていましたが、API28以上ではデフォルトでfalseになっているので、明示する必要があります。

公式ページにも以下の様に書かれています。

アプリが Android 9 以降をターゲットとしている場合、isCleartextTrafficPermitted() メソッドはデフォルトで false を返します。アプリで特定のドメインのクリアテキストを有効にする必要がある場合、アプリのネットワーク セキュリティ構成でそのドメインの cleartextTrafficPermitted を明示的に true に設定する必要があります。

動作の変更点: API レベル 28 以降をターゲットとするアプリ | Android Developers

このHTTP通信を許可するかどうかの書き方は色々あって、特定のドメインではHTTP通信を許可したりできます。

詳細は「 Android 8: Cleartext HTTP traffic not permitted - Stack Overflow 」の記事を見ると良いです。