在Android Studio

时间:2017-04-04 06:28:40

标签: java sql-server azure android-studio jdbc

因此,我已经开始/关闭了几天,并感觉好像我已经用尽任何相关的搜索条件。首先我要说的是,我已经对此进行了很多的研究,但无济于事;我得出的结论是,这可能是非常不正常的事情(不太可能),或者是我忽略了一些细微的细节。让我也说明了,是的,我知道直接从应用程序连接到数据库并不理想,我应该使用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

1 个答案:

答案 0 :(得分:0)

首先,在Android上直接连接Azure SQL数据库并不是一个好主意。通常,推荐的方法是通过调用一些REST API来访问数据库,这些REST API在Azure上创建为Web App或Mobile App。

其次,许多现有的SO线程与您的问题类似,解决方案是在Android上使用jTDS驱动程序而不是MS SQL Server驱动程序sqljdbc进行连接,因为sqljdbc Android上似乎没有完全支持驱动程序。作为参考,请参阅以下解决的这些主题。

  1. https://social.msdn.microsoft.com/forums/sqlserver/en-US/4799819a-27fd-4292-a3d8-f114207c20b2/using-the-jdbc-driver-with-android
  2. Sql Database connect Using the JDBC Driver with android
  3. how to connect sql server using JTDS driver in Android
  4. 希望它有所帮助。