因此,我已经开始/关闭了几天,并感觉好像我已经用尽任何相关的搜索条件。首先我要说的是,我已经对此进行了很多的研究,但无济于事;我得出的结论是,这可能是非常不正常的事情(不太可能),或者是我忽略了一些细微的细节。让我也说明了,是的,我知道直接从应用程序连接到数据库并不理想,我应该使用Web服务器,但出于我的意图和目的,这个解决方案不是&# 39;问题。
我知道这篇文章超长,但我确实感谢所有人的时间。如果不出意外,至少它可能会帮助最近开始使用JDBC并开始遇到问题的其他人。 "我已经尝试过的"部分概述了您可以在网上找到的绝大部分内容。
我想做的事情:
使用JDBC驱动程序,通过Android Studio连接到我的Azure托管的SqlServer数据库。
我遇到的错误:
W/System.err: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host vet-to-go.database.windows.net, port 1433 has failed. Error: "Connection timed out: no further information. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
我尝试/验证的内容(短名单):
- 连接代码在活动类中发生,但它在AsyncTask中。
-uses-permission android:name =" android.permission.INTERNET"
-Azure防火墙配置为允许我的IP连接。
-Windows防火墙有适当的规则允许传入& 1433端口的出局流量。
- 从SQLServer配置管理器,我已启用命名管道& TCP / IP。在IP地址选项卡上,我已启用所有并将TCP端口设置为1433.已尝试使用&关闭TCP动态端口。
- 尝试使用SQL Server Browser运行&停止了(另一篇提到这样做的文章)。
- 试过同时使用jre7和amp; jre8 JDBC驱动程序。
-sourceCompatibility& targetCompatibility在相应的1_7或1_8版本中设置。
-compile files(' libs / sqljdbc41.jar')[或jre8的42]
- 更加拼命并且确保他们不是问题,在完全关闭Windows防火墙并允许任何IP通过Azure防火墙(开始/结束IP为0.0)连接后,我也无法连接。 0.0 - 255.255.255.255)
-I 可以 ping& telnet into(mydbname).database.windows.net 1433(DNS和实际IP)
考虑到以上所有,我只能假设错误落在我的代码中,但我绝对无法弄清楚在哪里。为了在棺材中钉一个钉子,应该提到我 能够成功地查询DB&在我的项目中返回一个值,但仅在静态的非活动类中。复制代码几乎完全没有在添加到实际活动类时产生结果。
这是工作代码:
import java.sql.*;
public class DatabaseHelper {
public static void main(String[] args) throws Exception {
String custID = "1";
String connectionString = "jdbc:sqlserver://vet-to-go.database.windows.net:1433;database=Vet To Go DB;user=myLogin@vet-to-go;password=myPass;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";
String queryString = "SELECT FirstName, LastName FROM Tbl_Customer WHERE CustomerID = " + custID;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection myConnection = DriverManager.getConnection(connectionString);
Statement myStatement = myConnection.createStatement();
ResultSet myResultSet = myStatement.executeQuery(queryString);
myResultSet.next();
String firstName = myResultSet.getString("FirstName");
String lastName = myResultSet.getString("LastName");
System.out.println(firstName);
System.out.println(lastName);
myStatement.close();
myConnection.close();
}
}
我知道有些代码看起来很奇怪,只是因为我希望将它合并到另一个类中。这是我最近这样做的尝试(正如我所提到的,我已经有一段时间了,所以我尝试了几种不同的组合)
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import java.sql.*;
public class LandingPage extends AppCompatActivity {
TextView txtFirst, txtLast;
String firstName, lastName, customerID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_landing_page);
txtFirst = (TextView)findViewById(R.id.txtFirstName);
txtLast = (TextView)findViewById(R.id.txtLastName);
customerID = getIntent().getStringExtra("custID");
new myAsyncTask(LandingPage.this).execute();
txtFirst.setText(firstName);
txtLast.setText(lastName);
}
public class myAsyncTask extends AsyncTask<Void, Void, String> {
String connectionString = "jdbc:sqlserver://vet-to-go.database.windows.net:1433;database=Vet To Go DB;user=myLogin@vet-to-go;password=myPass;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";
String queryString = "SELECT FirstName, LastName FROM Tbl_Customer WHERE CustomerID = " + customerID;
Context context;
public myAsyncTask(Context context) {
System.out.println("Async instantiated.");
this.context = context;
}
protected void onPreExecute() {
System.out.println("Pre-executing Async task.");
}
protected String doInBackground(Void... params) {
try {
System.out.println("Attempting to connect to DB...");
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection(connectionString);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(queryString);
while (rs.next()) {
System.out.println("Sorting through ResultSet...");
firstName = rs.getString("FirstName");
lastName = rs.getString("LastName");
}
} catch (SQLException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return "Complete";
}
protected void onPostExecute(String result) {
if (result.equals("Complete")) {
System.out.println("Async task complete.");
}
}
}
}
运行上面的代码后,我得到了与主机vet-to-go.database.windows.net的TCP / IP连接,端口1433失败了。&#34;这一行的错误:
Connection con = DriverManager.getConnection(connectionString);
我不认为这是相关的,但为了以防万一,这里有 MainActivity 中的所有内容:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etID = (EditText)findViewById(R.id.etCustID);
btnSubmit = (Button)findViewById(R.id.btnSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
customerID = etID.getText().toString();
myIntent = new Intent(MainActivity.this, LandingPage.class);
myIntent.putExtra("custID", customerID);
startActivity(myIntent);
}
});
}
Android Studio 2.3
Build#AI-162.3764568,建于2017年2月24日
JRE:1.8.0_112-release-b06 amd64
JVM:JetBrains s.r.o的OpenJDK 64位服务器VM
Gradle版本3.3
目标API 22:Android 5.1
Min Sdk V 21
构建工具v 25.0.0
答案 0 :(得分:0)
首先,在Android上直接连接Azure SQL数据库并不是一个好主意。通常,推荐的方法是通过调用一些REST API来访问数据库,这些REST API在Azure上创建为Web App或Mobile App。
其次,许多现有的SO线程与您的问题类似,解决方案是在Android上使用jTDS
驱动程序而不是MS SQL Server驱动程序sqljdbc
进行连接,因为sqljdbc
Android上似乎没有完全支持驱动程序。作为参考,请参阅以下解决的这些主题。