尝试通过JDBC连接Android到MySQL数据库时出错。

huangapple go评论76阅读模式
英文:

Error when trying to connect mySQL DB to Android via JDBC

问题

以下是翻译好的部分:

当我尝试通过JDBC将MySQL数据库连接到Android时,出现以下错误:

2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: com.mysql.cj.jdbc.exceptions.CommunicationsException: 通信链接失败
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: 上次成功发送到服务器的数据包距离现在0毫秒。驱动程序未从服务器接收到任何数据包。
...
...


以下是我的代码:

```java
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtility
{
    public static Connection connect() throws IOException, ClassNotFoundException, SQLException {
        Connection con =null;

            Class.forName("com.mysql.cj.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://192.168.1.202:3306/mmi?useSSL=false", "username", "password");

        return con;
    }
}
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class MainActivity extends AppCompatActivity {

    EditText mTextUsername;
    EditText mTextPassword;
    Button mButtonLogin;
    TextView mTextViewForgot;

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

        mTextUsername = (EditText) findViewById(R.id.edittext_username);
        mTextPassword = (EditText) findViewById(R.id.edittext_password);
        mButtonLogin = (Button) findViewById(R.id.button_login);
        mTextViewForgot = (TextView) findViewById(R.id.textview_forgot);
        mTextViewForgot.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Intent forgotIntent = new Intent (MainActivity.this,ForgotActivity.class);
                startActivity(forgotIntent);
            }
        });

        mButtonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {

                String user = mTextUsername.getText().toString().trim();
                String pwd = mTextPassword.getText().toString().trim();

                boolean res = checkUser(user, pwd);
                if (res)
                {
                    Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    Toast.makeText(MainActivity.this, "登录错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    public boolean checkUser(String user, String pass)
    {
        boolean statement = false;
        try {
            Connection con = DBUtility.connect();
            Statement st = con.createStatement();
            statement = true;
            ResultSet rs = st.executeQuery("SELECT * FROM mmi_userinfo where USERNAME='"+ user + "' and USER PASSWORD='"+ pass + "'");

            if (rs.next()) {
                statement = true;
            }

        }catch (Exception e)
        {
            e.printStackTrace();
        }
        return statement;
    }
}

我确认我的数据库正在运行,我刷新了我的DNS,我将my.cnf文件更改为适当的bind-address,并删除了skip-networking行。

我不确定是什么阻止了这个工作,任何帮助将不胜感激。


<details>
<summary>英文:</summary>
I get the following errors when trying to connect mySQL DB to Android via JDBC:

2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at java.sql.DriverManager.getConnection(DriverManager.java:580)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at java.sql.DriverManager.getConnection(DriverManager.java:218)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at com.example.mmi.DBUtility.connect(DBUtility.java:14)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at com.example.mmi.MainActivity.checkUser(MainActivity.java:99)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at com.example.mmi.MainActivity$2.onClick(MainActivity.java:49)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at android.view.View.performClick(View.java:7125)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at android.view.View.performClickInternal(View.java:7102)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at android.view.View.access$3500(View.java:801)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at android.view.View$PerformClick.run(View.java:27336)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at android.os.Handler.handleCallback(Handler.java:883)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err: at android.os.Handler.dispatchMessage(Handler.java:100)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: at android.os.Looper.loop(Looper.java:214)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7356)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at java.lang.reflect.Constructor.newInstance0(Native Method)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.NativeSession.connect(NativeSession.java:144)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: ... 19 more
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: Caused by: java.net.SocketException: socket failed: EPERM (Operation not permitted)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: at java.net.Socket.createImpl(Socket.java:492)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: at java.net.Socket.getImpl(Socket.java:552)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: at java.net.Socket.setTcpNoDelay(Socket.java:1012)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.protocol.StandardSocketFactory.configureSocket(StandardSocketFactory.java:94)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:147)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err: ... 22 more
2020-06-28 21:08:58.015 31747-31788/com.example.mmi D/EGL_emulation: eglMakeCurrent: 0xe2da9260: ver 3 0 (tinfo 0xe2d99b40)
2020-06-28 21:08:58.026 31747-31788/com.example.mmi D/EGL_emulation: eglMakeCurrent: 0xe2da9260: ver 3 0 (tinfo 0xe2d99b40)


Here is my code:

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtility
{
public static Connection connect() throws IOException, ClassNotFoundException, SQLException {
Connection con =null;

        Class.forName(&quot;com.mysql.cj.jdbc.Driver&quot;);
con = DriverManager.getConnection(&quot;jdbc:mysql://192.168.1.202:3306/mmi?useSSL=false&quot;, &quot;username&quot;, &quot;password&quot;);
return con;
}

}


import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class MainActivity extends AppCompatActivity {

EditText mTextUsername;
EditText mTextPassword;
Button mButtonLogin;
TextView mTextViewForgot;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextUsername = (EditText) findViewById(R.id.edittext_username);
mTextPassword = (EditText) findViewById(R.id.edittext_password);
mButtonLogin = (Button) findViewById(R.id.button_login);
mTextViewForgot = (TextView) findViewById(R.id.textview_forgot);
mTextViewForgot.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Intent forgotIntent = new Intent (MainActivity.this,ForgotActivity.class);
startActivity(forgotIntent);
}
});
mButtonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view)
{
String user = mTextUsername.getText().toString().trim();
String pwd = mTextPassword.getText().toString().trim();
boolean res = checkUser(user, pwd);
if (res)
{
Toast.makeText(MainActivity.this, &quot;Successfully Logged In&quot;, Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, &quot;Login Error&quot;, Toast.LENGTH_SHORT).show();
}
}
});
}
public boolean checkUser(String user, String pass)
{
boolean statement = false;
try {
Connection con = DBUtility.connect();
Statement st = con.createStatement();
statement = true;
ResultSet rs = st.executeQuery(&quot;SELECT * FROM mmi_userinfo where USERNAME=&#39;&quot;+ user + &quot;&#39; and USER PASSWORD=&#39;&quot; + pass + &quot;&#39;&quot;);
if (rs.next()) {
statement = true;
}
}catch (Exception e)
{
e.printStackTrace();
}
return statement;
}

}

I&#39;ve confirmed my DB is running, I&#39;ve flushed my DNS, I changed the my.cnf file to bind-address appropriately, and I removed the skip-networking line.  
I am not sure what is preventing this from working, any help would be appreciated.
</details>
# 答案1
**得分**: 0
你需要获取你要连接的计算机的实际IP地址。127.0.0.1指的是本地主机(在你的情况下是你的Android手机或模拟器),这是一个错误的目标。请查看已经回答的问题 [链接在这里][1]。
<details>
<summary>英文:</summary>
You have to get the actual IP address of the computer you are connecting to. 127.0.0.1 refers to localhost (in your case, your android phone or emulator), which is a wrong destination.Have a look at the question that was answered [available here][1]
[1]: https://stackoverflow.com/questions/26470117/can-we-connect-remote-mysql-database-in-android-using-jdbc
</details>
# 答案2
**得分**: 0
错误堆栈跟踪中,如果仔细查看,在末尾您会看到是什么导致了它:
&gt; Caused by: java.net.SocketException: socket failed: EPERM (Operation not permitted)
这意味着应用程序缺少进行网络连接所需的必要权限:请参阅
https://developer.android.com/training/basics/network-ops/connecting
您需要将以下内容添加到应用程序清单中:
```xml
&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_NETWORK_STATE&quot; /&gt;

在您添加这些内容之后,您应该开始看到不同的错误,这次是由于NetworkOnMainThreadException引起的,因为您正在尝试在应用程序主线程上连接到网络资源。有几种解决方法,随着新技术的开发,推荐的方法也在变化。开发者指南应始终包含最新信息:https://developer.android.com/guide/background/threading

当前的建议似乎是使用来自Android架构组件的ViewModel和MutableLiveData。您将网络操作提交给线程池(ExecutorService的实例),并在操作完成时更新MutableLiveData。

英文:

If you look closely at the error stack trace, towards the end you see what caused it:

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

This means the app is missing the necessary permissions for making network connections: see
https://developer.android.com/training/basics/network-ops/connecting

You have to add these to the app manifest:

&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
&lt;uses-permission android:name=&quot;android.permission.ACCESS_NETWORK_STATE&quot; /&gt;

After you do that, you should start seeing a different error, this time caused by NetworkOnMainThreadException because you are trying to connect to a network resource on the application main thread. There are several ways to solve that and the recommended way changes as new technology is developed. The developer guide should always have the latest information: https://developer.android.com/guide/background/threading

The current recommendation seems to be to use ViewModel and MutableLiveData from the Android Architecture components. You submit the networked operation to a thread pool (instance of ExecutorService) and have it update the MutableLiveData when it finishes.

huangapple
  • 本文由 发表于 2020年6月29日 10:16:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/62630259.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定