导出手机中某个号码的短信或者是手机中全部的短信
需要用到异步处理。由于查询短信并写入文本是一个比较耗时的操作,因此需要开辟一个单独的线程来完成,使用一部任务来实现这一过程比较方便。
public class MainActivity extends ActionBarActivity {
final String SMS_URL_ALL = "content://sms/";
final String TAG = "EXPORT";
EditText edt_number;
Button btn_export;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edt_number = (EditText) findViewById(R.id.editText);
btn_export = (Button) findViewById(R.id.button1);
btn_export.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//异步执行
new AsyncTask<Integer, Integer, String>() {
private ProgressDialog dialog;
// ui显示
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
//当点击导出短信按钮的时候弹出一个对话框,提示正在进行导出短信
dialog = ProgressDialog.show(MainActivity.this, "",
"正在导出短信,请稍后。。。。");
super.onPreExecute();
}
// 后台执行
@Override
protected String doInBackground(Integer... params) {
// TODO Auto-generated method stub
String input_number = edt_number.getText().toString();
String result = "";
//判断得到的电话号码,如果没有任何电话号码,则所有的短信都导出
if(input_number.equals("")){
List<String> listnumber = getAllNumber();
for(String number : listnumber){
if(file_write("AllNumber.txt",get_sms(number))){
result += "号码" + number + "的所有短信已经导出到文件AllNumber.txt中\n";
}else{
result += "号码" + number + "的所有短信导出到文件失败\n";
}
}
}else{
//导出固定的电话的短信
if(file_write(input_number + ".txt",get_sms(input_number))){
result = "号码" + input_number + "的所有短信已经导出到文件" + input_number + ".txt中";
}else{
result = "号码" + input_number + "的所有短信导出到文件失败";
}
}
return result;
}
// 搜索完毕后,结果处理
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
dialog.dismiss();
new AlertDialog.Builder(MainActivity.this)
.setMessage(result).create().show();
/*Toast.makeText(getApplicationContext(), result, 1000).show(); Log.i("TAG", "XXX" + result);*/
super.onPostExecute(result);
}
}.execute(0);
}
});
}
指定号码短信获取。输入号码,提取出属于此号号码的所有短信。
private String get_sms(String number){
//定义了一个字符串变量(非线程安全)SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类。
//它允许格式化 (date -> text)、语法分析 (text -> date)和标准化。
StringBuilder sms_Builder = new StringBuilder();
//获取contentProvider 提供的数据
ContentResolver cr = getContentResolver();
String[] projection = new String[]{"_id","address","person","body","date","type"};
Uri uri = Uri.parse(SMS_URL_ALL);
Cursor cur = cr.query(uri, projection, "address like '%" + number + "'", null, "date desc");
if(cur.moveToFirst()){
String name;
String phoneNumber;
String smsbody;
String date;
String type;
do{
name = cur.getString(2);
phoneNumber = cur.getString(1);
smsbody = cur.getString(3);
if(smsbody == null)
smsbody = "";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//将字符串类型转换为长整形的十进制
Date d = new Date(Long.parseLong(cur.getString(4)));
date = dateFormat.format(d);
int typeId = cur.getInt(5);
if(typeId == 1){
type = "接受";
}else if(typeId == 2){
type = "发送";
}else{
type = "草稿";
}
//将字符串填充到sms_Builder中
sms_Builder.append(name + ",");
sms_Builder.append(phoneNumber + ",");
sms_Builder.append(smsbody + ",");
sms_Builder.append(date + ",") ;
sms_Builder.append(type);
sms_Builder.append("\n");
}while(cur.moveToNext());
}else{
sms_Builder.append("no result");
}
cur.close();
return sms_Builder.toString();
}
文本导出。将短息导出到sd卡中的某个文件中。
private boolean file_write(String filename,String content){
//判断sd卡是否可用
if(!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
return false;
}
String filepath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + filename;
File file = new File(filepath);
try {
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file,true);
fos.write(content.getBytes());
fos.close();
} catch (Exception e) {
// TODO: handle exception
Log.i(TAG, "file write w " + e.toString());
return false;
}
return true;
}
获取所有的短信号码。
private List<String> getAllNumber(){
List<String> list = new ArrayList<String>();
String address = "";
ContentResolver cr = getContentResolver();
String[] projection = new String[]{"_id","address","person","body","date","type"};
Uri uri = Uri.parse(SMS_URL_ALL);
Cursor cur = null;
try {
//使所有的号码都按照降序排列
cur = cr.query(uri, projection, null, null, "address desc");
if(cur.moveToFirst()){
do{
//得到cr的第二个内容
String tmpString = cur.getString(1);
//如果得到的地址为真,则将tmpString 复制给address
if(!address.equals(tmpString)){
address = tmpString;
list.add(tmpString);
}
}while(cur.moveToNext());
}
} catch (Exception e) {
// TODO: handle exception
Log.i(TAG, "getallnumber w" + e.toString());
}
cur.close();
return list;
}
需要申请权限。需要读取短信的权限以及在sd卡中创建文件和写入数据的权限。在AndroidMainfest.xml中申请这些权限:
<!--在sd卡中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<!--在sd卡中写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!--读取短信的权限 -->
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
最后运行程序。在编辑框中输入要导出的短信,然后点击导出短信。接着会弹出一个正在执行的对话框,执行完之后会在弹出一个对话框,显示某短信已经导出。然后在mnt/sdcard/下去寻找点好号码对应的.txt文件,在文件中就会看到导出的信息。
(参考android 编程兵书)