1、基于socket的用法
服务器端:
先启动一个服务器端的socket ServerSocket svr = new ServerSocket(8989);
开始侦听请求 Socket s = svr.accept();
取得输入和输出 DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
Socket 的交互通过流来完成,即是说传送的字节流,因此任何文件都可以在上面传送。谁打开的记得要关上。
用DataInputStream/DataOutputStream来进行包装是因为我们想要他们对基本数据类型的读写功能readInt(),writeInt(),readUTF(),writeUTF()等等。
客户端:
发起一个socket连接 Socket s = new Socket("192.168.1.200",8989);
取得输入和输出 DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
之后就可以相互通信了。谁打开的记得要关上。
2、基于Http协议
一般是发送请求到某个应用服务器。此时需要用到HttpURLConnection
先取得HttpURLConnection urlConn = new URL("http://www.google.com").openConnection();
设置标志
urlConn.setDoOutput(true); urlConn.setDoInput(true);//post的情况下需要设置DoOutput为true
urlConn.setRequestMethod("POST");
urlConn.setUseCache(false);//设置是否用缓存
urlConn.setRequestProperty("Content-type","application/x-www-form-urlencoded");//设置content-type
获得输出流,便于想服务器发送信息。
DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());
望流里面写请求参数
dos.writeBytes("name="+URLEncoder.encode("chenmouren","gb2312");
dos.flush();dos.close();//发送完后马上关闭。
获得输入流,取数据
BufferReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
reader.readLine();//用 !=null来判断是否结束
reader.close();
读完了记得关闭connection urlConn.disconnect();
流程记录就到此为止。
3、HttpURLConnection接口
首先需要明确的是,Http通信中的POST和GET请求方式的不同。GET可以获得静态页面,也可以把参数放在URL字符串后面,传递给服务器。而POST方法的参数是放在Http请求中。因此,在编程之前,应当首先明确使用的请求方法,然后再根据所使用的方式选择相应的编程方式。
HttpURLConnection是继承于URLConnection类,二者都是抽象类。其对象主要通过URL的openConnection方法获得。创建方法如下代码所示:
|
通过以下方法可以对请求的属性进行一些设置,如下所示:
|
HttpURLConnection默认使用GET方式,例如下面代码所示:
|
如果需要使用POST方式,则需要setRequestMethod设置。代码如下:
|
4、使用Apache提供的HttpClient接口同样可以进行HTTP操作。
对于GET和POST请求方法的操作有所不同。GET方法的操作代码示例如下:
[java] view plaincopy
- // http地址
- String httpUrl = "http://192.168.1.110:8080/httpget.jsp?par=HttpClient_android_Get";
- //HttpGet连接对象
- HttpGet httpRequest = new HttpGet(httpUrl);
- //取得HttpClient对象
- HttpClient httpclient = new DefaultHttpClient();
- //请求HttpClient,取得HttpResponse
- HttpResponse httpResponse = httpclient.execute(httpRequest);
- //请求成功
- if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
- {
- //取得返回的字符串
- String strResult = EntityUtils.toString(httpResponse.getEntity());
- mTextView.setText(strResult);
- }
- else
- {
- mTextView.setText("请求错误!");
- }
- }
使用POST方法进行参数传递时,需要使用NameValuePair来保存要传递的参数。,另外,还需要设置所使用的字符集。代码如下所示:
[java] view plaincopy
- // http地址
- String httpUrl = "http://192.168.1.110:8080/httpget.jsp";
- //HttpPost连接对象
- HttpPost httpRequest = new HttpPost(httpUrl);
- //使用NameValuePair来保存要传递的Post参数
- List<NameValuePair> params = new ArrayList<NameValuePair>();
- //添加要传递的参数
- params.add(new BasicNameValuePair("par", "HttpClient_android_Post"));
- //设置字符集
- HttpEntity httpentity = new UrlEncodedFormEntity(params, "gb2312");
- //请求httpRequest
- httpRequest.setEntity(httpentity);
- //取得默认的HttpClient
- HttpClient httpclient = new DefaultHttpClient();
- //取得HttpResponse
- HttpResponse httpResponse = httpclient.execute(httpRequest);
- //HttpStatus.SC_OK表示连接成功
- if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
- {
- //取得返回的字符串
- String strResult = EntityUtils.toString(httpResponse.getEntity());
- mTextView.setText(strResult);
- }
- else
- {
- mTextView.setText("请求错误!");
- }
- }
HttpClient实际上是对Java提供方法的一些封装,在HttpURLConnection中的输入输出流操作,在这个接口中被统一封装成了HttpPost(HttpGet)和HttpResponse,这样,就减少了操作的繁琐性。
另外,在使用POST方式进行传输时,需要进行字符编码。
5、
- package com.study.ws;
- import java.io.IOException;
- import org.ksoap2.SoapEnvelope;
- import org.ksoap2.SoapFault;
- import org.ksoap2.serialization.SoapObject;
- import org.ksoap2.serialization.SoapSerializationEnvelope;
- import org.ksoap2.transport.AndroidHttpTransport;
- import org.ksoap2.transport.HttpTransportSE;
- import org.xmlpull.v1.XmlPullParserException;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.webkit.WebSettings;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- public class WSClient extends Activity {
- private Button search;
- private EditText phone;
- private TextView result;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- search=(Button)findViewById(R.id.search);
- phone=(EditText)findViewById(R.id.phone);
- result=(TextView)findViewById(R.id.result);
- search.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String strPhone=phone.getText().toString().trim();
- if(!(strPhone.length()==0||strPhone.equals("")))
- {
- String str = "";
- try {
- str = getPhoneInfo(strPhone);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (XmlPullParserException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- result.setText(str);
- }
- }
- });
- }
- public String getPhoneInfo(String phoneName) throws IOException, XmlPullParserException
- {
- //返回的查询结果
- String result = null;
- //调用webservice接口的名称空间
- String nameSpace="http://WebXml.com.cn/";
- //调用的方法名
- String methodName="getMobileCodeInfo";
- //将方法名和名称空间绑定在一起
- String SOAP_ACTION = nameSpace + methodName;
- //获得返回请求对象
- SoapObject request = new SoapObject(nameSpace, methodName);
- //设置需要返回请求对象的参数
- request.addProperty("mobileCode", phoneName);
- request.addProperty("userId", "");
- //设置soap的版本
- SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
- SoapEnvelope.VER11);
- //设置是否调用的是dotNet开发的
- envelope.dotNet = true;
- //
- envelope.bodyOut = request;
- AndroidHttpTransport hts = new AndroidHttpTransport
- ("http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx");
- // web service请求
- hts.call(SOAP_ACTION, envelope);
- // 得到返回结果
- Object o = envelope.getResponse();
- result = o.toString();
- return result;
- }
- }
6、一、获取并使用KSOAP包
在Android SDK中并没有提供调用WebService的库,因此,需要使用第三方的SDK来调用WebService。PC版本的WebService库非常丰富,但这些对Android来说过于庞大。适合手机的WebService客户端的SDK有一些,比较常用的是KSOAP2。
KSOAP2 地址:http://code.google.com/p/ksoap2-android/
我下载的最新的是: ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar
注意:
我在使用ksoap2-android时犯了一个低级错误:使用时报错误:The import org.ksoap2 cannot be resolved。
当时分析这个问题时一直以为是Eclipse出了问题,找了好多方法都不行,
实际是我下载的ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar文件是错误的导致的,走了弯路。
在 http://code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2 页面 通过鼠标右键链接另存为存的是同名的一个纯文本的Html文件。而不是我们想要的。
我是在
http://code.google.com/p/ksoap2-android/source/browse/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/2.5.4/ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar 点 View raw file 才正确下载对应文件的。
选择我们的项目,右键菜单中 Build Path –> Add External Archives… 增加这个下载的包
增加好后,我们在 选择我们的项目,右键菜单中 Build Path –> Configure Build Path 的 Libraries 中可以看到下面图:
二,分以下几步来调用 WebService
1、指定 WebService 的命名空间和调用方法
import org.ksoap2.serialization.SoapObject;private static final String NAMESPACE = "http://WebXml.com.cn/";private static final String METHOD_NAME = "getWeatherbyCityName"; SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
SoapObject类的第一个参数表示WebService的命名空间,可以从WSDL文档中找到WebService的命名空间。
第二个参数表示要调用的WebService方法名。
2、设置调用方法的参数值,如果没有参数,可以省略,设置方法的参数值的代码如下:
rpc.addProperty("theCityName", "北京");
要注意的是,addProperty方法的第1个参数虽然表示调用方法的参数名,但该参数值并不一定与服务端的WebService类中的方法参数名一致,只要设置参数的顺序一致即可。
3、生成调用Webservice方法的SOAP请求信息。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = rpc;envelope.dotNet = true;envelope.setOutputSoapObject(rpc);
创建SoapSerializationEnvelope对象时需要通过SoapSerializationEnvelope类的构造方法设置SOAP协议的版本号。
该版本号需要根据服务端WebService的版本号设置。
在创建SoapSerializationEnvelope对象后,不要忘了设置SOAPSoapSerializationEnvelope类的bodyOut属性,
该属性的值就是在第一步创建的SoapObject对象。
4、创建HttpTransportsSE对象。
这里不要使用 AndroidHttpTransport ht = new AndroidHttpTransport(URL); 这是一个要过期的类
private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx";HttpTransportSE ht = new HttpTransportSE(URL);
ht.debug = true;
5、使用call方法调用WebService方法
private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName";ht.call(SOAP_ACTION, envelope);
网上有人说这里的call的第一个参数为null,但是经过我的测试,null是不行的。
第2个参数就是在第3步创建的SoapSerializationEnvelope对象。
6、获得WebService方法的返回结果
有两种方法:
1、使用getResponse方法获得返回数据。
private SoapObject detail;detail =(SoapObject) envelope.getResponse();
2、使用 bodyIn 及 getProperty。
private SoapObject detail;SoapObject result = (SoapObject)envelope.bodyIn;detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult");
7、 这时候执行会出错,提示没有权限访问网络
需要修改 AndroidManifest.xml 文件,赋予相应权限
简单来说就是增加下面这行配置:<uses-permission android:name="android.permission.INTERNET"></uses-permission>
完整的 AndroidManifest.xml 文件 如下:
注:Android 中在代码中为了调试写了system.out.print()输出项
在菜单:Window-->show view-->other-->找到Android,选择Logcat 是可以看到输出的,
如果你想在一个单独的窗口看到system.out.print()的输出的话,可以在logcat界面点那个绿色的“+”好,
在Filter name 和 By log tag里面均填入System.out,这样的话你就能在单独的界面查看system.out.print()的输出了!!
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ghj1976.MyWeather" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MyWeatherActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest>
完整的代码如下:
package ghj1976.MyWeather;import java.io.UnsupportedEncodingException;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;import org.ksoap2.SoapEnvelope;import org.ksoap2.serialization.SoapObject;import org.ksoap2.serialization.SoapSerializationEnvelope;//import org.ksoap2.transport.AndroidHttpTransport;import org.ksoap2.transport.HttpTransportSE;public class MyWeatherActivity extends Activity { private Button okButton; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); okButton = (Button) this.findViewById(R.id.btn_Search); okButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { String city = "北京"; getWeather(city); } }); } private static final String NAMESPACE = "http://WebXml.com.cn/"; // WebService地址 private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx"; private static final String METHOD_NAME = "getWeatherbyCityName"; private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName"; private String weatherToday; private SoapObject detail; public void getWeather(String cityName) { try { System.out.println("rpc------"); SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME); System.out.println("rpc" + rpc); System.out.println("cityName is " + cityName); rpc.addProperty("theCityName", cityName); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.bodyOut = rpc; envelope.dotNet = true; envelope.setOutputSoapObject(rpc); HttpTransportSE ht = new HttpTransportSE(URL); //AndroidHttpTransport ht = new AndroidHttpTransport(URL); ht.debug = true; ht.call(SOAP_ACTION, envelope); //ht.call(null, envelope); //SoapObject result = (SoapObject)envelope.bodyIn; //detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult"); detail =(SoapObject) envelope.getResponse(); //System.out.println("result" + result); System.out.println("detail" + detail); Toast.makeText(this, detail.toString(), Toast.LENGTH_LONG).show(); parseWeather(detail); return; } catch (Exception e) { e.printStackTrace(); } } private void parseWeather(SoapObject detail) throws UnsupportedEncodingException { String date = detail.getProperty(6).toString(); weatherToday = "今天:" + date.split(" ")[0]; weatherToday = weatherToday + "\n天气:" + date.split(" ")[1]; weatherToday = weatherToday + "\n气温:" + detail.getProperty(5).toString(); weatherToday = weatherToday + "\n风力:" + detail.getProperty(7).toString() + "\n"; System.out.println("weatherToday is " + weatherToday); Toast.makeText(this, weatherToday, Toast.LENGTH_LONG).show(); }}
参考资料
在Android中访问WebService接口
http://www.cnblogs.com/yy-7years/archive/2011/01/24/1943286.html
Android调用WebService
http://express.ruanko.com/ruanko-express_34/technologyexchange5.html
中国气象局的WebService地址
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
Android与服务器端数据交互(基于SOAP协议整合android+webservice)
http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html
版权声明:本文为博主原创文章,未经博主允许不得转载。
7、[java] view plaincopy
- 在android程序中运行第一步就是检测当前有无可用网络
- 如果没有网络可用就退出程序
- if (isConnect(this)==false)
- {
- new AlertDialog.Builder(this)
- .setTitle("网络错误")
- .setMessage("网络连接失败,请确认网络连接")
- .setPositiveButton("确定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface arg0, int arg1) {
- // TODO Auto-generated method stub
- android.os.Process.killProcess(android.os.Process.myPid());
- System.exit(0);
- }
- }).show();
- }
- public static boolean isConnect(Context context) {
- // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
- try {
- ConnectivityManager connectivity = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- if (connectivity != null) {
- // 获取网络连接管理的对象
- NetworkInfo info = connectivity.getActiveNetworkInfo();
- if (info != null&& info.isConnected()) {
- // 判断当前网络是否已经连接
- if (info.getState() == NetworkInfo.State.CONNECTED) {
- return true;
- }
- }
- }
- } catch (Exception e) {
- // TODO: handle exception
- Log.v("error",e.toString());
- }
- return false;
- }
- 最后一点还得再manifest中添加权限
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
8、[java] view plaincopy
- public class MainActivity extends Activity
- {
- private static final String TAG = "MainActivity";
- private EditText timelengthText;
- private EditText titleText;
- private EditText videoText;
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //提交上传按钮
- Button button = (Button) this.findViewById(R.id.button);
- timelengthText = (EditText) this.findViewById(R.id.timelength);
- videoText = (EditText) this.findViewById(R.id.video);
- titleText = (EditText) this.findViewById(R.id.title);
- button.setOnClickListener(new View.OnClickListener()
- {
- @Override
- public void onClick(View v)
- {
- String title = titleText.getText().toString();
- String timelength = timelengthText.getText().toString();
- Map<String, String> params = new HashMap<String, String>();
- params.put("method", "save");
- params.put("title", title);
- params.put("timelength", timelength);
- try
- {
- //得到SDCard的目录
- File uploadFile = new File(Environment.getExternalStorageDirectory(), videoText.getText().toString());
- //上传音频文件
- FormFile formfile = new FormFile("02.mp3", uploadFile, "video", "audio/mpeg");
- SocketHttpRequester.post("http://192.168.1.100:8080/videoweb/video/manage.do", params, formfile);
- Toast.makeText(MainActivity.this, R.string.success, 1).show();
- }
- catch (Exception e)
- {
- Toast.makeText(MainActivity.this, R.string.error, 1).show();
- Log.e(TAG, e.toString());
- }
- }
- });
- }
- }
[java] view plaincopy
- .上传工具类,注意里面构造协议字符串需要根据不同的提交表单来处理
- public class SocketHttpRequester
- {
- /**
- * 发送xml数据
- * @param path 请求地址
- * @param xml xml数据
- * @param encoding 编码
- * @return
- * @throws Exception
- */
- public static byte[] postXml(String path, String xml, String encoding) throws Exception{
- byte[] data = xml.getBytes(encoding);
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod("POST");
- conn.setDoOutput(true);
- conn.setRequestProperty("Content-Type", "text/xml; charset="+ encoding);
- conn.setRequestProperty("Content-Length", String.valueOf(data.length));
- conn.setConnectTimeout(5 * 1000);
- OutputStream outStream = conn.getOutputStream();
- outStream.write(data);
- outStream.flush();
- outStream.close();
- if(conn.getResponseCode()==200){
- return readStream(conn.getInputStream());
- }
- return null;
- }
- /**
- * 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:
- * <FORM METHOD=POST ACTION="http://192.168.0.200:8080/ssi/fileload/test.do" enctype="multipart/form-data">
- <INPUT TYPE="text" NAME="name">
- <INPUT TYPE="text" NAME="id">
- <input type="file" name="imagefile"/>
- <input type="file" name="zip"/>
- </FORM>
- * @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,
- * 因为它会指向手机模拟器,你可以使用http://www.baidu.com或http://192.168.1.10:8080这样的路径测试)
- * @param params 请求参数 key为参数名,value为参数值
- * @param file 上传文件
- */
- public static boolean post(String path, Map<String, String> params, FormFile[] files) throws Exception
- {
- //数据分隔线
- final String BOUNDARY = "---------------------------7da2137580612";
- //数据结束标志"---------------------------7da2137580612--"
- final String endline = "--" + BOUNDARY + "--/r/n";
- //下面两个for循环都是为了得到数据长度参数,依据表单的类型而定
- //首先得到文件类型数据的总长度(包括文件分割线)
- int fileDataLength = 0;
- for(FormFile uploadFile : files)
- {
- StringBuilder fileExplain = new StringBuilder();
- fileExplain.append("--");
- fileExplain.append(BOUNDARY);
- fileExplain.append("/r/n");
- fileExplain.append("Content-Disposition: form-data;name=/""+ uploadFile.getParameterName()+"/";filename=/""+ uploadFile.getFilname() + "/"/r/n");
- fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"/r/n/r/n");
- fileExplain.append("/r/n");
- fileDataLength += fileExplain.length();
- if(uploadFile.getInStream()!=null){
- fileDataLength += uploadFile.getFile().length();
- }else{
- fileDataLength += uploadFile.getData().length;
- }
- }
- //再构造文本类型参数的实体数据
- StringBuilder textEntity = new StringBuilder();
- for (Map.Entry<String, String> entry : params.entrySet())
- {
- textEntity.append("--");
- textEntity.append(BOUNDARY);
- textEntity.append("/r/n");
- textEntity.append("Content-Disposition: form-data; name=/""+ entry.getKey() + "/"/r/n/r/n");
- textEntity.append(entry.getValue());
- textEntity.append("/r/n");
- }
- //计算传输给服务器的实体数据总长度(文本总长度+数据总长度+分隔符)
- int dataLength = textEntity.toString().getBytes().length + fileDataLength + endline.getBytes().length;
- URL url = new URL(path);
- //默认端口号其实可以不写
- int port = url.getPort()==-1 ? 80 : url.getPort();
- //建立一个Socket链接
- Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);
- //获得一个输出流(从Android流到web)
- OutputStream outStream = socket.getOutputStream();
- //下面完成HTTP请求头的发送
- String requestmethod = "POST "+ url.getPath()+" HTTP/1.1/r/n";
- outStream.write(requestmethod.getBytes());
- //构建accept
- String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*/r/n";
- outStream.write(accept.getBytes());
- //构建language
- String language = "Accept-Language: zh-CN/r/n";
- outStream.write(language.getBytes());
- //构建contenttype
- String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "/r/n";
- outStream.write(contenttype.getBytes());
- //构建contentlength
- String contentlength = "Content-Length: "+ dataLength + "/r/n";
- outStream.write(contentlength.getBytes());
- //构建alive
- String alive = "Connection: Keep-Alive/r/n";
- outStream.write(alive.getBytes());
- //构建host
- String host = "Host: "+ url.getHost() +":"+ port +"/r/n";
- outStream.write(host.getBytes());
- //写完HTTP请求头后根据HTTP协议再写一个回车换行
- outStream.write("/r/n".getBytes());
- //把所有文本类型的实体数据发送出来
- outStream.write(textEntity.toString().getBytes());
- //把所有文件类型的实体数据发送出来
- for(FormFile uploadFile : files)
- {
- StringBuilder fileEntity = new StringBuilder();
- fileEntity.append("--");
- fileEntity.append(BOUNDARY);
- fileEntity.append("/r/n");
- fileEntity.append("Content-Disposition: form-data;name=/""+ uploadFile.getParameterName()+"/";filename=/""+ uploadFile.getFilname() + "/"/r/n");
- fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"/r/n/r/n");
- outStream.write(fileEntity.toString().getBytes());
- //边读边写
- if(uploadFile.getInStream()!=null)
- {
- byte[] buffer = new byte[1024];
- int len = 0;
- while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1)
- {
- outStream.write(buffer, 0, len);
- }
- uploadFile.getInStream().close();
- }
- else
- {
- outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
- }
- outStream.write("/r/n".getBytes());
- }
- //下面发送数据结束标志,表示数据已经结束
- outStream.write(endline.getBytes());
- BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- //读取web服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败
- if(reader.readLine().indexOf("200")==-1)
- {
- return false;
- }
- outStream.flush();
- outStream.close();
- reader.close();
- socket.close();
- return true;
- }
- /**
- * 提交数据到服务器
- * @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.baidu.com或http://192.168.1.10:8080这样的路径测试)
- * @param params 请求参数 key为参数名,value为参数值
- * @param file 上传文件
- */
- public static boolean post(String path, Map<String, String> params, FormFile file) throws Exception
- {
- return post(path, params, new FormFile[]{file});
- }
- /**
- * 提交数据到服务器
- * @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.baidu.com或http://192.168.1.10:8080这样的路径测试)
- * @param params 请求参数 key为参数名,value为参数值
- * @param encode 编码
- */
- public static byte[] postFromHttpClient(String path, Map<String, String> params, String encode) throws Exception
- {
- //用于存放请求参数
- List<NameValuePair> formparams = new ArrayList<NameValuePair>();
- for(Map.Entry<String, String> entry : params.entrySet())
- {
- formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
- }
- UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, encode);
- HttpPost httppost = new HttpPost(path);
- httppost.setEntity(entity);
- //看作是浏览器
- HttpClient httpclient = new DefaultHttpClient();
- //发送post请求
- HttpResponse response = httpclient.execute(httppost);
- return readStream(response.getEntity().getContent());
- }
- /**
- * 发送请求
- * @param path 请求路径
- * @param params 请求参数 key为参数名称 value为参数值
- * @param encode 请求参数的编码
- */
- public static byte[] post(String path, Map<String, String> params, String encode) throws Exception
- {
- //String params = "method=save&name="+ URLEncoder.encode("老毕", "UTF-8")+ "&age=28&";//需要发送的参数
- StringBuilder parambuilder = new StringBuilder("");
- if(params!=null && !params.isEmpty())
- {
- for(Map.Entry<String, String> entry : params.entrySet())
- {
- parambuilder.append(entry.getKey()).append("=")
- .append(URLEncoder.encode(entry.getValue(), encode)).append("&");
- }
- parambuilder.deleteCharAt(parambuilder.length()-1);
- }
- byte[] data = parambuilder.toString().getBytes();
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- //设置允许对外发送请求参数
- conn.setDoOutput(true);
- //设置不进行缓存
- conn.setUseCaches(false);
- conn.setConnectTimeout(5 * 1000);
- conn.setRequestMethod("POST");
- //下面设置http请求头
- conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
- conn.setRequestProperty("Accept-Language", "zh-CN");
- conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
- conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- conn.setRequestProperty("Content-Length", String.valueOf(data.length));
- conn.setRequestProperty("Connection", "Keep-Alive");
- //发送参数
- DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
- outStream.write(data);//把参数发送出去
- outStream.flush();
- outStream.close();
- if(conn.getResponseCode()==200)
- {
- return readStream(conn.getInputStream());
- }
- return null;
- }
- /**
- * 读取流
- * @param inStream
- * @return 字节数组
- * @throws Exception
- */
- public static byte[] readStream(InputStream inStream) throws Exception
- {
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = -1;
- while( (len=inStream.read(buffer)) != -1)
- {
- outSteam.write(buffer, 0, len);
- }
- outSteam.close();
- inStream.close();
- return outSteam.toByteArray();
- }
- }
[java] view plaincopy
- public class StreamTool
- {
- /**
- * 从输入流读取数据
- * @param inStream
- * @return
- * @throws Exception
- */
- public static byte[] readInputStream(InputStream inStream) throws Exception{
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while( (len = inStream.read(buffer)) !=-1 ){
- outSteam.write(buffer, 0, len);
- }
- outSteam.close();
- inStream.close();
- return outSteam.toByteArray();
- }
- }
[java] view plaincopy
- /**
- * 使用JavaBean封装上传文件数据
- *
- */
- public class FormFile
- {
- //上传文件的数据
- private byte[] data;
- private InputStream inStream;
- private File file;
- //文件名称
- private String filname;
- //请求参数名称
- private String parameterName;
- //内容类型
- private String contentType = "application/octet-stream";
- /**
- * 上传小文件,把文件数据先读入内存
- * @param filname
- * @param data
- * @param parameterName
- * @param contentType
- */
- public FormFile(String filname, byte[] data, String parameterName, String contentType)
- {
- this.data = data;
- this.filname = filname;
- this.parameterName = parameterName;
- if(contentType!=null) this.contentType = contentType;
- }
- /**
- * 上传大文件,一边读文件数据一边上传
- * @param filname
- * @param file
- * @param parameterName
- * @param contentType
- */
- public FormFile(String filname, File file, String parameterName, String contentType)
- {
- this.filname = filname;
- this.parameterName = parameterName;
- this.file = file;
- try
- {
- this.inStream = new FileInputStream(file);
- }
- catch (FileNotFoundException e)
- {
- e.printStackTrace();
- }
- if(contentType!=null) this.contentType = contentType;
- }
- public File getFile()
- {
- return file;
- }
- public InputStream getInStream()
- {
- return inStream;
- }
- public byte[] getData()
- {
- return data;
- }
- public String getFilname()
- {
- return filname;
- }
- public void setFilname(String filname)
- {
- this.filname = filname;
- }
- public String getParameterName()
- {
- return parameterName;
- }
- public void setParameterName(String parameterName)
- {
- this.parameterName = parameterName;
- }
- public String getContentType()
- {
- return contentType;
- }
- public void setContentType(String contentType)
- {
- this.contentType = contentType;
- }
- }
9、[java] view plaincopy
- 对于Android流量统计来说在2.2版中新加入了TrafficStats类可以轻松获取,其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析。android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为 long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计。
- Java代码
- static long getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi
- static long getMobileRxPackets() //获取Mobile连接收到的数据包总数
- static long getMobileTxBytes() //Mobile发送的总字节数
- static long getMobileTxPackets() //Mobile发送的总数据包数
- static long getTotalRxBytes() //获取总的接受字节数,包含Mobile和WiFi等
- static long getTotalRxPackets() //总的接受数据包数,包含Mobile和WiFi等
- static long getTotalTxBytes() //总的发送字节数,包含Mobile和WiFi等
- static long getTotalTxPackets() //发送的总数据包数,包含Mobile和WiFi等
- static long getUidRxBytes(int uid) //获取某个网络UID的接受字节数
- static long getUidTxBytes(int uid) //获取某个网络UID的发送字节数
- 总接受流量TrafficStats.getTotalRxBytes(),
- 总发送流量TrafficStats.getTotalTxBytes());
- 不包含WIFI的手机GPRS接收量TrafficStats.getMobileRxBytes());
- 不包含Wifi的手机GPRS发送量TrafficStats.getMobileTxBytes());
- 某一个进程的总接收量TrafficStats.getUidRxBytes(Uid));
- 某一个进程的总发送量TrafficStats.getUidTxBytes(Uid));
- 这些都是从第一次启动程序到最后一次启动的统计量。并不是这篇文章里所说的“从本次开机到本次关机的统计量”!
- 用法举例,注意这里得到的单位都是"KB"
- Java代码
- public long getTotalRxBytes(){ //获取总的接受字节数,包含Mobile和WiFi等
- return TrafficStats.getTotalRxBytes()==TrafficStats.UNSUPPORTED?0:(TrafficStats.getTotalRxBytes()/1024);
- }
- public long getTotalTxBytes(){ //总的发送字节数,包含Mobile和WiFi等
- return TrafficStats.getTotalTxBytes()==TrafficStats.UNSUPPORTED?0:(TrafficStats.getTotalTxBytes()/1024);
- }
- public long getMobileRxBytes(){ //获取通过Mobile连接收到的字节总数,不包含WiFi
- return TrafficStats.getMobileRxBytes()==TrafficStats.UNSUPPORTED?0:(TrafficStats.getMobileRxBytes()/1024);
- }
10、Android开发应用程序时,如果应用程序需要访问网络权限,需要在 AndroidManifest.xml 中加入以下代码<uses-permission android:name=”android.permission.INTERNET”></uses-permission>
如果不知道放在哪个位置,那就放在</manifest>前边好了。
同样的如果用到其它的权限,也需要作出声明,部分权限列表如下:
android.permission.ACCESS_CHECKIN_PROPERTIES
允许读写访问”properties”表在 checkin数据库中,改值可以修改上传( Allows read/write access to the “properties” table in the checkin database, to change values that get uploaded)
android.permission.ACCESS_COARSE_LOCATION
允许一个程序访问CellID或WiFi热点来获取粗略的位置(Allows an application to access coarse (e.g., Cell-ID, WiFi) location)
android.permission.ACCESS_FINE_LOCATION
允许一个程序访问精良位置(如GPS) (Allows an application to access fine (e.g., GPS) location)
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
允许应用程序访问额外的位置提供命令(Allows an application to access extra location provider commands)
android.permission.ACCESS_MOCK_LOCATION
允许程序创建模拟位置提供用于测试(Allows an application to create mock location providers for testing)
android.permission.ACCESS_NETWORK_STATE
允许程序访问有关GSM网络信息(Allows applications to access information about networks)
android.permission.ACCESS_SURFACE_FLINGER
允许程序使用SurfaceFlinger底层特性 (Allows an application to use SurfaceFlinger’s low level features)
android.permission.ACCESS_WIFI_STATE
允许程序访问Wi-Fi网络状态信息(Allows applications to access information about Wi-Fi networks)
android.permission.ADD_SYSTEM_SERVICE
允许程序发布系统级服务(Allows an application to publish system-level services).
android.permission.BATTERY_STATS
允许程序更新手机电池统计信息(Allows an application to update the collected battery statistics)
android.permission.BLUETOOTH
允许程序连接到已配对的蓝牙设备(Allows applications to connect to paired bluetooth devices)
11、不说废话,直接说说实现android定位有关的API吧。
这些API都在android.location包下,一共有三个接口和八个类。它们配合使用即可实现定位功能。
三个接口:
GpsStatus.Listener:这是一个当GPS状态发生改变时,用来接收通知的接口。
GpsStatus.NmeaListener:这是一个用来从GPS里接收Nmea-0183(为海用电子设备制定的标准格式)信息的接口。
LocationListener:位置监听器,用于接收当位置信息发生改变时从LocationManager接收通知的接口。
八个类:
Address:描述地址的类,比如:北京*
Criteria:用于描述Location Provider标准的类,标准包括位置精度水平,电量消耗水平,是否获取海拔、方位信息,是否允许接收付费服务。
GeoCoder:用于处理地理位置的编码。
GpsSatellite:和GpsStatus联合使用,用于描述当前GPS卫星的状态。
GpsStatus:和GpsStatus.Listener联合使用,用于描述当前GPS卫星的状态。
Location:用于描述位置信息。
LocationManager:通过此类获取和调用系统位置服务
LocationProvider:用于描述Location Provider的抽象超类,一个LocationProvider应该能够周期性的报告当前设备的位置信息。
这里通过一个示例代码来演示一下android定位。
首先,在AndroidManifest.xml清单文件里需要加入ACCESS_FINE_LOCATION权限:
1 |
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> |
其次,实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
package com.test; import java.io.IOException; import java.util.List; import android.app.Activity; import android.location.Address; import android.location.Criteria; import android.location.Geocoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; import android.widget.Toast; public class PositionActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取到LocationManager对象 LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 创建一个Criteria对象 Criteria criteria = new Criteria(); // 设置粗略精确度 criteria.setAccuracy(Criteria.ACCURACY_COARSE); // 设置是否需要返回海拔信息 criteria.setAltitudeRequired(false); // 设置是否需要返回方位信息 criteria.setBearingRequired(false); // 设置是否允许付费服务 criteria.setCostAllowed(true); // 设置电量消耗等级 criteria.setPowerRequirement(Criteria.POWER_HIGH); // 设置是否需要返回速度信息 criteria.setSpeedRequired(false); // 根据设置的Criteria对象,获取最符合此标准的provider对象 41 String currentProvider = locationManager .getBestProvider(criteria, true); Log.d("Location", "currentProvider: " + currentProvider); // 根据当前provider对象获取最后一次位置信息 44 Location currentLocation = locationManager .getLastKnownLocation(currentProvider); // 如果位置信息为null,则请求更新位置信息 46 if (currentLocation == null) { locationManager.requestLocationUpdates(currentProvider, 0, 0, locationListener); } // 直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度 50 // 每隔10秒获取一次位置信息 51 while (true) { currentLocation = locationManager .getLastKnownLocation(currentProvider); if (currentLocation != null) { Log.d("Location", "Latitude: " + currentLocation.getLatitude()); Log.d("Location", "location: " + currentLocation.getLongitude()); break; } else { Log.d("Location", "Latitude: " + 0); Log.d("Location", "location: " + 0); } try { Thread.sleep(10000); } catch (InterruptedException e) { Log.e("Location", e.getMessage()); } } // 解析地址并显示 69 Geocoder geoCoder = new Geocoder(this); try { int latitude = (int) currentLocation.getLatitude(); int longitude = (int) currentLocation.getLongitude(); List<Address> list = geoCoder.getFromLocation(latitude, longitude, 2); for (int i = 0; i < list.size(); i++) { Address address = list.get(i); Toast.makeText( PositionActivity.this, address.getCountryName() + address.getAdminArea() + address.getFeatureName(), Toast.LENGTH_LONG) .show(); } } catch (IOException e) { Toast.makeText(PositionActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } // 创建位置监听器 85 private LocationListener locationListener = new LocationListener() { // 位置发生改变时调用 87 @Override public void onLocationChanged(Location location) { Log.d("Location", "onLocationChanged"); Log.d("Location", "onLocationChanged Latitude" + location.getLatitude()); Log.d("Location", "onLocationChanged location" + location.getLongitude()); } // provider失效时调用 95 @Override public void onProviderDisabled(String provider) { Log.d("Location", "onProviderDisabled"); } // provider启用时调用101 @Override public void onProviderEnabled(String provider) { Log.d("Location", "onProviderEnabled"); } // 状态改变时调用107 @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Location", "onStatusChanged"); } }; } |
由于代码里的Criteria对象对位置精度要求并不高,所以一般会返回“network”作为provider,而基于network的定位往往会存在一定的位置偏差,这对于需要精确定位的应用程序来说,显然不合要求。这时,需要则需要用到基于GPS的定位方法了
12、在前文Android定位功能(一)中,已经大致介绍了一下在Android平台中,和定位功能相关的类,并举例获取了位置信息。但是前文是基于Criteria定制了一个标准,通过getBestProvider()方法由Android系统自动获取最符合Criteria的LocationProvider,从而实现了定位功能。这样的做法能最大限度的保证定位功能的可实现性,但是却无法保证获取到的位置信息有最大的准确度。因为除了GPS外,其他定位方式都或多或少存在着位置偏移。
在实现GPS定位前,先了解一下GPS的部分特性:
1:GPS定位需要依靠3颗或以上的卫星。
2:GPS定位受环境影响较大,在晴朗的空地上,较容易搜索到卫星,而在室内通常是无法搜索到卫星的。
3:GPS定位需要使用GPS功能模块,而GPS功能模块的耗电量是巨大的。
在Android系统中,实现GPS定位的思路大致是:
1、获取GPS的Location Provider。
2、将此Provider传入到requestLocationUpdates()方法,让Android系统获知搜索位置方式。
3、创建实现了GpsStatus.Listener接口的对象,重写onGpsStatusChanged()方法,向LocationManager添加次监听器,检测卫星状态。(可选步骤)
根据以上思路,仿照Android定位功能(一)中的例子,可以很容易的得到以下实现代码:(此代码的实现前提是GPS功能模块处于打开状态)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
public class MainActivity extends Activity { private LocationManager locationManager; private GpsStatus gpsstatus; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取到LocationManager对象 locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // 根据设置的Criteria对象,获取最符合此标准的provider对象 String currentProvider = locationManager.getProvider( LocationManager.GPS_PROVIDER).getName(); // 根据当前provider对象获取最后一次位置信息 Location currentLocation = locationManager .getLastKnownLocation(currentProvider); // 如果位置信息为null,则请求更新位置信息 if (currentLocation == null) { locationManager.requestLocationUpdates(currentProvider, 0, 0, locationListener); } // 增加GPS状态监听器 locationManager.addGpsStatusListener(gpsListener); // 直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度 // 每隔10秒获取一次位置信息 while (true) { currentLocation = locationManager .getLastKnownLocation(currentProvider); if (currentLocation != null) { Log.d("Location", "Latitude: " + currentLocation.getLatitude()); Log.d("Location", "location: " + currentLocation.getLongitude()); break; } else { Log.d("Location", "Latitude: " + 0); Log.d("Location", "location: " + 0); } try { Thread.sleep(10000); } catch (InterruptedException e) { Log.e("Location", e.getMessage()); } } } private GpsStatus.Listener gpsListener = new GpsStatus.Listener() { // GPS状态发生变化时触发 @Override public void onGpsStatusChanged(int event) { // 获取当前状态 gpsstatus = locationManager.getGpsStatus(null); switch (event) { // 第一次定位时的事件 case GpsStatus.GPS_EVENT_FIRST_FIX: break; // 开始定位的事件 case GpsStatus.GPS_EVENT_STARTED: break; // 发送GPS卫星状态事件 case GpsStatus.GPS_EVENT_SATELLITE_STATUS: Toast.makeText(MainActivity.this,"GPS_EVENT_SATELLITE_STATUS", Toast.LENGTH_SHORT).show(); Iterable<GpsSatellite> allSatellites = gpsstatus .getSatellites(); Iterator<GpsSatellite> it = allSatellites.iterator(); int count = 0; while (it.hasNext()) { count++; } Toast.makeText(MainActivity.this, "Satellite Count:" + count, Toast.LENGTH_SHORT).show(); break; // 停止定位事件 case GpsStatus.GPS_EVENT_STOPPED: Log.d("Location", "GPS_EVENT_STOPPED"); break; } } }; // 创建位置监听器 private LocationListener locationListener = new LocationListener() { // 位置发生改变时调用 @Override public void onLocationChanged(Location location) { Log.d("Location", "onLocationChanged"); } // provider失效时调用 @Override public void onProviderDisabled(String provider) { Log.d("Location", "onProviderDisabled"); } // provider启用时调用 @Override public void onProviderEnabled(String provider) { Log.d("Location", "onProviderEnabled"); } // 状态改变时调用 @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Location", "onStatusChanged"); } }; } |
13、[java] view plaincopy
- package wizzer.cn.app;
- public class SecBase64 {
- private static final byte[] encodingTable = { (byte) 'A', (byte) 'B',
- (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
- (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
- (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q',
- (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
- (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
- (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
- (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
- (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p',
- (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
- (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
- (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
- (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
- (byte) '+', (byte) '/' };
- private static final byte[] decodingTable;
- static {
- decodingTable = new byte[128];
- for (int i = 0; i < 128; i++) {
- decodingTable[i] = (byte) -1;
- }
- for (int i = 'A'; i <= 'Z'; i++) {
- decodingTable[i] = (byte) (i - 'A');
- }
- for (int i = 'a'; i <= 'z'; i++) {
- decodingTable[i] = (byte) (i - 'a' + 26);
- }
- for (int i = '0'; i <= '9'; i++) {
- decodingTable[i] = (byte) (i - '0' + 52);
- }
- decodingTable['+'] = 62;
- decodingTable['/'] = 63;
- }
- // 加密
- public static byte[] encode(byte[] data) {
- byte[] bytes;
- int modulus = data.length % 3;
- if (modulus == 0) {
- bytes = new byte[(4 * data.length) / 3];
- } else {
- bytes = new byte[4 * ((data.length / 3) + 1)];
- }
- int dataLength = (data.length - modulus);
- int a1;
- int a2;
- int a3;
- for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) {
- a1 = data[i] & 0xff;
- a2 = data[i + 1] & 0xff;
- a3 = data[i + 2] & 0xff;
- bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
- bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
- bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
- bytes[j + 3] = encodingTable[a3 & 0x3f];
- }
- int b1;
- int b2;
- int b3;
- int d1;
- int d2;
- switch (modulus) {
- case 0:
- break;
- case 1:
- d1 = data[data.length - 1] & 0xff;
- b1 = (d1 >>> 2) & 0x3f;
- b2 = (d1 << 4) & 0x3f;
- bytes[bytes.length - 4] = encodingTable[b1];
- bytes[bytes.length - 3] = encodingTable[b2];
- bytes[bytes.length - 2] = (byte) '=';
- bytes[bytes.length - 1] = (byte) '=';
- break;
- case 2:
- d1 = data[data.length - 2] & 0xff;
- d2 = data[data.length - 1] & 0xff;
- b1 = (d1 >>> 2) & 0x3f;
- b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
- b3 = (d2 << 2) & 0x3f;
- bytes[bytes.length - 4] = encodingTable[b1];
- bytes[bytes.length - 3] = encodingTable[b2];
- bytes[bytes.length - 2] = encodingTable[b3];
- bytes[bytes.length - 1] = (byte) '=';
- break;
- }
- return bytes;
- }
- // 解密
- public static byte[] decode(byte[] data) {
- byte[] bytes;
- byte b1;
- byte b2;
- byte b3;
- byte b4;
- data = discardNonBase64Bytes(data);
- if (data[data.length - 2] == '=') {
- bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
- } else if (data[data.length - 1] == '=') {
- bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
- } else {
- bytes = new byte[((data.length / 4) * 3)];
- }
- for (int i = 0, j = 0; i < (data.length - 4); i += 4, j += 3) {
- b1 = decodingTable[data[i]];
- b2 = decodingTable[data[i + 1]];
- b3 = decodingTable[data[i + 2]];
- b4 = decodingTable[data[i + 3]];
- bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
- bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
- bytes[j + 2] = (byte) ((b3 << 6) | b4);
- }
- if (data[data.length - 2] == '=') {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
- } else if (data[data.length - 1] == '=') {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- b3 = decodingTable[data[data.length - 2]];
- bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
- } else {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- b3 = decodingTable[data[data.length - 2]];
- b4 = decodingTable[data[data.length - 1]];
- bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
- bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
- }
- return bytes;
- }
- // 解密
- public static byte[] decode(String data) {
- byte[] bytes;
- byte b1;
- byte b2;
- byte b3;
- byte b4;
- data = discardNonBase64Chars(data);
- if (data.charAt(data.length() - 2) == '=') {
- bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
- } else if (data.charAt(data.length() - 1) == '=') {
- bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
- } else {
- bytes = new byte[((data.length() / 4) * 3)];
- }
- for (int i = 0, j = 0; i < (data.length() - 4); i += 4, j += 3) {
- b1 = decodingTable[data.charAt(i)];
- b2 = decodingTable[data.charAt(i + 1)];
- b3 = decodingTable[data.charAt(i + 2)];
- b4 = decodingTable[data.charAt(i + 3)];
- bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
- bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
- bytes[j + 2] = (byte) ((b3 << 6) | b4);
- }
- if (data.charAt(data.length() - 2) == '=') {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
- } else if (data.charAt(data.length() - 1) == '=') {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- b3 = decodingTable[data.charAt(data.length() - 2)];
- bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
- } else {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- b3 = decodingTable[data.charAt(data.length() - 2)];
- b4 = decodingTable[data.charAt(data.length() - 1)];
- bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
- bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
- }
- return bytes;
- }
- private static byte[] discardNonBase64Bytes(byte[] data) {
- byte[] temp = new byte[data.length];
- int bytesCopied = 0;
- for (int i = 0; i < data.length; i++) {
- if (isValidBase64Byte(data[i])) {
- temp[bytesCopied++] = data[i];
- }
- }
- byte[] newData = new byte[bytesCopied];
- System.arraycopy(temp, 0, newData, 0, bytesCopied);
- return newData;
- }
- private static String discardNonBase64Chars(String data) {
- StringBuffer sb = new StringBuffer();
- int length = data.length();
- for (int i = 0; i < length; i++) {
- if (isValidBase64Byte((byte) (data.charAt(i)))) {
- sb.append(data.charAt(i));
- }
- }
- return sb.toString();
- }
- private static boolean isValidBase64Byte(byte b) {
- if (b == '=') {
- return true;
- } else if ((b < 0) || (b >= 128)) {
- return false;
- } else if (decodingTable[b] == -1) {
- return false;
- }
- return true;
- }
- // 测试类
- public static void main(String[] args) {
- String data = "wizzer@qq.com:etpass";
- byte[] result = SecBase64.encode(data.getBytes());// 加密
- System.out.println("Basic " + data);
- System.out.println("Basic " + new String(result));
- System.out.println(new String(SecBase64.decode(new String(result))));// 解密
- }
- }
14、登陆页面输入用户名和密码,登陆成功后跳转到主页面,失败时显示错误信息。
传递参数时用BasicNameValuePair的List以httpPost.setEntity的方式来做,不能用HttpParams。
[java] view plaincopy
- userName = (EditText) this.findViewById(R.id.editTextUserName);
- password = (EditText) this.findViewById(R.id.editTextPassword);
- errorMsg = (TextView) this.findViewById(R.id.textViewLoginMsg);
- Button loginBtn = (Button) this.findViewById(R.id.btnLogin);
- loginBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- String result;
- /* 发送部分 */
- try {
- HttpClient httpClient = new DefaultHttpClient();
- String address = strUrl;
- HttpPost httpPost = new HttpPost(address);
- List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
- params.add(new BasicNameValuePair("username", userName.getText().toString()));
- params.add(new BasicNameValuePair("password", password.getText().toString()));
- httpPost.setEntity(new UrlEncodedFormEntity(params, "utf-8")); //将参数填入POST Entity中
- HttpResponse httpResponse = httpClient.execute(httpPost);
- /* 接收 */
- if (httpResponse.getStatusLine().getStatusCode() == 200) {
- result = EntityUtils.toString(httpResponse.getEntity());
- /* json文本解析 */
- JSONTokener jsonParser = new JSONTokener(result);
- JSONObject jsonResult = (JSONObject) jsonParser.nextValue();
- String status = jsonResult.getString("loginStatus");
- String outMessage = jsonResult.getString("outMessage");
- if(status.equals("true")){
- Intent i = new Intent(LoginActivity.this, MainActivity.class);
- i.putExtra("username", outMessage);
- startActivityForResult(i, FIRST_REQUEST_CODE);
- } else {
- errorMsg.setVisibility(View.VISIBLE);
- errorMsg.setText(outMessage);
- }
- } else {
- errorMsg.setVisibility(View.VISIBLE);
- errorMsg.setText("网络连接问题。CODE:" + httpResponse.getStatusLine().getStatusCode());
- }
- } catch (JSONException e) {
- e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- });
15、Android Http JSon服务器端和客户端通信
服务器端:
[java] view plaincopy
- package com.web.servlet;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import net.sf.json.JSONArray;
- import net.sf.json.JSONObject;
- import com.web.model.User;
- public class JSONServlet extends HttpServlet {
- /**
- * Constructor of the object.
- */
- public JSONServlet() {
- super();
- }
- /**
- * Destruction of the servlet. <br>
- */
- public void destroy() {
- super.destroy(); // Just puts "destroy" string in log
- // Put your code here
- }
- /**
- * The doGet method of the servlet. <br>
- *
- * This method is called when a form has its tag value method equals to get.
- *
- * @param request the request send by the client to the server
- * @param response the response send by the server to the client
- * @throws ServletException if an error occurred
- * @throws IOException if an error occurred
- */
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doPost(request, response);
- }
- /**
- * The doPost method of the servlet. <br>
- *
- * This method is called when a form has its tag value method equals to post.
- *
- * @param request the request send by the client to the server
- * @param response the response send by the server to the client
- * @throws ServletException if an error occurred
- * @throws IOException if an error occurred
- */
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html");
- PrintWriter out = response.getWriter();
- List<User> list = new ArrayList<User>();
- User u1 = new User();
- u1.setId(111);
- u1.setUsername("zhang shan");
- u1.setPassword("zs");
- User u2 = new User();
- u2.setId(222);
- u2.setUsername("li si");
- u2.setPassword("ls");
- User u3 = new User();
- u3.setId(333);
- u3.setUsername("wang wu");
- u3.setPassword("ww");
- list.add(u1);
- list.add(u2);
- list.add(u3);
- JSONArray ja = new JSONArray();
- for (Iterator iterator = list.iterator(); iterator.hasNext();) {
- User user = (User) iterator.next();
- JSONObject jobj= new JSONObject();
- jobj.put("id", user.getId());
- jobj.put("username", user.getUsername());
- jobj.put("password", user.getPassword());
- ja.add(jobj);
- }
- out.write(ja.toString());
- out.flush();
- out.close();
- }
- /**
- * Initialization of the servlet. <br>
- *
- * @throws ServletException if an error occurs
- */
- public void init() throws ServletException {
- // Put your code here
- }
- }
[java] view plaincopy
[java] view plaincopy
- 手机端:
[java] view plaincopy
- package com.web.activity;
- import java.io.BufferedInputStream;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.ObjectInputStream;
- import java.io.UnsupportedEncodingException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import org.apache.commons.httpclient.Cookie;
- import org.apache.commons.httpclient.HttpException;
- import org.apache.commons.httpclient.HttpStatus;
- import org.apache.commons.httpclient.NameValuePair;
- import org.apache.commons.httpclient.methods.PostMethod;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.entity.UrlEncodedFormEntity;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.client.methods.HttpUriRequest;
- import org.apache.http.entity.StringEntity;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.message.BasicNameValuePair;
- import org.apache.http.params.HttpConnectionParams;
- import org.apache.http.params.HttpParams;
- import org.apache.http.protocol.HTTP;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import com.web.model.User;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- public class WebclientActivity extends Activity {
- private TextView hello;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- HttpClient httpclient = new DefaultHttpClient();
- String uri="http://10.11.72.108:8086/web/JSONServlet";
- HttpPost httpReqest = new HttpPost(uri);
- try {
- HttpResponse response = httpclient.execute(httpReqest);
- HttpEntity entity = response.getEntity();
- BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
- StringBuffer sb = new StringBuffer();
- String line = null;
- while ((line = reader.readLine()) != null) {
- sb.append(line + "\n");
- }
- reader.close();
- JSONArray ja = new JSONArray(sb.toString());
- StringBuffer sb2 = new StringBuffer();
- for (int i = 0; i < ja.length(); i++) {
- JSONObject jobj= (JSONObject)ja.get(i);
- sb2.append("id:").append(jobj.getInt("id")).append(" ");
- sb2.append("用户:").append(jobj.getString("username")).append(" ");
- sb2.append("密码:").append(jobj.getString("password")).append("\r\n");
- }
- TextView hello = (TextView) findViewById(R.id.helloid);
- hello.setText(sb2.toString());
- } catch (Exception e) {
- Log.i("uuu", e.toString());
- }
- }
- }
16、我们编写的是Andorid的HTTP协议多线程断点下载应用程序。直接使用单线程下载HTTP文件对我们来说是一件非常简单的事。那么,多线程断点需要什么功能?
1.多线程下载,
2.支持断点。
使用多线程的好处:使用多线程下载会提升文件下载的速度。那么多线程下载文件的过程是:
(1)首先获得下载文件的长度,然后设置本地文件的长度。
HttpURLConnection.getContentLength();//获取下载文件的长度
RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");
file.setLength(filesize);//设置本地文件的长度
(2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置。
如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如下图所示。
例如10M大小,使用3个线程来下载,
线程下载的数据长度 (10%3 == 0 ? 10/3:10/3+1) ,第1,2个线程下载长度是4M,第三个线程下载长度为2M
下载开始位置:线程id*每条线程下载的数据长度 = ?
下载结束位置:(线程id+1)*每条线程下载的数据长度-1=?
(3)使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,
如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止
代码如下:HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");
(4)保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd");
threadfile.seek(2097152);//从文件的什么位置开始写入数据
程序结构如下图所示:
string.xml文件中代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">Android网络多线程断点下载</string>
<string name="path">下载路径</string>
<string name="downloadbutton">下载</string>
<string name="sdcarderror">SDCard不存在或者写保护</string>
<string name="success">下载完成</string>
<string name="error">下载失败</string>
</resources>
main.xml文件中代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- 下载路径 -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/path"/>
<EditText
android:id="@+id/path"
android:text="http://www.winrar.com.cn/download/wrar380sc.exe"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</EditText>
<!-- 下载按钮 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/downloadbutton"
android:id="@+id/button"/>
<!-- 进度条 -->
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="20dip"
style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/downloadbar" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="@+id/resultView" />
</LinearLayout>
AndroidManifest.xml文件中代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.downloader" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 访问internet权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
MainActivity中代码:
package com.android.downloader;
import java.io.File;
import com.android.network.DownloadProgressListener;
import com.android.network.FileDownloader;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText downloadpathText;
private TextView resultView;
private ProgressBar progressBar;
/**
* 当Handler被创建会关联到创建它的当前线程的消息队列,该类用于往消息队列发送消息
* 消息队列中的消息由当前线程内部进行处理
*/
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
progressBar.setProgress(msg.getData().getInt("size"));
float num = (float)progressBar.getProgress()/(float)progressBar.getMax();
int result = (int)(num*100);
resultView.setText(result+ "%");
if(progressBar.getProgress()==progressBar.getMax()){
Toast.makeText(MainActivity.this, R.string.success, 1).show();
}
break;
case -1:
Toast.makeText(MainActivity.this, R.string.error, 1).show();
break;
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
downloadpathText = (EditText) this.findViewById(R.id.path);
progressBar = (ProgressBar) this.findViewById(R.id.downloadbar);
resultView = (TextView) this.findViewById(R.id.resultView);
Button button = (Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String path = downloadpathText.getText().toString();
System.out.println(Environment.getExternalStorageState()+"------"+Environment.MEDIA_MOUNTED);
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
download(path, Environment.getExternalStorageDirectory());
}else{
Toast.makeText(MainActivity.this, R.string.sdcarderror, 1).show();
}
}
});
}
/**
* 主线程(UI线程)
* 对于显示控件的界面更新只是由UI线程负责,如果是在非UI线程更新控件的属性值,更新后的显示界面不会反映到屏幕上
* @param path
* @param savedir
*/
private void download(final String path, final File savedir) {
new Thread(new Runnable() {
@Override
public void run() {
FileDownloader loader = new FileDownloader(MainActivity.this, path, savedir, 3);
progressBar.setMax(loader.getFileSize());//设置进度条的最大刻度为文件的长度
try {
loader.download(new DownloadProgressListener() {
@Override
public void onDownloadSize(int size) {//实时获知文件已经下载的数据长度
Message msg = new Message();
msg.what = 1;
msg.getData().putInt("size", size);
handler.sendMessage(msg);//发送消息
}
});
} catch (Exception e) {
handler.obtainMessage(-1).sendToTarget();
}
}
}).start();
}
}
DBOpenHelper中代码:
package com.android.service;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DBNAME = "down.db";
private static final int VERSION = 1;
public DBOpenHelper(Context context) {
super(context, DBNAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS filedownlog (id integer primary key autoincrement, downpath varchar(100), threadid INTEGER, downlength INTEGER)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS filedownlog");
onCreate(db);
}
}
FileService中代码:
package com.android.service;
import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class FileService {
private DBOpenHelper openHelper;
public FileService(Context context) {
openHelper = new DBOpenHelper(context);
}
/**
* 获取每条线程已经下载的文件长度
* @param path
* @return
*/
public Map<Integer, Integer> getData(String path){
SQLiteDatabase db = openHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select threadid, downlength from filedownlog where downpath=?", new String[]{path});
Map<Integer, Integer> data = new HashMap<Integer, Integer>();
while(cursor.moveToNext()){
data.put(cursor.getInt(0), cursor.getInt(1));
}
cursor.close();
db.close();
return data;
}
/**
* 保存每条线程已经下载的文件长度
* @param path
* @param map
*/
public void save(String path, Map<Integer, Integer> map){//int threadid, int position
SQLiteDatabase db = openHelper.getWritableDatabase();
db.beginTransaction();
try{
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
db.execSQL("insert into filedownlog(downpath, threadid, downlength) values(?,?,?)",
new Object[]{path, entry.getKey(), entry.getValue()});
}
db.setTransactionSuccessful();
}finally{
db.endTransaction();
}
db.close();
}
/**
* 实时更新每条线程已经下载的文件长度
* @param path
* @param map
*/
public void update(String path, Map<Integer, Integer> map){
SQLiteDatabase db = openHelper.getWritableDatabase();
db.beginTransaction();
try{
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
db.execSQL("update filedownlog set downlength=? where downpath=? and threadid=?",
new Object[]{entry.getValue(), path, entry.getKey()});
}
db.setTransactionSuccessful();
}finally{
db.endTransaction();
}
db.close();
}
/**
* 当文件下载完成后,删除对应的下载记录
* @param path
*/
public void delete(String path){
SQLiteDatabase db = openHelper.getWritableDatabase();
db.execSQL("delete from filedownlog where downpath=?", new Object[]{path});
db.close();
}
}
DownloadProgressListener中代码:
package com.android.network;
public interface DownloadProgressListener {
public void onDownloadSize(int size);
}
FileDownloader中代码:
package com.android.network;
import java.io.File;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.android.service.FileService;
import android.content.Context;
import android.util.Log;
public class FileDownloader {
private static final String TAG = "FileDownloader";
private Context context;
private FileService fileService;
/* 已下载文件长度 */
private int downloadSize = 0;
/* 原始文件长度 */
private int fileSize = 0;
/* 线程数 */
private DownloadThread[] threads;
/* 本地保存文件 */
private File saveFile;
/* 缓存各线程下载的长度*/
private Map<Integer, Integer> data = new ConcurrentHashMap<Integer, Integer>();
/* 每条线程下载的长度 */
private int block;
/* 下载路径 */
private String downloadUrl;
/**
* 获取线程数
*/
public int getThreadSize() {
return threads.length;
}
/**
* 获取文件大小
* @return
*/
public int getFileSize() {
return fileSize;
}
/**
* 累计已下载大小
* @param size
*/
protected synchronized void append(int size) {
downloadSize += size;
}
/**
* 更新指定线程最后下载的位置
* @param threadId 线程id
* @param pos 最后下载的位置
*/
protected synchronized void update(int threadId, int pos) {
this.data.put(threadId, pos);
this.fileService.update(this.downloadUrl, this.data);
}
/**
* 构建文件下载器
* @param downloadUrl 下载路径
* @param fileSaveDir 文件保存目录
* @param threadNum 下载线程数
*/
public FileDownloader(Context context, String downloadUrl, File fileSaveDir, int threadNum) {
try {
this.context = context;
this.downloadUrl = downloadUrl;
fileService = new FileService(this.context);
URL url = new URL(this.downloadUrl);
if(!fileSaveDir.exists()) fileSaveDir.mkdirs();
this.threads = new DownloadThread[threadNum];
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5*1000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Referer", downloadUrl);
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
printResponseHeader(conn);
if (conn.getResponseCode()==200) {
this.fileSize = conn.getContentLength();//根据响应获取文件大小
if (this.fileSize <= 0) throw new RuntimeException("Unkown file size ");
String filename = getFileName(conn);//获取文件名称
this.saveFile = new File(fileSaveDir, filename);//构建保存文件
Map<Integer, Integer> logdata = fileService.getData(downloadUrl);//获取下载记录
if(logdata.size()>0){//如果存在下载记录
for(Map.Entry<Integer, Integer> entry : logdata.entrySet())
data.put(entry.getKey(), entry.getValue());//把各条线程已经下载的数据长度放入data中
}
if(this.data.size()==this.threads.length){//下面计算所有线程已经下载的数据长度
for (int i = 0; i < this.threads.length; i++) {
this.downloadSize += this.data.get(i+1);
}
print("已经下载的长度"+ this.downloadSize);
}
//计算每条线程下载的数据长度
this.block = (this.fileSize % this.threads.length)==0? this.fileSize / this.threads.length : this.fileSize / this.threads.length + 1;
}else{
throw new RuntimeException("server no response ");
}
} catch (Exception e) {
print(e.toString());
throw new RuntimeException("don't connection this url");
}
}
/**
* 获取文件名
* @param conn
* @return
*/
private String getFileName(HttpURLConnection conn) {
String filename = this.downloadUrl.substring(this.downloadUrl.lastIndexOf('/') + 1);
if(filename==null || "".equals(filename.trim())){//如果获取不到文件名称
for (int i = 0;; i++) {
String mine = conn.getHeaderField(i);
if (mine == null) break;
if("content-disposition".equals(conn.getHeaderFieldKey(i).toLowerCase())){
Matcher m = Pattern.compile(".*filename=(.*)").matcher(mine.toLowerCase());
if(m.find()) return m.group(1);
}
}
filename = UUID.randomUUID()+ ".tmp";//默认取一个文件名
}
return filename;
}
/**
* 开始下载文件
* @param listener 监听下载数量的变化,如果不需要了解实时下载的数量,可以设置为null
* @return 已下载文件大小
* @throws Exception
*/
public int download(DownloadProgressListener listener) throws Exception{
try {
RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rw");
if(this.fileSize>0) randOut.setLength(this.fileSize);
randOut.close();
URL url = new URL(this.downloadUrl);
if(this.data.size() != this.threads.length){
this.data.clear();
for (int i = 0; i < this.threads.length; i++) {
this.data.put(i+1, 0);//初始化每条线程已经下载的数据长度为0
}
}
for (int i = 0; i < this.threads.length; i++) {//开启线程进行下载
int downLength = this.data.get(i+1);
if(downLength < this.block && this.downloadSize<this.fileSize){//判断线程是否已经完成下载,否则继续下载
this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
this.threads[i].setPriority(7);
this.threads[i].start();
}else{
this.threads[i] = null;
}
}
this.fileService.save(this.downloadUrl, this.data);
boolean notFinish = true;//下载未完成
while (notFinish) {// 循环判断所有线程是否完成下载
Thread.sleep(900);
notFinish = false;//假定全部线程下载完成
for (int i = 0; i < this.threads.length; i++){
if (this.threads[i] != null && !this.threads[i].isFinish()) {//如果发现线程未完成下载
notFinish = true;//设置标志为下载没有完成
if(this.threads[i].getDownLength() == -1){//如果下载失败,再重新下载
this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
this.threads[i].setPriority(7);
this.threads[i].start();
}
}
}
if(listener!=null) listener.onDownloadSize(this.downloadSize);//通知目前已经下载完成的数据长度
}
fileService.delete(this.downloadUrl);
} catch (Exception e) {
print(e.toString());
throw new Exception("file download fail");
}
return this.downloadSize;
}
/**
* 获取Http响应头字段
* @param http
* @return
*/
public static Map<String, String> getHttpResponseHeader(HttpURLConnection http) {
Map<String, String> header = new LinkedHashMap<String, String>();
for (int i = 0;; i++) {
String mine = http.getHeaderField(i);
if (mine == null) break;
header.put(http.getHeaderFieldKey(i), mine);
}
return header;
}
/**
* 打印Http头字段
* @param http
*/
public static void printResponseHeader(HttpURLConnection http){
Map<String, String> header = getHttpResponseHeader(http);
for(Map.Entry<String, String> entry : header.entrySet()){
String key = entry.getKey()!=null ? entry.getKey()+ ":" : "";
print(key+ entry.getValue());
}
}
private static void print(String msg){
Log.i(TAG, msg);
}
}
DownloadThread 中代码:
package com.android.network;
import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import android.util.Log;
public class DownloadThread extends Thread {
private static final String TAG = "DownloadThread";
private File saveFile;
private URL downUrl;
private int block;
/* 下载开始位置 */
private int threadId = -1;
private int downLength;
private boolean finish = false;
private FileDownloader downloader;
public DownloadThread(FileDownloader downloader, URL downUrl, File saveFile, int block, int downLength, int threadId) {
this.downUrl = downUrl;
this.saveFile = saveFile;
this.block = block;
this.downloader = downloader;
this.threadId = threadId;
this.downLength = downLength;
}
@Override
public void run() {
if(downLength < block){//未下载完成
try {
HttpURLConnection http = (HttpURLConnection) downUrl.openConnection();
http.setConnectTimeout(5 * 1000);
http.setRequestMethod("GET");
http.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
http.setRequestProperty("Accept-Language", "zh-CN");
http.setRequestProperty("Referer", downUrl.toString());
http.setRequestProperty("Charset", "UTF-8");
int startPos = block * (threadId - 1) + downLength;//开始位置
int endPos = block * threadId -1;//结束位置
http.setRequestProperty("Range", "bytes=" + startPos + "-"+ endPos);//设置获取实体数据的范围
http.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
http.setRequestProperty("Connection", "Keep-Alive");
InputStream inStream = http.getInputStream();
byte[] buffer = new byte[1024];
int offset = 0;
print("Thread " + this.threadId + " start download from position "+ startPos);
RandomAccessFile threadfile = new RandomAccessFile(this.saveFile, "rwd");
threadfile.seek(startPos);
while ((offset = inStream.read(buffer, 0, 1024)) != -1) {
threadfile.write(buffer, 0, offset);
downLength += offset;
downloader.update(this.threadId, downLength);
downloader.append(offset);
}
threadfile.close();
inStream.close();
print("Thread " + this.threadId + " download finish");
this.finish = true;
} catch (Exception e) {
this.downLength = -1;
print("Thread "+ this.threadId+ ":"+ e);
}
}
}
private static void print(String msg){
Log.i(TAG, msg);
}
/**
* 下载是否完成
* @return
*/
public boolean isFinish() {
return finish;
}
/**
* 已经下载的内容大小
* @return 如果返回值为-1,代表下载失败
*/
public long getDownLength() {
return downLength;
}
}
运行效果如下:
版权声明:本文为博主原创文章,未经博主允许不得转载。
17、Android手机操作系统已经出现就受到了用户的好评。各大手机厂商也开始利用这一开源的系统抓住商机,发展自己的产业。在这里先来了解一下这一操作系统的一个小技巧,有关Android显示网络图片的实现。
在Android中显示一张网络图片其实是超级简单的,下面就一个非常简单的例子:
Android显示网络图片Step1:
1、创建你的Activity,本例中以ViewWebImageActivity说明;
2、ViewWebImageActivity中的代码如下:
[java] view plaincopy
- String imageUrl = "http://hiphotos.baidu.com/baidu/pic
- /item/7d8aebfebf3f9e125c6008d8.jpg";
- //这就是你需要显示的网络图片---网上随便找的
- Bitmap bmImg;
- ImageView imView;
- Button button1;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- imView = (ImageView) findViewById(R.id.imview);
- imView.setImageBitmap(returnBitMap(imageUrl));
- }
- public Bitmap returnBitMap(String url) {
- URL myFileUrl = null;
- Bitmap bitmap = null;
- try {
- myFileUrl = new URL(url);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- try {
- HttpURLConnection conn = (HttpURLConnection)
- myFileUrl.openConnection();
- conn.setDoInput(true);
- conn.connect();
- InputStream is = conn.getInputStream();
- bitmap = BitmapFactory.decodeStream(is);
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return bitmap;
- }
3、其中,returnBitMap(String url) 方法就是具体实现网络图片转换成bitmap。
Android显示网络图片Step2:
1、修改你的main.xml文件如下:
[java] view plaincopy
- < ?xml version="1.0" encoding="utf-8"?>
- < LinearLayout xmlns:android=
- "http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- < ImageView
- android:id="@+id/imview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- />
- < /LinearLayout>
Android显示网络图片Step3:
在你的AndroidManifest.xml文件的< /manifest>节点上面添加< uses-permission android:name="android.permission.INTERNET" />,这是由于Android有很多的权限限制,否则图片是不能在你的模拟器上显示的
18、android
[java] view plaincopy
- <span style=" font-family: Arial, Tahoma, Verdana, sans-serif; font-size: 14px;">获取网络信息需要在AndroidManifest.xml文件中加入相应的权限。 </span>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1)判断是否有网络连接
[java] view plaincopy
- public boolean isNetworkConnected(Context context) {
- if (context != null) {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
- if (mNetworkInfo != null) {
- return mNetworkInfo.isAvailable();
- }
- }
- return false;
- }
2)判断WIFI网络是否可用
[java] view plaincopy
- public boolean isWifiConnected(Context context) {
- if (context != null) {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo mWiFiNetworkInfo = mConnectivityManager
- .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- if (mWiFiNetworkInfo != null) {
- return mWiFiNetworkInfo.isAvailable();
- }
- }
- return false;
- }
3)判断MOBILE网络是否可用
[java] view plaincopy
- public boolean isMobileConnected(Context context) {
- if (context != null) {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo mMobileNetworkInfo = mConnectivityManager
- .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- if (mMobileNetworkInfo != null) {
- return mMobileNetworkInfo.isAvailable();
- }
- }
- return false;
- }
4)获取当前网络连接的类型信息
[java] view plaincopy
- public static int getConnectedType(Context context) {
- if (context != null) {
- ConnectivityManager mConnectivityManager = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
- if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
- return mNetworkInfo.getType();
- }
- }
- return -1;
- }
在开发android应用时,涉及到要进行网络访问,时常需要进行网络状态的检查,以提供给用户必要的提醒。一般可以通过ConnectivityManager来完成该工作。
ConnectivityManager有四个主要任务:
1、监听手机网络状态(包括GPRS,WIFI, UMTS等)
2、手机状态发生改变时,发送广播
3、当一个网络连接失败时进行故障切换
4、为应用程序提供可以获取可用网络的高精度和粗糙的状态
当我们要在程序中监听网络状态时,只要一下几个步骤即可:
1、定义一个Receiver重载其中的onReceive函数,在其中完成所需要的功能,如根据WIFI和GPRS是否断开来改变空间的外观
[java] view plaincopy
- connectionReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- ConnectivityManager connectMgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
- NetworkInfo mobNetInfo = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
- NetworkInfo wifiNetInfo = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- if (!mobNetInfo.isConnected() && !wifiNetInfo.isConnected()) {
- Log.i(TAG, "unconnect");
- // unconnect network
- }else {
- // connect network
- }
- }
- };
2、在适当的地方注册Receiver,可以在程序中注册,在onCreate中调用如下函数即可:
[java] view plaincopy
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- registerReceiver(connectionReceiver, intentFilter);
3、在适当时取消注册Receiver,可以在程序中取消,在onDestroye中调用如下函数即可:
[java] view plaincopy
- if (connectionReceiver != null) {
- unregisterReceiver(connectionReceiver);
- }
Ps:网上还有很多关于使用TelephonyManager 的方法的,方法如下(但是我试了好几次都有问题,如每次第一次进入一个Activity时会自动收到网络断开的信号,每次网络状态改变时收到多次回调且状态不正确。不知道有什么要注意的地方,求指点!)
[java] view plaincopy
- final TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
- mTelephonyMgr.listen(new PhoneStateListener(){
- @Override
- public void onDataConnectionStateChanged(int state) {
- switch(state){
- case TelephonyManager.DATA_DISCONNECTED://网络断开
- break;
- case TelephonyManager.DATA_CONNECTING://网络正在连接
- break;
- case TelephonyManager.DATA_CONNECTED://网络连接上
- break;
- }
- }
- }, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
至于第二种方法,本人并没有去尝试过。第一种方式还是比较好用,如果要程序隐藏在后台的话,建议开个service,将BroadcastReceiver注册在service,但不要忘了取消注册。
在测试中遇到过这样的状况,将一个当前连接wifi的路由设备关闭,但是程序并没有捕捉到unconnect network,可能是因为手机设备立刻连接另一个路由设备了
Android 监控网络状态
[java] view plaincopy
- public static boolean isNetworkAvailable(Context context) {
- ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (connectivity == null) {
- Log.i("NetWorkState", "Unavailabel");
- return false;
- } else {
- NetworkInfo[] info = connectivity.getAllNetworkInfo();
- if (info != null) {
- for (int i = 0; i < info.length; i++) {
- if (info[i].getState() == NetworkInfo.State.CONNECTED) {
- Log.i("NetWorkState", "Availabel");
- return true;
- }
- }
- }
- }
- return false;
- }
上面这个方法就是判断网络是否连接的代码,返回true表示有网络,返回false表示无网络。 在Android网络应用程序开发中,经常要判断网络连接是否可用,因此经常有必要监听网络状态的变化。android的网络状态监听可以用BroadcastReceiver来接收网络状态改变的广 播,具体实现如下
[java] view plaincopy
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.e(TAG, "网络状态改变");
- boolean success = false;
- //获得网络连接服务
- ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
- // State state = connManager.getActiveNetworkInfo().getState();
- State state = connManager.getNetworkInfo(
- ConnectivityManager.TYPE_WIFI).getState(); // 获取网络连接状态
- if (State.CONNECTED == state) { // 判断是否正在使用WIFI网络
- success = true;
- }
- state = connManager.getNetworkInfo(
- ConnectivityManager.TYPE_MOBILE).getState(); // 获取网络连接状态
- if (State.CONNECTED != state) { // 判断是否正在使用GPRS网络
- success = true;
- }
- if (!success) {
- Toast.makeText(LocationMapActivity.this, "您的网络连接已中断", Toast.LENGTH_LONG).show();
- }
- }
[java] view plaincopy
- //注册网络监听
- IntentFilter filter = new IntentFilter();
- filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- registerReceiver(mNetworkStateReceiver, filter);
- //在Activity中的onDestroy中:'
- unregisterReceiver(mNetworkStateReceiver); //取消监听
很多朋友在android开发中,都会遇到手机网络类型判断,因为就目前的android平台手机来说:可能会存在4中状态
1.无网络(这种状态可能是因为手机停机,网络没有开启,信号不好等原因)
2.使用WIFI上网
3.CMWAP(中国移动代理)
4.CMNET上网
这四种状态,如果没有网络,肯定是无法请求Internet了,如果是wap就需要为手机添加中国移动代理,关于为手机添加中国移动的代理!
下面是网络判断的方法:
[java] view plaincopy
- /**
- * @author sky
- * Email vipa1888@163.com
- * QQ:840950105
- * 获取当前的网络状态 -1:没有网络 1:WIFI网络2:wap网络3:net网络
- * @param context
- * @return
- */
- public static int getAPNType(Context context){
- int netType = -1;
- ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
- if(networkInfo==null){
- return netType;
- }
- int nType = networkInfo.getType();
- if(nType==ConnectivityManager.TYPE_MOBILE){
- Log.e("networkInfo.getExtraInfo()", "networkInfo.getExtraInfo() is "+networkInfo.getExtraInfo());
- if(networkInfo.getExtraInfo().toLowerCase().equals("cmnet")){
- netType = CMNET;
- }
- else{
- netType = CMWAP;
- }
- }
- else if(nType==ConnectivityManager.TYPE_WIFI){
- netType = WIFI;
- }
- return netType;
- }