因此,我一直在爲此打開/關閉幾天,感覺好像我已經用盡了任何相關搜索條件。首先讓我說說我已經做了一個很多的研究到這無濟於事;我得出的結論是,它要麼是非常不正常的(不太可能),要麼是我忽略了的一些微小細節。讓我也直接說蝙蝠,是的,我知道直接從應用程序連接到數據庫是不理想的,我應該使用Web服務器,但爲了我的意圖和目的,這個解決方案不是一個問題。在Android Studio中,與Azure的JDBC連接失敗
我知道這篇文章超長,但我非常感謝大家的時間。如果沒有別的,至少它可能會幫助最近開始使用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-許可的android:NAME = 「android.permission.INTERNET對」
-Azure防火牆配置爲允許我的IP連接。
-Windows防火牆有規則的地方,允許傳入&傳出流量在端口1433上
- 從SQLServer的配置管理器,我已經啓用命名管道& TCP/IP。在「IP地址」選項卡上,我已啓用全部並將TCP端口設置爲1433.已嘗試使用&關閉TCP動態端口。
- 已嘗試使用SQL Server Browser運行&已停止(另一篇文章中提到這麼做)。
- 曾嘗試使用jre7 & jre8 JDBC驅動程序。
-sourceCompatibility & targetCompatibility在相應的1_7或1_8版本中設置。
-compile文件(「庫/ sqljdbc41.jar」)或42 jre8]
- 更拼命,並確保他們沒有問題,我也沒打開Windows防火牆後連接完全關閉,並且允許任何IP經由天青防火牆(爲0.0.0.0開始/結束IP - 255.255.255.255)連接
-I 可以平&遠程登錄到(mydbname).database.windows。網絡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;[email protected];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;[email protected];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,端口1433的TCP/IP連接失敗。「錯誤在這行:
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
內部編號AI-162.3764568,始建於2017年2月24日
JRE:1.8.0_112-釋放-B06 AMD64
JVM:OpenJDK的64位服務器VM通過JetBrains的SRO
搖籃3.3版
目標API 22:Android的5.1
敏SDK 21節
構建工具v 25.0.0
是的,我在帖子中提到,我知道直接連接並不是最佳實踐,但對於這種特定情況,這並不重要。我也已經構建了一個C#桌面應用程序,並使用直接連接,所以我想保持一致。我遇到了一些使用jTDS的建議,但認爲我只是在做一些錯誤的事情,所以我想堅持使用官方的MS。但是,如果事實證明,我確實沒有什麼可以做的不同,我很可能不得不走這條路。謝謝! – Nick