java.net.SocketException: échec de la prise: EPERM (opération non autorisée)

144

Je travaille sur un projet Android Studio avec plusieurs activités. J'essaie actuellement de lire la sortie d'un servlet Java sur localhost, mais il semble se bloquer en raison d'une autorisation de socket.

J'ai créé un nouveau projet, utilisé exactement le même code et travaillé parfaitement. Donc je ne comprends pas pourquoi n'est pas disposé à travailler sur mon projet.

public class LoginActivity extends AppCompatActivity {


String apiUrl = "http://10.0.2.2:8080/ProyectService/Servlet?action=login";
EditText username;
EditText password;
AlertDialog dialog;
Usuario session;

@Override
public void onCreate(Bundle savedInstanceState) {
    // Inicializacion de ventana
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    getSupportActionBar().hide();

    // Inicializacion de componentes
    username = findViewById(R.id.username);
    password = findViewById(R.id.password);

    // Inicializacion de funcionalidad de botones
    Button button= (Button) findViewById(R.id.login);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            UserLoginTask mAuthTask = new UserLoginTask();
            mAuthTask.execute();
        }
    });

    password = findViewById(R.id.password);
    createAlertDialog("Usuario o Contraseña Incorrectos");
    }

    private void createAlertDialog(String message){
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(message)
            .setTitle("Error");
    dialog = builder.create();
    }



    // ASYNCRONUS NETWORK PROCESS

    public class UserLoginTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
    }


    @Override
    protected String doInBackground(String... params) {

        // implement API in background and store the response in current variable
        String current = "";
        try {
            URL url;
            HttpURLConnection urlConnection = null;
            try {
                url = new URL(apiUrl);
                System.out.println(apiUrl);
                urlConnection = (HttpURLConnection) url
                        .openConnection();

                InputStream in = urlConnection.getInputStream();

                InputStreamReader isw = new InputStreamReader(in);

                int data = isw.read();
                while (data != -1) {
                    current += (char) data;
                    data = isw.read();
                    //System.out.print(current);

                }
                System.out.print(current);
                // return the data to onPostExecute method
                return current;

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "Exception: " + e.getMessage();
        }
        return current;
        }
    }

    protected void onPostExecute(String success) {
        Log.i(success, "");
       //attemptLogin();
    }
}

Je m'attends à ce qu'il lise les données mais il plante à cette ligne:

InputStream in = urlConnection.getInputStream();

Voici la sortie d'erreur:

java.net.SocketException: socket failed: EPERM (Operation not permitted)
at java.net.Socket.createImpl(Socket.java:492)
at java.net.Socket.getImpl(Socket.java:552)
at java.net.Socket.setSoTimeout(Socket.java:1180)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:143)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:248)
at com.example.controller.LoginActivity$UserLoginTask.doInBackground(LoginActivity.java:114)
at com.example.controller.LoginActivity$UserLoginTask.doInBackground(LoginActivity.java:93)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Aaron Villalobos
la source

Réponses:

395

Résolu: Tout ce que j'avais à faire était de désinstaller l'application de l'émulateur et de l'exécuter à nouveau.

Aaron Villalobos
la source
8
cela a fonctionné pour moi aussi, avez-vous déjà trouvé pourquoi cela se produisait en premier lieu?
Vikas Pandey
9
Dans mon cas, j'ai dû fournir l'autorisation ACCESS_NETWORK_STATE. Ajoutez <uses-permission android: name = "android.permission.ACCESS_NETWORK_STATE" /> au manifeste. Et désinstaller aussi
sk md
3
Pareil ici. Il est étrange que la question soit si jeune. C'est peut-être un bug.
user1511417
1
L'application supprimée d'un émulateur et la réinstallation ont résolu mon problème, merci. Il semble que Firebase cache quelque chose dans le système de fichiers et le réutilise, je suppose que des données d'application claires résoudront également un problème.
Onregs le
1
peut-être que la permission est déjà mise en cache et la ruiner encore et encore n'est pas la mise à jour de la permission et au lieu de mettre à jour uniquement les fichiers src.? c'est la réinstallation a aidé.
Atif AbbAsi
38

désinstallez simplement l'application de l'émulateur puis exécutez à nouveau et cela fonctionnera j'ai eu le même problème

pour désinstaller l'application, exécutez votre projet lorsque le message "l'application s'est arrêtée" apparaît, cliquez sur "infos sur l'application" puis désinstaller

John Alexander
la source
1
Je ne sais pas comment, mais ça marche. Publication en décembre 2019. Bien que cela fonctionne, curieux de savoir pourquoi.
Rajkiran
30

Tout d'abord, vous devez modifier votre manifeste Android .xml Mais après cette action, vous devez désinstaller l'application et l'exécuter à nouveau. https://developer.android.com/training/basics/network-ops/connecting

et codez ici:

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

dans AndroidManifest.xml

Archil Labadze
la source
2
C'est vrai, si cela est déjà défini et que vous obtenez toujours la même erreur - faites comme suggéré ci-dessus - supprimez l'application sur l'appareil et réinstallez-la.
Vladislav Varslavans le
11

J'ai dû désinstaller l'application de l'émulateur, puis tout a commencé à fonctionner. J'avais juste besoin de l'autorisation suivante sur AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
Juan Cabello
la source
9
  1. Ajouter l'autorisation ACCESS_NETWORK_STATE dans le manifeste
  2. Émulateur de réinstallation
Habib Adnan
la source
2

Défini android:usesCleartextTraffic="true"dans le fichier manifeste. Ajoutez l'autorisation INTERNET. Désinstallez l'application, puis réinstallez-la.

Ssenyonjo
la source
0

Si quelqu'un a toujours ce problème, je l'ai rencontré lorsque j'ai utilisé un VPN et essayé de me connecter au wifi alors que le cellulaire était activé. J'utilisais le client VPN Anyconnect. La solution consiste à activer le contournement d'autorisation qui vous permettra de lier une socket à un réseau spécifique si c'est ce que vous recherchez.

AnyConnect n'utilise allowBypass que s'il est configuré dans ses restrictions gérées (par EMM), via cette clé: vpn_connection_allow_bypass.

ovidiur
la source