在编写最简单的Content Provider中,是应用内部调用自定义的Content Provider,因此可以做到类似的写法:
Cursor cursor = managedQuery(MyContentProvider.CONTENT_URI, null, null,null, null);
其实,如果编写调用android系统自带的比如通讯录的Content provider,也可以有类似的写法。因为你的应用可以引用到这些类。
如果是自己的Content provider要让其他应用使用,那不可能让人家把自己的包导入进来的。怎么办呢?可以直接把这些常量的值写出来即可。这也要求,如果你想共享自己的Content provider,需要告诉人家这些常量:
- MyContentProvider.CONTENT_URI
- MyContentProvider.NAME
- MyContentProvider.START_YEAR
- MyContentProvider.DYNASTY
在前面的编写最简单的Content Provider的示例是很粗糙的,目的是让读者尽快了解怎样编写和使用Content provider。
其中一个事情是,如果重复启动该应用,会多次插入,产生重复的记录并显示到activity中。在上个例子中没有做处理,比如判断是否存在数据库等等。
Android为SQLite提供了便利的API,方便自动创建新的数据库或者升级数据库。其实本文的示例并不一定要在Content provider使用情况下,是在android sqlite编程下都可以用的。
android提供了这个类:
android.database.sqlite.SQLiteOpenHelper
有两个抽象方法需要继承以后实现:
public void onCreate(SQLiteDatabase database)
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion)
其中第一个onCreate方法,在实现代码中要写出怎样创建你需要的数据库和表,以及一些初始数据。这实际上是个回调(callback),android会自动判断是否有该数据库,如果没有,就调用这个方法创建。
onUpgrade方法,在这种情况下调用,你的应用中的sqlite数据库升级了,比如,表结构都发生了变化,那么android就会调用这个方法升级数据库。你需要实现这个方法,指出如何升级数据库,在下面示例中,是很简单的一种做法,就是删除就版本数据库,重新创建新版本的数据库。复杂的做法(也是平滑升级的做法)是,把旧数据库中的信息导入到新数据库中。
在自己的android应用中存储数据,可以用SQLite数据库。不过,如果需要在多个应用中共享数据,在Android中,只有通过Content provider机制。
下面用一个最简单(不完整)的示例来说明Content Provider的创建。在界面中使用这个示例显示的效果:
显示帝王姓名、登基年份和朝代。
在android下通过adb shell命令可以进入sqlite3的命令行client,见:在android命令行下使用sqlite3。
如果想列出该数据库中的所有表,可:
.table
如果想查看这些表的结构:
select * from sqlite_master where type="table";
可以看到类似:
写了个简单的zip压缩单文件的示例,应该可以用在android环境下。主要用于对日志文件的压缩,方便上传。
package com.easymorse.gallery;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;public class ZipDemo {
public static void main(String[] args) throws Exception {
zipFile(new File("a.log"),new File("a.zip"));
}public static void zipFile(File source, File target) throws IOException {
byte[] buffer = new byte[1024];
ZipOutputStream outputStream = new ZipOutputStream(
new FileOutputStream(target));
outputStream.putNextEntry(new ZipEntry(source.getName()));
InputStream inputStream = new FileInputStream(source);
for (int i = inputStream.read(buffer); i > 0; i = inputStream
.read(buffer)) {
outputStream.write(buffer, 0, i);
}
inputStream.close();
outputStream.close();
}
}
Android系统中,如果发起对浏览器的调用,并不是直接调用chrome lite浏览器,而是发起一个Intent对象,包含一些条件。这样其他浏览器比如opera mini也可进入备选应用列表,供用户选择。
本文主要参考:http://androidappdocs.appspot.com/guide/topics/intents/intents-filters.html
Activity、Service和Broadcast Receiver这些核心组件之间通过消息激活,这个消息就是Intent。
Intent消息可用于当前运行时同应用内部的组件之间或者不同应用的组件之间通信。Intent自身,即一个Intent对象,包含说明一个执行操作的抽象数据结构,传递给执行操作的组件,或者,常见于broadcast的情况,该数据结构用于描述正在执行或者已经发生的事情。
针对组件类型不同,发送Intent有不同的机制:
- 针对Activity,Context.startActivity()方法传递Intent,启动一个新的Activity,或者Activity.startActivityForResult()方法启动新的Activity做完事情后返回到本Activity来;
- 针对Service,Context.startService()方法,用于创建一个Service或者传递给已经运行Service一个指令,于此类似,Context.bindService()建立当前组件和Service之间的连接,可选的,如果该Service未运行,可以创建新的实例;
- 针对Broadcast Receiver,可通过:Context.sendBroadcast()、Context.sendOrderedBroadcast()或者Context.sendStickyBroadcast()方法发送Intent给所有感兴趣的broadcast receiver。
在自己应用中,从系统图库中取图片,然后截取其中一部分,再返回到自己应用中。这是很多有关图片的应用需要的功能。
写了一个示例,上来就是个大按钮,连布局都不要了。最终,用选取图片中的一部分作为按钮的背景。
这样的场景:OA中的报销审批。如果老板公务缠身,经常出差,员工经常会抱怨得不到及时的报销审批。因此类似审批性质的需求在移动OA中很常用。
下面用这样的场景演示一下Android的通知的使用。
写了个简单的Activity,按按钮,就产生一个通知,并且有声音提示。
下拉通知栏:
找到一个软件(Input Director),可以让两台电脑共享一套键盘鼠标。就像电脑使用多屏幕一样。和多屏幕的不同在于是两台物理上独立的电脑,性能上要好,另外可以是不同的系统,比如一个Windows7,一个Windows XP。
基本原理是,分别在两台电脑上安装软件,一个是服务器端(使用它的鼠标和键盘),一个是客户端。都跑起来之后,比如只要鼠标移出服务器端屏幕右侧,就会自动出现在客户端机器屏幕的左侧,这时键盘也变成在客户端上生效。
可以有多个客户端。这样可同时使用更多的电脑工作。下面是我的工作台:
中间的Thinkpad和右侧的屏幕组成双屏工作台,其中左侧屏幕运行ubuntu虚拟机。共享鼠标是Thinkpad和右侧的hp笔记本,它们共用Thinkpad的键盘和鼠标。本文就是通过thinkpad上的键盘和鼠标,使用右侧的hp笔记本写的。