最近在研究Android,需要用Android连sql,查各种资料终于成了,写上来以后忘了还可以回来查
首先是数据库和c#部分,我的环境是win7旗舰版 + sql 2008 + VS2010。
数据库要确保使用sql验证sa或其他账户可用,最好不要用windows验证,不然IIS会比较麻烦。
数据库部分,建立数据库不细说了,我用的是课设的数据库,图书管理系统->书籍表,一共7个字段,分别是图书编号,书名,作者,出版社,出版日期版次和库存。这里不用考虑字段数据类型,反正最后传到手机里都是Object。
c#部分,新建一个ASP.NET Web服务应用程序,注意.NET版本一定是3.5,4.0没有Web服务应用我也不知道为啥=.=
新建一个DataBase类,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
namespace AndroidService
{
public class DataBase
{
private SqlConnection sqlConnection;
private SqlCommand sqlCommand;
private SqlDataReader sqlDataReader;
private string connectionString = @"Data Source=GREENSHADOW-PC\SQLEXPRESS;Initial Catalog=Library;User ID=sa;Password=123456";
private string sql = null;
public DataBase()
{
if (sqlConnection == null)
{
sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();
}
}
public void Dispose()
{
if (sqlConnection != null)
{
sqlConnection.Close();
sqlConnection.Dispose();
}
}
/// <returns>所有货物信息</returns>
public List<string> AllInfo()
{
List<string> list = new List<string>();
sql = "select * from 书籍表";
try
{
sqlCommand = new SqlCommand(sql, sqlConnection);
sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
list.Add(sqlDataReader[0].ToString().Trim());
list.Add(sqlDataReader[1].ToString().Trim());
list.Add(sqlDataReader[2].ToString().Trim());
list.Add(sqlDataReader[3].ToString().Trim());
list.Add(sqlDataReader[4].ToString().Trim());
list.Add(sqlDataReader[5].ToString().Trim());
list.Add(sqlDataReader[6].ToString().Trim());
}
sqlDataReader.Close();
sqlCommand.Dispose();
}
catch (Exception)
{
return null;
}
return list;
}
}
}
注意连接字符串,要用sql验证方式。
然后修改Service.asmx:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
namespace AndroidService
{
/// <summary>
/// Service 的摘要说明
/// </summary>
[WebService(Namespace = "http://GreenShadow.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService
{
DataBase DB = new DataBase();
[WebMethod(Description = "返回所有值")]
public List<string> AllInfo()
{
return DB.AllInfo();
}
}
}
建议把 [WebService(Namespace = "http://GreenShadow.com/")]里的命名空间改一下
注意要加上这句
[SoapDocumentService(RoutingStyle = SoapServiceRoutingStyle.RequestElement)]
不然java会提示服务器未能识别 HTTP 标头 SOAPAction 的值。
说明一下,我这是第一次做webservice,以前用c#都是做WinForm的,所以对web部分知之甚少,我把Service1.asmx改名成Service.asmx后各种运行出错
原来是要在VS外面打开Service.asmx,然后把
<%@ WebService Language="C#" CodeBehind="Service1.asmx.cs" Class="AndroidService.Service1" %>
改成
<%@ WebService Language="C#" CodeBehind="Service.asmx.cs" Class="AndroidService.Service" %>
F5运行,会打开浏览器看到这个画面
点击测试一下:
好了没问题~接下来要把这个webservice在IIS发布一下。IIS具体配置百度一下吧。
打开 控制面板->管理工具->Internet 信息服务(IIS)管理器,左边的网站击右键选择添加网站,然后随便起个名字,把物理路径设置为刚才c#的工程路径,IP地址选择当前电脑的IPv4地址,如图:
不放心的话去cmd里看下ipconfig,端口最好改一个,不改也行。然后启动网站,点右边的浏览网站:
你会看到一个文件选择界面,选择刚才的Service.asmx:
然后就又看到刚才写的服务了!好了webservices大功告成,接下来是Android部分。
Android部分,需要用到ksoap2的包 下载地址 https://code.google.com/p/ksoap2-android/
我下载的最新版是ksoap2-android-assembly-3.3.0-jar-with-dependencies.jar PS.要翻墙
复制到工程目录下的libs文件夹下,然后点右键,选Build Path->Add to Build Path。
activity_main:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.greenshadow.database.MainActivity" >
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
这里的TextView1是用来显示正常的信息的, TextView2是用来显示异常信息的。
MainActivity:
package com.greenshadow.database;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import com.greenshadow.news.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.widget.TextView;
public class MainActivity extends Activity {
TextView textView1, textView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
textView1 = (TextView) findViewById(R.id.tv1);
textView2 = (TextView) findViewById(R.id.tv2);
getRemoteInfo();
}
public void getRemoteInfo() {
String nameSpace = "http://GreenShadow.com/";
String methodName = "AllInfo";
String endPoint = "http://192.168.253.194:8080/Service.asmx";
<span style="white-space:pre"> </span>//我不太理解soapAction的意思,我也是瞎猫碰死耗子地这么写就成功了,还望各路大大指教
String soapAction = "http://GreenShadow.com/Service";
SoapObject rpc = new SoapObject(nameSpace, methodName);
final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER10);
envelope.bodyOut = rpc;
envelope.dotNet = true;
envelope.setOutputSoapObject(rpc);
final HttpTransportSE transport = new HttpTransportSE(endPoint);
transport.debug = true;
try {
transport.call(soapAction, envelope);
} catch (Exception e) {
textView2.setText(e.toString());
return;
}
try {
SoapObject object = (SoapObject) envelope.getResponse();
int count = object.getPropertyCount();
textView1.setText("");
for (int i = 0; i < count; i++)
textView1.append(object.getProperty(i).toString() + "\n");
} catch (Exception e) {
textView2.setText(e.toString());
return;
}
}
}
说来惭愧,这里有两行:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
是用来强制让手机在主线程使用网络连接的...比较暴力...线程异步我还不会...还望大神指教...
在AndroidManifest里添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
至此,大功告成!最后来个运行截图: