0

I'm trying to make an Android app communicate with a MySQL database. I get the following error even with the correct permissions set up in the manifest:

java.net.SocketException: socket failed: EACCES (Permission denied) in Android Studio

Here is the AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.biddingapp">

    <uses-configuration android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />


    <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">
        <activity android:name=".SecondActivity"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Here is the MainActivity.java

public class MainActivity extends AppCompatActivity {

    private EditText username;
    private EditText password;
    private Button login;

    Connection con;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        username = (EditText)findViewById(R.id.username);
        password = (EditText)findViewById(R.id.password);
        login = (Button)findViewById(R.id.login);

        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new MainActivity.checkLogin().execute("");
            }
        });
    }

    private class checkLogin extends AsyncTask<String, String, String>{

        String str = null;
        Boolean isSuccess = false;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
        }

        @Override
        protected String doInBackground(String... strings) {
            con = connectionClass(ConnectionClass.user.toString(),ConnectionClass.password.toString(),ConnectionClass.database.toString(),ConnectionClass.server.toString());
            if(con == null){
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,"Check Internet Connection",Toast.LENGTH_LONG).show();
                    }
                });
                str = "On Internet Connection";
            }
            else {
                try {
                    String sql = "SELECT * FROM users WHERE username = '" + username.getText() + "' AND password = '" + password.getText() + "' ";
                    Statement stmt = con.createStatement();
                    ResultSet rs = stmt.executeQuery(sql);

                    if (rs.next()) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "Login Success", Toast.LENGTH_LONG).show();
                            }
                        });
                        str = "Success";

                        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                        startActivity(intent);
                        finish();
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "Check email or password", Toast.LENGTH_LONG).show();
                            }
                        });

                        username.setText("");
                        password.setText("");
                    }
                } catch (Exception e) {
                    isSuccess = false;
                    Log.e("SQL Error : ", e.getMessage());
                }
            }
            return str;
        }
    }

    @SuppressLint("NewApi")
    public Connection connectionClass(String user, String password, String database, String server){
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        Connection connection = null;
        String connectionURL = null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            connectionURL = "jdbc:mysql://localhost/biddingapp://" + server+"/" + database + ";user=" + user + ";password=" + password + ";";
            connection = DriverManager.getConnection(connectionURL);
        }catch (Exception e){
            Log.e("SQL Connection Error : ", e.getMessage());
        }

        return connection;
    }
}

Here is the ConnectionClass.java

package com.example.biddingapp;

import android.annotation.SuppressLint;
import android.os.StrictMode;
import android.util.Log;

import java.sql.Connection;
import java.sql.DriverManager;

public class ConnectionClass {
    public static String user = "androidstudio";
    public static String password = "program";
    public static String database = "users";
    public static String server = "localhost";
}

How can I solve this issue? Is there any better way to do this?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • Which error are you referring to? – blackapps Jan 05 '21 at 21:28
  • 1
    `localhost` is the Android device itself, and I suspect that is not where MySQL is running. Also, note that using JDBC to directly connect to a MySQL database is not recommended, for reliability and security reasons. – CommonsWare Jan 05 '21 at 21:29
  • `if(con == null)` Dirty code. You should just return null and display a Toast in onPostExecute. Its for that. Dont use runOnUiThread there. Dirty code. – blackapps Jan 05 '21 at 21:32
  • Can you tell me, which android Version you are using? – puspak saha Jan 06 '21 at 12:14
  • Does this answer your question? [Error message 'java.net.SocketException: socket failed: EACCES (Permission denied)'](https://stackoverflow.com/questions/11273197/error-message-java-net-socketexception-socket-failed-eacces-permission-denie) – puspak saha Jan 06 '21 at 12:22

3 Answers3

0

The first line should be: <uses-permission android:name="android.permission.INTERNET" />

I think you are running the application in an android emulator and want connect to a sql server running on your host machine.

Connecting from the Android emulator to the machine the emulator is running on, you need to use the IP 10.0.2.2

More Information you can find here

mhlnstdt25
  • 41
  • 7
0
  • 1st The permission <uses-permission android:name="android.permission.INTERNET" /> suppose to be like this,

  • 2nd How do you access the database, If using local storage, Then <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> and <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> needed.

  • You also need to have runtime permission.

  • 3rd If you are using Android 10 or upper version You need to add legacy Storage permission android:requestLegacyExternalStorage="true" under the <application/> tab.

for more information click here.

0

You need to mention the port as well.

MySQL runs on 3306 port on local machine.

Do the following:

connectionURL = "jdbc:mysql://localhost:3306/biddingapp://" + server+"/" + database + ";user=" + user + ";password=" + password + ";";

Moreover, internet permission needs to be corrected

<uses-permission android:name="android.permission.INTERNET" />
Umer Khalid
  • 330
  • 2
  • 16