往sd卡写数据
权限<
uses-permission
android:name
=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
try {
//得到sd卡路径
String str = Environment.getExternalStorageDirectory().getPath();
File file = new File(str, "测试.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write("测试".getBytes());
fos.close();
} catch (Exception e) {
Toast.makeText(FileStudyActivity.this, "失败啊", 1).show();
// TODO Auto-generated catch block
e.printStackTrace();
}
//判断sd卡状态
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
Toast.makeText(FileStudyActivity.this, "sd卡可用", 1).show();
}
else{
Toast.makeText(FileStudyActivity.this, "sd卡不可用", 1).show();
}
获取sd卡空间数据
//得到路径
File file = Environment.getExternalStorageDirectory();
long totaSpace = file.getTotalSpace();//总大小
long usablespace = file.getUsableSpace();//可用空间
//转换格式
t1.setText(t1.getText()+
Formatter.formatFileSize(this, totaSpace));
t2.setText(t2.getText()+
Formatter.formatFileSize(this, usablespace));
文件权限
// 按钮点击事件
public
void
click1(View v) {
try
{
FileOutputStream fos = openFileOutput(
"私有.txt"
,
MODE_PRIVATE
);
fos.write(
"私有文件演示"
.getBytes());
fos.close();
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
// 按钮点击事件
public
void
click2(View v) {
try
{
FileOutputStream fos = openFileOutput(
"可追加.txt"
,
MODE_APPEND
);
fos.write(
"可追加文件演示"
.getBytes());
fos.close();
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
// 按钮点击事件
public
void
click3(View v) {
try
{
FileOutputStream fos = openFileOutput(
"可读.txt"
,
MODE_WORLD_READABLE
);
fos.write(
"可读文件演示"
.getBytes());
fos.close();
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
// 按钮点击事件
public
void
click4
(View v) {
try
{
FileOutputStream fos = openFileOutput(
"可写.txt"
,
MODE_WORLD_WRITEABLE
);
fos.write(
"可写文件演示"
.getBytes());
fos.close();
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
xml文件
<
LinearLayout
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:orientation
=
"vertical"
>
<
Button
android:onClick
=
"click1"
android:id
=
"@+id/button1"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"私有"
/>
<
Button
android:id
=
"@+id/button2"
android:onClick
=
"click2"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"可追加"
/>
<
Button
android:id
=
"@+id/button3"
android:onClick
=
"click3"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"可读"
/>
<
Button
android:id
=
"@+id/button4"
android:onClick
=
"click4"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:text
=
"可写"
/>
LinearLayout
>
SharedPreferences介绍(*****)
用法:
【1】获取sp实例
【2】获取编辑器 Edit edit = sp.edit();
【3】存数据 edit.put类型();
【4】提交 edit.
commit();
public
void
click5(View v) {
//拿到实例(通过上下文)
/**
* 第一个参数会帮我们生成一个xml文件
* 第二个参数代表文件权限
*/
SharedPreferences sp = getSharedPreferences(
"user"
, 0);
//获取sp的编辑器
Editor edit = sp.edit();
edit.putString(
"name"
,
"登录名"
);
edit.putString(
"pwd"
,
"密码"
);
//提交
edit.commit();
public
void
click6(View v){
//先初始化sp实例
SharedPreferences sp = getSharedPreferences(
"user"
, 0);
String str =
""
;
str += sp.getString(
"name"
,
""
);
str += sp.getString(
"pwd"
,
""
);
Toast.makeText(
this
, str, 1).show();
生成xml
第一种 自己拼接
public
void
click7(View v) {
List smsLists =
new
ArrayList();
for
(
int
i = 0; i < 10; i++) {
smsLists.add(
new
Sms(
"100"
+ i,
"你好"
+ i));
}
StringBuffer sb =
new
StringBuffer();
sb.append(
""
);
sb.append(
""
);
for
(Sms sms : smsLists){
sb.append(
""
);
sb.append(
""
+sms.getName());
sb.append(
""
);
sb.append(
"pwd"
+sms.getPwd());
sb.append(
""
);
sb.append(
""
);
}
sb.append(
""
);
//保存
File file =
new
File(Environment.getExternalStorageDirectory(),
"MyUser.xml"
);
try
{
FileOutputStream fos =
new
FileOutputStream(file);
fos.write(sb .toString().getBytes());
fos.close();
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
第二种
public
void
click8(View v) {
List smsLists =
new
ArrayList();
for
(
int
i = 0; i < 10; i++) {
smsLists.add(
new
Sms(
"100"
+ i,
"你好"
+ i));
}
// 获取xmlSerializer类的实例, 通过Xml这个工具类获取
XmlSerializer xsl = Xml.newSerializer();
// 设置Xmlserializer序列化器参数
File file =
new
File(Environment.getExternalStorageDirectory()
.getPath(),
"MyUser2.xml"
);
try
{
FileOutputStream fos =
new
FileOutputStream(file);
xsl.setOutput(fos,
"utf-8"
);
// 开始写xml文档开头
xsl.startDocument(
"utf-8"
,
true
);
// 写xml的根节点 第一个参数:命名空间 第二个参数 标签名
xsl.startTag(
null
,
"smss"
);
//
for
(Sms sms : smsLists) {
xsl.startTag(
null
,
"sms"
);
xsl.startTag(
null
,
"name"
);
xsl.text(sms.getName());
xsl.endTag(
null
,
"name"
);
xsl.startTag(
null
,
"pwd"
);
xsl.text(sms.getPwd());
xsl.endTag(
null
,
"pwd"
);
xsl.endTag(
null
,
"sms"
);
}
xsl.endTag(
null
,
"smss"
);
// 文档结尾
xsl.endDocument();
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
Xml解析
解析步骤
【1】获取XmlPullParser
【2】设置XmlPullParser的参数
【3】获取解析文档的事件类型
【4】具体判断一下是哪个标签
public
static
List parserXml(InputStream in)
throws
Exception {
List weatherLists =
null
;
// 1、获取XmlPullParser 解析的实例
XmlPullParser parser = Xml.newPullParser();
// 2、设置XmlPullParser 的参数
parser.setInput(in,
"utf-8"
);
// 3、获取事件类型
int
type = parser.getEventType();
while
(type != XmlPullParser.
END_DOCUMENT
) {
// 4、具体判断一下解析到了哪个节点
switch
(type) {
// 解析开始
case
XmlPullParser.
START_TAG
:
if
(
"weather"
.equals(parser.getName())) {
// 创建一个集合对象
weatherLists =
new
ArrayList();
}
else
if
(
"channel"
.equals(parser.getName())) {
// 属性值
String str1 = parser.getAttributeValue(0);
}
else
if
(
"city"
.equals(parser.getName())) {
// 两个标签之中的值
String city = parser.nextText();
}
break
;
// 解析结束
case
XmlPullParser.
END_TAG
:
break
;
}
// 不停的向下解析
parser.next();
}
return
null
;
}
获取资产的管理者(安卓工程assets目录下的文件)
InputStream is = getAssets().open(文件名);
数据库
(在有大量数据需要存储的时候需要用到数据库)
使用SQLLite Expert Professionan这个工具
可以打开创建的数据库
import
android.content.Context;
import
android.database.sqlite.SQLiteDatabase;
import
android.database.sqlite.SQLiteDatabase.CursorFactory;
import
android.database.sqlite.SQLiteOpenHelper;
public
class
MyOpenHelper
extends
SQLiteOpenHelper {
/**
*
@param
context
*
@param
name
*
@param
factory
*
@param
version
* name第二个参数:数据库的名字 第三个参数:目的创建Cursor对象 第四个参数:数据库的版本 从1开始
*/
public
MyOpenHelper(Context context) {
super
(context,
"MySQL.db"
,
null
, 1);
}
/*
* (non-Javadoc)
*
* @see
* android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite
* .SQLiteDatabase) 当数据库第一次创建时调用 这个方法特别适合做表结构的初始化
*/
@Override
public
void
onCreate(SQLiteDatabase db) {
// id一般以下划线开头
db.execSQL(
"Create table info(_id interger primary key, name varchar(20))"
);
}
@Override
public
void
onUpgrade(SQLiteDatabase db,
int
oldVersion,
int
newVersion) {
}
}
----------------------------------------
调用
// 打开数据库或者创建数据库 如果是第一次就创建
MyOpenHelper myOpenHelper =
new
MyOpenHelper(getApplicationContext());
// 打开数据库或者创建数据库 如果是第一次就创建 如果磁盘满了 返回只读的
SQLiteDatabase sqliteDatabase = myOpenHelper.getWritableDatabase();
//SQL语句
db.execSQL("insert into info(name, phone) values(?,?)",new Object[]{"张三","15055819391"});
//数据库用完需要关闭
db.close();
//查找
Cursor cursor= db.rawQuery(参数1, 参数2);
if(cursor != null && cursor.getCount()>0){
while(cursor.moveToNext()){
String name = cursor.getString(1);
}
}
cursor.close();
----------------------------------------
使用谷歌提供操作数据库的方法
添加 : ContentValues values = new ContentValues();
values.put("name", "王五");
values.put("phone", "110");
long insert = db.insert("表名", null, values);
//返回插入新行id, >0添加成功
db.close();
删除 ; int delete = db.delete("表名", "name=?", new String[]{"王五"});
//删除的行数
db.close();
更新 : ContentValues values = new ContentValues();
int update = db.update("表名",values, "name=?", new String[]{"王五"});
//代表更新了多少行
第二个参数代表要查询的列(null代表所有列)
第三个参数代表查询根据
第五个参数是否分组
第七个是否排序
查找 : Cursor cursor = db.quary("表名", new String[]{"phone"}, "name=?", new String[]{"王五"}, null, null, null);
ListVIew
import
org.w3c.dom.Text;
import
android.content.Context;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.BaseAdapter;
import
android.widget.TextView;
public
class
Base
extends
BaseAdapter {
Context
context
;
Base(ListAgainStudy con) {
this
.
context
= con;
}
public
int
getCount() {
return
100;
}
public
Object getItem(
int
position) {
return
null
;
}
public
long
getItemId(
int
position) {
return
0;
}
public
View getView(
int
position, View conTextView, ViewGroup arg2) {
// 代码优化
TextView tv =
null
;
if
(conTextView ==
null
) {
// 创建新的view 对象
tv =
new
TextView(
context
);
}
else
{
// 复用历史缓存对象
tv = (TextView) conTextView;
}
tv.setText(
"haha"
+position);
return
tv;
}
}
调用
listView = (ListView) findViewById(R.id.list1);
listView.setAdapter(new Base(this));
LIstView 的奇怪现象
注意:在使用ListView 时,XML文件中ListView 属性的高应该使用(匹配父控件), 不应该使用(包裹内容),因为使用(包裹内容)
效率低
列表复杂界面(使用打气筒)
private
class
MyBase
extends
BaseAdapter {
public
int
getCount() {
return
20;
}
public
Object getItem(
int
position) {
return
null
;
}
public
long
getItemId(
int
position) {
return
0;
}
public
View getView(
int
position, View convertView, ViewGroup parent) {
View view;
if
(convertView ==
null
){
// 打气筒 : 可以通过一个打气筒把一个资源布局转换成一个view 对象
// 第二个参数: 布局文件
// 第三个参数: 用不到
view = View.inflate(getApplicationContext(), R.layout.
item
,
null
);
}
else
{
// 复用历史缓存对象
view = convertView;
}
return
view;
}
}
TextView
单行显示
android:singleLine="true"
...
android:ellipsize="end"
线性布局, 相对布局 都继承自ViewGroup 可以有自己的孩子
打气筒详解(inflate)
第一种:
view = View.inflate(getApplicationContext(), R.layout.item, null);
第二种:
LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
第三种:
(工作中常见)
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.item, null);
Adaper作用:把数据展示到ListView上
ArrayAdapter适配器
public
class
Arrayadapter
extends
Activity {
private
ListView
lv
;
String
object
[] = {
"老张"
,
"老方"
,
"老李"
,
"老王"
,
"老毕"
,
"老师"
,
"老孙"
};
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.
array
);
lv
= (ListView) findViewById(R.id.
ALV
);
// 创建一个ArrayAdapter
ArrayAdapter adapter =
new
ArrayAdapter(
this
,
R.layout.
aarrayitem
,
object
);
// 设置数据适配器
lv
.setAdapter(adapter);
}
}
xml:
array:
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
android:orientation
=
"vertical"
>
<
ListView
android:id
=
"@+id/ALV"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
>
ListView
>
LinearLayout
>
arrayitem:
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
TextView
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
>
TextView
>
SimpleAdapter适配器
使用map封装数据
public
class
Simplleadapter
extends
Activity {
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.
sim
);
ListView lv = (ListView) findViewById(R.id.
SLV
);
// 准备数据
List
new
ArrayList
Map map1 =
new
HashMap();
map1.put(
"name"
,
"张三"
);
map1.put(
"phone"
,
"88888888"
);
Map map2 =
new
HashMap();
map2.put(
"name"
,
"赵云"
);
map2.put(
"phone"
,
"66668888"
);
Map map3 =
new
HashMap();
map3.put(
"name"
,
"貂蝉"
);
map3.put(
"phone"
,
"12345678"
);
data.add(map1);
data.add(map2);
data.add(map3);
SimpleAdapter adapter =
new
SimpleAdapter(getApplicationContext(),
data, R.layout.
sim1
,
new
String[] {
"name"
,
"phone"
},
new
int
[] { R.id.
stv1
, R.id.
stv2
});
lv.setAdapter(adapter);
TextView tv = (TextView) findViewById(R.id.
smiantv
);
tv.setText(
"源码:\nSimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), data, R.layout.sim1, new String[]{\"name\", \"phone\"}, new int[]{R.id.stv1, R.id.stv2});"
);
}
权重只在线性布局中使用
网络编程
HttpURLConnection用于发送和接收数据
android.os.NetworkOnMainThreadException是说不要在主线程中访问网络,这个是android3.0版本开始就强制程序不能在主线程中访问网络,要把访问网络放在独立的线程中。
在开发中,为了防止访问网络阻塞主线程,一般都要把访问网络放在独立线程中或者异步线程AsyncTask中。
1、想要忽略这些强制策略问题的话,可以在onCreate()方法里面加上
StrictMode.ThreadPolicy policy =
new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
并在方法上加上@SuppressLint("NewApi"),重试,OK。
只有主线程才能更新UI
Handler使用
Handler作用:是用来发消息和处理消息
Lopper作用: 去消息队列里面取消息(主线程一创建Lopper就有了)
在主线程中定义
private
Handler
handler
=
new
Handler() {
public
void
handleMessage(Message msg) {
// 可以在主线程中更新UI
String content = (String) msg.
obj
;
tv
.setText(content);
}
};
点击事件
public
void
click(View v) {
new
Thread() {
public
void
run() {
// 获取源码路径
String path =
ed
.getText().toString();
path =
"http://"
+ path;
// HttpURLConnection
try
{
URL url =
new
URL(path);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setRequestMethod(
"GET"
);
// 要求大写
// 设置请求的超时时间
conn.setConnectTimeout(5000);
// 获取服务器返回的状态吗
int
code = conn.getResponseCode();
// 如果code == 200 请求成功
if
(code == 200) {
// 过去服务器返回的数据 是以流的方式返回
InputStream in = conn.getInputStream();
// 把流里面的数据显示到文本标签上
// 把流转换成字符串 (做成工具类)
String content = StreamTools.readStream(in);
// tv.setText(content);
// 拿着我们创建的handler(助手)告诉系统需要更新UI
Message msg =
new
Message();
msg.
obj
= content;
handler
.sendMessage(msg);
// 发送一条消息, 消息
}
}
catch
(Exception e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
图片查看器
1、把流信息转换成bitmap对象
2、bitmapFactory.decodeStream(imputStream in)
3、加上网络访问权限
//这句API不管在什么地方调用 action都运行在UI线程路
runOnUiThread(action)
runOnUiThread(new Runnable(){
public void runn(){
//动作
}
});
1、如果仅仅就是更新UI 那么就用runOnUiThread 这个API就可以
2、有的时候可以通过Handler 发送消息 携带数据, 这个时候必须的用Handler
API:应用开发接口
Handler
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.
main
);
new
Handler().postDelayed(
new
Runnable() {
public
void
run() {
//
TODO
Auto-generated method stub
Toast.makeText(getApplicationContext(),
"handler等待5s显示"
, 1)
.show();
TextView tv = (TextView) findViewById(R.id.
button1
);
tv.setText(
"5s后显示"
);
}
}, 5000);
}