ホームページ >ウェブフロントエンド >htmlチュートリアル >[ダークホース Android] (05) SMS/クエリと追加/コンテンツ オブザーバーの使用/サブスレッド ネットワーク イメージ ビューアーとハンドラー メッセージ プロセッサ/html ビューアー/HttpURLConnection を使用して Post メソッドを使用してデータをリクエスト/オープンソース Project_html/css_WEB-ITnose
SMS のバックアップと SMS の追加
オペレーティング システム SMS URI: content://sms/
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.backupsms" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.backupsms.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></manifest>
<RelativeLayout 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" tools:context=".MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:onClick="backupSms" android:text="备份短信" /></RelativeLayout>
package com.itheima28.backupsms.entities;public class SmsInfo { private int id; private String address; private long date; private int type; private String body; public SmsInfo(int id, String address, long date, int type, String body) { super(); this.id = id; this.address = address; this.date = date; this.type = type; this.body = body; } @Override public String toString() { return "SmsInfo [id=" + id + ", address=" + address + ", date=" + date + ", type=" + type + ", body=" + body + "]"; } public SmsInfo() { super(); // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public long getDate() { return date; } public void setDate(long date) { this.date = date; } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getBody() { return body; } public void setBody(String body) { this.body = body; }}
package com.itheima28.backupsms;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.List;import org.xmlpull.v1.XmlSerializer;import com.itheima28.backupsms.entities.SmsInfo;import android.net.Uri;import android.os.Bundle;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.util.Xml;import android.view.Menu;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 备份短信 * @param v */ public void backupSms(View v) { // 1. 查出所有的短信 Uri uri = Uri.parse("content://sms/"); ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(uri, new String[]{"_id", "address", "date", "type", "body"}, null, null, null); if(cursor != null && cursor.getCount() > 0) { List<SmsInfo> smsList = new ArrayList<SmsInfo>(); SmsInfo sms; while(cursor.moveToNext()) { // 控制游标结果集的指针向下移一位, 当到最后一位, 停止.返回false sms = new SmsInfo(); sms.setId(cursor.getInt(0)); // 设置短信的id sms.setAddress(cursor.getString(1)); // 设置短信的号码 sms.setDate(cursor.getLong(2)); // 设置短信的日期 sms.setType(cursor.getInt(3)); // 设置短信的类型, 接收1还是发送2 sms.setBody(cursor.getString(4)); // 设置短信的内容 smsList.add(sms); } cursor.close(); // 2. 序列化到本地 writeToLocal(smsList); } } /** * 序列化到本地 */ private void writeToLocal(List<SmsInfo> smsList) { try { XmlSerializer serializer = Xml.newSerializer(); // 得到序列化对象 // 指定输出位置 FileOutputStream fos = new FileOutputStream("/mnt/sdcard/sms.xml"); serializer.setOutput(fos, "utf-8"); serializer.startDocument("utf-8", true); serializer.startTag(null, "smss"); for (SmsInfo smsInfo : smsList) { serializer.startTag(null, "sms"); serializer.attribute(null, "id", String.valueOf(smsInfo.getId())); // 写号码 serializer.startTag(null, "address"); serializer.text(smsInfo.getAddress()); serializer.endTag(null, "address"); // 写时间 serializer.startTag(null, "date"); serializer.text(String.valueOf(smsInfo.getDate())); serializer.endTag(null, "date"); //写类型 serializer.startTag(null, "type"); serializer.text(String.valueOf(smsInfo.getType())); serializer.endTag(null, "type"); // 写内容 serializer.startTag(null, "body"); serializer.text(smsInfo.getBody()); serializer.endTag(null, "body"); serializer.endTag(null, "sms"); } serializer.endTag(null, "smss"); serializer.endDocument(); Toast.makeText(this, "备份成功", 0).show(); } catch (Exception e) { Toast.makeText(this, "备份失败", 0).show(); e.printStackTrace(); } }}
デート ツール
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.xiangqin" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.WRITE_SMS"/> <uses-permission android:name="android.permission.READ_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.xiangqin.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></manifest>
package com.itheima28.xiangqin;import android.net.Uri;import android.os.Bundle;import android.os.SystemClock;import android.app.Activity;import android.content.ContentValues;import android.view.Menu;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 停10秒钟, 想系统短信数据库中写一条短信 new Thread(new Runnable() { @Override public void run() { SystemClock.sleep(10 * 1000); Uri uri = Uri.parse("content://sms/"); // 操作sms表的uri ContentValues values = new ContentValues(); values.put("address", "95555"); values.put("type", "1"); values.put("body", "您的尾号为8890的账户, 收到100, 000, 000, 000.00元的转账. 活期余额为: 899, 777, 000, 111, 000.00元"); getContentResolver().insert(uri, values); } }).start(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }}連絡先のクエリと追加
連絡先のクエリ: raw_contacts、data
クエリ:
1. raw_contacts テーブルに移動して、すべての連絡先の _id を取得します
2. データ テーブルに移動して、上記で取得した _id に基づいて、ID に対応するデータをクエリします。
content://com .android .contacts/raw_contacts
content://com.android.contacts/data
<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" tools:context=".MainActivity" > <Button android:onClick="queryContacts" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="查询所有联系人" /> <Button android:onClick="addContacts" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="添加联系人" /></LinearLayout>
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.contacts" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.contacts.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></manifest>
package com.itheima28.contacts;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.view.View;public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private void printCursor(Cursor cursor) { if(cursor != null && cursor.getCount() > 0) { while(cursor.moveToNext()) { int columnCount = cursor.getColumnCount(); // 列的总数 for (int i = 0; i < columnCount; i++) { String columnName = cursor.getColumnName(i); // 取对应i位置的列的名称 String columnValue = cursor.getString(i); // 取出对应i位置的列的值 Log.i(TAG, "当前是第" + cursor.getPosition() + "行: " + columnName + " = " + columnValue); } } cursor.close(); } } /** * 查询联系人 * @param v */ public void queryContacts(View v) { // 1. 去raw_contacts表中取所有联系人的_id Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); Cursor cursor = getContentResolver().query(uri, new String[]{"_id"}, null, null, null);// printCursor(cursor); if(cursor != null && cursor.getCount() > 0) { while(cursor.moveToNext()) { int id = cursor.getInt(0); // 2. 去data表中根据上面取到的_id查询对应id的数据. String selection = "raw_contact_id = ?"; String[] selectionArgs = {String.valueOf(id)}; Cursor c = getContentResolver().query(dataUri, new String[]{"data1", "mimetype"}, selection, selectionArgs, null); if(c != null && c.getCount() > 0) { while(c.moveToNext()) { String mimetype = c.getString(1); // 当前取的是mimetype的值 String data1 = c.getString(0); // 当前取的是data1数据 if("vnd.android.cursor.item/phone_v2".equals(mimetype)) { Log.i(TAG, "号码: " + data1); } else if("vnd.android.cursor.item/name".equals(mimetype)) { Log.i(TAG, "姓名: " + data1); } else if("vnd.android.cursor.item/email_v2".equals(mimetype)) { Log.i(TAG, "邮箱: " + data1); } } c.close(); } } cursor.close(); } } public void addContacts(View v) { Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri = Uri.parse("content://com.android.contacts/data"); // 1. 在raw_contacts表中添加一个记录 // 取raw_contacts表中contact_id的值 Cursor cursor = getContentResolver().query(uri, new String[]{"contact_id"}, null, null, "contact_id desc limit 1"); if(cursor != null && cursor.moveToFirst()) { int contact_id = cursor.getInt(0); contact_id ++; cursor.close(); ContentValues values = new ContentValues(); values.put("contact_id", contact_id); getContentResolver().insert(uri, values); // 2. 根据上面添加记录的id, 取data表中添加三条数据 // 存号码 values = new ContentValues(); values.put("mimetype", "vnd.android.cursor.item/phone_v2"); values.put("data1", "10086"); values.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, values); // 存姓名 values = new ContentValues(); values.put("mimetype", "vnd.android.cursor.item/name"); values.put("data1", "中国移动"); values.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, values); // 存邮箱 values = new ContentValues(); values.put("mimetype", "vnd.android.cursor.item/email_v2"); values.put("data1", "10086@kengni.com"); values.put("raw_contact_id", contact_id); getContentResolver().insert(dataUri, values); } }}コンテンツ オブザーバーの使用法 コンテンツ オブザーバー:
送信ボックス uri:content://sms/outbox
package com.itheima28.contentobserverdemo;import android.app.Activity;import android.content.ContentResolver;import android.database.ContentObserver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.util.Log;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 监听系统短信 ContentResolver resolver = getContentResolver(); // 注册一个内容观察者观察短信数据库 resolver.registerContentObserver(Uri.parse("content://sms/"), true, new MyContentObserver(new Handler())); } /** * @author andong * 内容观察者 */ class MyContentObserver extends ContentObserver { private static final String TAG = "MyContentObserver"; public MyContentObserver(Handler handler) { super(handler); } /** * 当被监听的内容发生改变时回调 */ @Override public void onChange(boolean selfChange) { Log.i(TAG, "短信改变了"); Uri uri = Uri.parse("content://sms/outbox"); // 发件箱的uri // 查询发件箱的内容 Cursor cursor = getContentResolver().query(uri, new String[]{"address", "date", "body"}, null, null, null); if(cursor != null && cursor.getCount() > 0) { String address; long date; String body; while(cursor.moveToNext()) { address = cursor.getString(0); date = cursor.getLong(1); body = cursor.getString(2); Log.i(TAG, "号码: " + address + ", 日期: " + date + ", 内容: " + body); } cursor.close(); } } }}
ネットワーク画像ビューア
Android notResponding (アプリケーションが応答しない) がメイン スレッド ANR 例外をブロックしました
Exception:
CalledFromWrongThreadException: ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます。
元のスレッド (メイン スレッド、UI スレッド) はビュー オブジェクトを変更できます。
サブスレッドでビューの表示ステータスを変更すると、上記の例外が報告されます。
サブスレッド ネットワーク イメージ ビューアーとハンドラー メッセージ プロセッサー。
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.netphoto" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /><!-- 访问网络的权限 --> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.netphoto.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></manifest>
<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" tools:context=".MainActivity" > <ImageView android:id="@+id/iv_icon" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/et_url" android:layout_width="0dip" android:text="http://imgstatic.baidu.com/img/image/d833c895d143ad4bf450b6dd80025aafa40f06b4_%E5%89%AF%E6%9C%AC.jpg" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" /> <Button android:id="@+id/btn_submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Go" android:textSize="20sp" /> </LinearLayout></LinearLayout>
package com.itheima28.netphoto;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import javax.net.ssl.HttpsURLConnection;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.EditText;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener { private static final String TAG = "MainActivity"; protected static final int ERROR = 1; private EditText etUrl; private ImageView ivIcon; private final int SUCCESS = 0; private Handler handler = new Handler() { /** * 接收消息 */ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.i(TAG, "what = " + msg.what); if(msg.what == SUCCESS) { // 当前是访问网络, 去显示图片 ivIcon.setImageBitmap((Bitmap) msg.obj); // 设置imageView显示的图片 } else if(msg.what == ERROR) { Toast.makeText(MainActivity.this, "抓去失败", 0).show(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ivIcon = (ImageView) findViewById(R.id.iv_icon); etUrl = (EditText) findViewById(R.id.et_url); findViewById(R.id.btn_submit).setOnClickListener(this); } @Override public void onClick(View v) { final String url = etUrl.getText().toString(); new Thread(new Runnable() { @Override public void run() { Bitmap bitmap = getImageFromNet(url);// ivIcon.setImageBitmap(bitmap); // 设置imageView显示的图片 if(bitmap != null) { Message msg = new Message(); msg.what = SUCCESS; msg.obj = bitmap; handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = ERROR; handler.sendMessage(msg); } }}).start(); } /** * 根据url连接取网络抓去图片返回 * @param url * @return url对应的图片 */ private Bitmap getImageFromNet(String url) { HttpURLConnection conn = null; try { URL mURL = new URL(url); // 创建一个url对象 // 得到http的连接对象 conn = (HttpURLConnection) mURL.openConnection(); conn.setRequestMethod("GET"); // 设置请求方法为Get conn.setConnectTimeout(10000); // 设置连接服务器的超时时间, 如果超过10秒钟, 没有连接成功, 会抛异常 conn.setReadTimeout(5000); // 设置读取数据时超时时间, 如果超过5秒, 抛异常 conn.connect(); // 开始链接 int responseCode = conn.getResponseCode(); // 得到服务器的响应码 if(responseCode == 200) { // 访问成功 InputStream is = conn.getInputStream(); // 获得服务器返回的流数据 Bitmap bitmap = BitmapFactory.decodeStream(is); // 根据 流数据 创建一个bitmap位图对象 return bitmap; } else { Log.i(TAG, "访问失败: responseCode = " + responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { conn.disconnect(); // 断开连接 } } return null; }}HTML ビューア
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.htmldemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheima28.htmldemo.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></manifest>
<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" tools:context=".MainActivity" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <EditText android:id="@+id/et_url" android:layout_width="0dip" android:text="http://www.baidu.com" android:layout_height="wrap_content" android:singleLine="true" android:layout_weight="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="getHtml" android:text="GO" /> </LinearLayout> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tv_html" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </ScrollView></LinearLayout>
package com.itheima28.htmldemo;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private static final int SUCCESS = 0; protected static final int ERROR = 1; private EditText etUrl; private TextView tvHtml; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SUCCESS: tvHtml.setText((String) msg.obj); break; case ERROR: Toast.makeText(MainActivity.this, "访问失败", 0).show(); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etUrl = (EditText) findViewById(R.id.et_url); tvHtml = (TextView) findViewById(R.id.tv_html); } public void getHtml(View v) { final String url = etUrl.getText().toString(); new Thread(new Runnable() { @Override public void run() { // 请求网络 String html = getHtmlFromInternet(url); if(!TextUtils.isEmpty(html)) { // 更新textview的显示了 Message msg = new Message(); msg.what = SUCCESS; msg.obj = html; handler.sendMessage(msg); } else { Message msg = new Message(); msg.what = ERROR; handler.sendMessage(msg); } } }).start(); } /** * 根据给定的url访问网络, 抓去html代码 * @param url * @return */ protected String getHtmlFromInternet(String url) { try { URL mURL = new URL(url); HttpURLConnection conn = (HttpURLConnection) mURL.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(10000); conn.setReadTimeout(5000); // conn.connect(); int responseCode = conn.getResponseCode(); if(responseCode == 200) { InputStream is = conn.getInputStream(); String html = getStringFromInputStream(is); return html; } else { Log.i(TAG, "访问失败: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 根据流返回一个字符串信息 * @param is * @return * @throws IOException */ private String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } is.close(); String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 String charset = "utf-8"; if(html.contains("gbk") || html.contains("gb2312") || html.contains("GBK") || html.contains("GB2312")) { // 如果包含gbk, gb2312编码, 就采用gbk编码进行对字符串编码 charset = "gbk"; } html = new String(baos.toByteArray(), charset); // 对原有的字节数组进行使用处理后的编码名称进行编码 baos.close(); return html; }}HTML ビューアの文字化け問題
/** * 根据流返回一个字符串信息 * @param is * @return * @throws IOException */ private String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } is.close(); String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 String charset = "utf-8"; if(html.contains("gbk") || html.contains("gb2312") || html.contains("GBK") || html.contains("GB2312")) { // 如果包含gbk, gb2312编码, 就采用gbk编码进行对字符串编码 charset = "gbk"; } html = new String(baos.toByteArray(), charset); // 对原有的字节数组进行使用处理后的编码名称进行编码 baos.close(); return html; }
HttpURLConnection を使用して Post メソッドを使用してデータをリクエストする
サーブレットサーバープログラム
package com.itheima28.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class LoginServlet extends HttpServlet { /** * 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 { String username = request.getParameter("username"); // 采用的编码是: iso-8859-1 String password = request.getParameter("password"); // 采用iso8859-1的编码对姓名进行逆转, 转换成字节数组, 再使用utf-8编码对数据进行转换, 字符串 username = new String(username.getBytes("iso8859-1"), "utf-8"); password = new String(password.getBytes("iso8859-1"), "utf-8"); System.out.println("姓名: " + username); System.out.println("密码: " + password); if("lisi".equals(username) && "123".equals(password)) { /* * getBytes 默认情况下, 使用的iso8859-1的编码, 但如果发现码表中没有当前字符, * 会使用当前系统下的默认编码: GBK */ response.getOutputStream().write("登录成功".getBytes("utf-8")); } else { response.getOutputStream().write("登录失败".getBytes("utf-8")); } } /** * 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 { System.out.println("doPost"); doGet(request, response); }}
Android クライアント
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheim28.submitdata" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.itheim28.submitdata.MainActivity2" 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></manifest>
<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" tools:context=".MainActivity" > <EditText android:id="@+id/et_username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入姓名" /> <EditText android:id="@+id/et_password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入密码" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="doGet" android:text="Get方式提交" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="doPost" android:text="Post方式提交" /></LinearLayout>
package com.itheim28.submitdata.utils;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.net.URLEncoder;import android.util.Log;public class NetUtils { private static final String TAG = "NetUtils"; /** * 使用post的方式登录 * @param userName * @param password * @return */ public static String loginOfPost(String userName, String password) { HttpURLConnection conn = null; try { URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet"); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(10000); // 连接的超时时间 conn.setReadTimeout(5000); // 读数据的超时时间 conn.setDoOutput(true); // 必须设置此方法, 允许输出// conn.setRequestProperty("Content-Length", 234); // 设置请求头消息, 可以设置多个 // post请求的参数 String data = "username=" + userName + "&password=" + password; // 获得一个输出流, 用于向服务器写数据, 默认情况下, 系统不允许向服务器输出内容 OutputStream out = conn.getOutputStream(); out.write(data.getBytes()); out.flush(); out.close(); int responseCode = conn.getResponseCode(); if(responseCode == 200) { InputStream is = conn.getInputStream(); String state = getStringFromInputStream(is); return state; } else { Log.i(TAG, "访问失败: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { conn.disconnect(); } } return null; } /** * 使用get的方式登录 * @param userName * @param password * @return 登录的状态 */ public static String loginOfGet(String userName, String password) { HttpURLConnection conn = null; try { String data = "username=" + URLEncoder.encode(userName) + "&password=" + URLEncoder.encode(password); URL url = new URL("http://10.0.2.2:8080/ServerItheima28/servlet/LoginServlet?" + data); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); // get或者post必须得全大写 conn.setConnectTimeout(10000); // 连接的超时时间 conn.setReadTimeout(5000); // 读数据的超时时间 int responseCode = conn.getResponseCode(); if(responseCode == 200) { InputStream is = conn.getInputStream(); String state = getStringFromInputStream(is); return state; } else { Log.i(TAG, "访问失败: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { conn.disconnect(); // 关闭连接 } } return null; } /** * 根据流返回一个字符串信息 * @param is * @return * @throws IOException */ private static String getStringFromInputStream(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } is.close(); String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8 // String html = new String(baos.toByteArray(), "GBK"); baos.close(); return html; }}
package com.itheim28.submitdata;import com.itheim28.submitdata.utils.NetUtils;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends Activity { private EditText etUserName; private EditText etPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etUserName = (EditText) findViewById(R.id.et_username); etPassword = (EditText) findViewById(R.id.et_password); } public void doGet(View v) { final String userName = etUserName.getText().toString(); final String password = etPassword.getText().toString(); new Thread( new Runnable() { @Override public void run() { // 使用get方式抓去数据 final String state = NetUtils.loginOfGet(userName, password); // 执行任务在主线程中 runOnUiThread(new Runnable() { @Override public void run() { // 就是在主线程中操作 Toast.makeText(MainActivity.this, state, 0).show(); } }); } }).start(); } public void doPost(View v) { final String userName = etUserName.getText().toString(); final String password = etPassword.getText().toString(); new Thread(new Runnable() { @Override public void run() { final String state = NetUtils.loginOfPost(userName, password); // 执行任务在主线程中 runOnUiThread(new Runnable() { @Override public void run() { // 就是在主线程中操作 Toast.makeText(MainActivity.this, state, 0).show(); } }); } }).start(); }}オープンソース プロジェクトの紹介
github.com オープンソースの Web サイト、大規模な倉庫 すべてのフレームワークが保存されています
android-async-http-master.zip
android-smart-image-view- master .zip
最も人気のある Android オープンソース プロジェクト csdn の投稿を直接使用します