java.net.SocketException: error en el socket: EPERM (operación no permitida)
Estoy trabajando en un proyecto de Android Studio con varias actividades. Actualmente estoy intentando leer la salida de un servlet Java en localhost pero parece fallar debido a un permiso de socket.
Hice un nuevo proyecto, usé exactamente el mismo código y funcionó perfectamente. Entonces no entiendo por qué no está dispuesto a trabajar en mi proyecto.
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();
}
}
Espero que lea los datos pero falla en esta línea:
InputStream in = urlConnection.getInputStream();
Esta es la salida del error:
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)
Su aplicación necesita permisos adicionales y/o ser reinstalada.
Agregue permisos adicionales AndroidManifest.xml
dentro de la <manifest>
sección:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Para reinstalar, desinstale la aplicación del emulador o del dispositivo físico conectado y luego ejecútela nuevamente. (Si agrega permisos, asegúrese de reinstalarlos después ).
Desinstale la aplicación del emulador, ejecútela nuevamente y funcionará. Tuve el mismo problema.
Para desinstalar la aplicación, ejecute su proyecto cuando aparezca el mensaje "la aplicación se había detenido", haga clic en "información de la aplicación" y luego desinstale.
En primer lugar, necesita cambiar el archivo .xml del manifiesto de Android. Pero después de esta acción, debe desinstalar la aplicación y ejecutarla nuevamente. https://developer.android.com/training/basics/network-ops/connecting
y código aquí:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
en AndroidManifest.xml
Si olvidó agregarlo <uses-permission android:name="android.permission.INTERNET" />
a su Manifest.xml, hágalo ahora
Si ya la agregó pero el error persiste, primero desinstale la aplicación y luego ejecute i nuevamente.
La mayoría de las veces me encuentro con el mismo problema porque lo olvidé <uses-permission android:name="android.permission.INTERNET" />
en mi primera instalación.
El sistema operativo pensó que la aplicación no necesita permiso de Internet (lo cual es una tontería en mi opinión) y no verificaría ninguna actualización de permisos para la aplicación (lo cual es aún más tonto en mi opinión).
La única forma de indicarle al sistema operativo Android que verifique sus solicitudes de permiso actualizadas es desinstalar la aplicación antes de volver a instalarla.
creo que tampoco
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- ni
android:usesCleartextTraffic="true"
realmente importa aquí
Tuve que desinstalar la aplicación del emulador y luego todo empezó a funcionar. Solo necesitaba el siguiente permiso en AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />