[android] 12_获取短信内容用ListView显--并备份短信到xml--插入一条短信到系统并插入一条短信到系统短信应用

Android 4.0

获取短信内容用ListView显--并备份短信到xml--插入一条短信到系统短信应用


一、使用ContentProvider共享数据

ContentProvider类主要方法的作用:
1、public boolean onCreate()
该方法在ContentProvider创建后就会被调用, Android开机后, ContentProvider在其它应用第一次访问它时才会被创建。
2、public Uri insert(Uri uri, ContentValues values)
该方法用于供外部应用往ContentProvider添加数据。
3、public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于供外部应用从ContentProvider删除数据。
4、public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于供外部应用更新ContentProvider中的数据。
5、public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于供外部应用从ContentProvider中获取数据。
6、public String getType(Uri uri)
该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有person记录的Uricontent://cn.itcast.provider.personprovider/person,那么返回的MIME类型字符串应该为:vnd.android.cursor.dir/person”。如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id10person记录,Uricontent://cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:vnd.android.cursor.item/person”

二、使用ContentResolver操作ContentProvider中的数据

当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 提供了与ContentProvider类相同签名的四个方法:
1、public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
2、public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
3、public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
4、public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://cn.itcast.providers.personprovider/person/10”),那么将会对主机名为cn.itcast.providers.personproviderContentProvider进行操作,操作的数据为person表中id10的记录。

短信类型:type

1:->发进来的

2:>发出去的短信

sqlite中存储日期为long的值

一、读取短信内容

1、短信存放的位置

2、去这里aosp_jb422\packages\providers\TelephonyProvider,查看manifest.xml文件

    可以查看到它的

 <provider android:name="SmsProvider"
      android:authorities="sms"
      android:multiprocess="true"
      android:exported="true"
      android:readPermission="android.permission.READ_SMS"
      android:writePermission="android.permission.WRITE_SMS" />
3、然后在aosp_jb422\packages\providers\TelephonyProvider\src\com\android\providers\telephony找到SmsProvider.java
     这个就是短信的内容提供者。
 
private static final int SMS_ALL = 0;
private static final int SMS_ALL_ID = 1;
private static final int SMS_INBOX = 2;
private static final int SMS_INBOX_ID = 3;
private static final int SMS_SENT = 4;
private static final int SMS_SENT_ID = 5;
private static final int SMS_DRAFT = 6;
private static final int SMS_DRAFT_ID = 7;
private static final int SMS_OUTBOX = 8;
private static final int SMS_OUTBOX_ID = 9;
private static final int SMS_CONVERSATIONS = 10;
private static final int SMS_CONVERSATIONS_ID = 11;
private static final int SMS_RAW_MESSAGE = 15;
private static final int SMS_ATTACHMENT = 16;
private static final int SMS_ATTACHMENT_ID = 17;
private static final int SMS_NEW_THREAD_ID = 18;
private static final int SMS_QUERY_THREAD_ID = 19;
private static final int SMS_STATUS_ID = 20;
private static final int SMS_STATUS_PENDING = 21;
private static final int SMS_ALL_ICC = 22;
private static final int SMS_ICC = 23;
private static final int SMS_FAILED = 24;
private static final int SMS_FAILED_ID = 25;
private static final int SMS_QUEUED = 26;
private static final int SMS_UNDELIVERED = 27;
 
private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 
static {
    sURLMatcher.addURI("sms", null, SMS_ALL);  //不加什么,null,表示获取所有的短信
    sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
    sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
    sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
    sURLMatcher.addURI("sms", "sent", SMS_SENT);
    sURLMatcher.addURI("sms", "sent/#", SMS_SENT_ID);
    sURLMatcher.addURI("sms", "draft", SMS_DRAFT);
    sURLMatcher.addURI("sms", "draft/#", SMS_DRAFT_ID);
    sURLMatcher.addURI("sms", "outbox", SMS_OUTBOX);
    sURLMatcher.addURI("sms", "outbox/#", SMS_OUTBOX_ID);
    sURLMatcher.addURI("sms", "undelivered", SMS_UNDELIVERED);
    sURLMatcher.addURI("sms", "failed", SMS_FAILED);
    sURLMatcher.addURI("sms", "failed/#", SMS_FAILED_ID);
    sURLMatcher.addURI("sms", "queued", SMS_QUEUED);
    sURLMatcher.addURI("sms", "conversations", SMS_CONVERSATIONS);
    sURLMatcher.addURI("sms", "conversations/*", SMS_CONVERSATIONS_ID);
    sURLMatcher.addURI("sms", "raw", SMS_RAW_MESSAGE);
    sURLMatcher.addURI("sms", "attachments", SMS_ATTACHMENT);
    sURLMatcher.addURI("sms", "attachments/#", SMS_ATTACHMENT_ID);
    sURLMatcher.addURI("sms", "threadID", SMS_NEW_THREAD_ID);
    sURLMatcher.addURI("sms", "threadID/*", SMS_QUERY_THREAD_ID);
    sURLMatcher.addURI("sms", "status/#", SMS_STATUS_ID);
    sURLMatcher.addURI("sms", "sr_pending", SMS_STATUS_PENDING);
    sURLMatcher.addURI("sms", "icc", SMS_ALL_ICC);
    sURLMatcher.addURI("sms", "icc/#", SMS_ICC);
 
    //we keep these for not breaking old applications
    sURLMatcher.addURI("sms", "sim", SMS_ALL_ICC);
    sURLMatcher.addURI("sms", "sim/#", SMS_ICC);
    sConversationProjectionMap.put(Sms.Conversations.SNIPPET,
        "sms.body AS snippet");
    sConversationProjectionMap.put(Sms.Conversations.THREAD_ID,
        "sms.thread_id AS thread_id");
    sConversationProjectionMap.put(Sms.Conversations.MESSAGE_COUNT,
        "groups.msg_count AS msg_count");
    sConversationProjectionMap.put("delta", null);
}

4、编写程序查看获取短信内容 (需要权限)

// 1、获取内容提供者
ContentResolver resolver = this.getContentResolver();
// 2、通过系统短信的ContentProvider获取系统的短信
Uri uri= Uri.parse("content://sms");
Cursor cursor = resolver.query(uri, nullnullnullnull);
// 参数二:projection 选择的列,如果为null,则返回所有列
while (cursor.moveToNext()) {
    Log.i(TAG"取到短信了");
    String address = cursor.getString(cursor.getColumnIndex("address"));// 发件人
    long date = cursor.getLong(cursor.getColumnIndex("date"));// 发送日期
//   type = cursor.getType(cursor.getColumnIndex("type"));
// 信息的类型:1表示接收,0表示发送出去的(API level 11 (current min is 8): )
    String subject = cursor.getString(cursor.getColumnIndex("subject"));
    String body = cursor.getString(cursor.getColumnIndex("body"));
    SmsInfo smsInfo = new SmsInfo(address, date, subject, body);
    listSmsInfos.add(smsInfo);
}

5、并用ListView给展示出来

 

二、备份短信到xml中

将查看到的短信,利用XmlSerializable将短信写到xml文件中去。

--------------------------

/**
 * 2、备份短信到xml中
 * 
 * @param view
 */
public void backupSms(View view) {
    try {
        readSmss();
        SmsUtils.backupsms(listSmsInfos);
        Toast.makeText(this, "备份短信成功~~~", 0).show();
    } catch (Exception e) {
        Toast.makeText(this, "备份短信失败!!!", 0).show();
        e.printStackTrace();
    }
}
------------------------
/**
     * 从系统读取短信加到list中去
     */
    private void readSmss() {
        listSmsInfos = new ArrayList<SmsInfo>();
        // 1、获取内容提供者
        ContentResolver resolver = this.getContentResolver();
        // 2、通过系统短信的ContentProvider获取系统的短信
        Uri uri= Uri.parse("content://sms");
        Cursor cursor = resolver.query(uri, nullnullnullnull);
        // 参数二:projection 选择的列,如果为null,则返回所有列
        while (cursor.moveToNext()) {
            Log.i(TAG"取到短信了");
            String address = cursor.getString(cursor.getColumnIndex("address"));// 发件人
            long date = cursor.getLong(cursor.getColumnIndex("date"));// 发送日期
//            int type = cursor.getType(cursor.getColumnIndex("type"));// 信息的类型:1表示接收,0表示发送出去的(API level 11 (current min is 8): )
            String subject = cursor.getString(cursor.getColumnIndex("subject"));
            String body = cursor.getString(cursor.getColumnIndex("body"));
            SmsInfo smsInfo = new SmsInfo(address, date, subject, body);
            listSmsInfos.add(smsInfo);
        }
    }
---------------------------------
public class SmsUtils {
    /**
     * 备份短信到xml中去
     * 
     * @param listsSmsInfos
     * @throws Exception
     */
    public static void backupsms(List<SmsInfo> listsSmsInfos) throws Exception {
        String storageState = Environment.getExternalStorageState();// 检查sdcard的状态
        System.out.println("sdcard状态:" + storageState);
        if (!Environment.MEDIA_MOUNTED.equals(storageState)) {
            System.out.println("sdcard状态:" + storageState);
            throw new Exception("SDcard没有准备好。。。");
        }
        // 1,初始化一个xml文件的序列化器
        XmlSerializer xSerializer = Xml.newSerializer();
        // 2.初始化序列器参数
        File file = new File(Environment.getExternalStorageDirectory(),
                "backup.xml");
        FileOutputStream fos = new FileOutputStream(file);
        xSerializer.setOutput(fos, "utf-8");
        // 3.开始写xml文件.
        xSerializer.startDocument("utf-8"true);
        xSerializer.startTag(null"smss");
        for (SmsInfo smsInfo : listsSmsInfos) {
            xSerializer.startTag(null"sms");
            xSerializer.startTag(null"body");
            xSerializer.text("</body>" + smsInfo.getBody());
            xSerializer.endTag(null"body");
            xSerializer.startTag(null"address");
            xSerializer.text(smsInfo.getAddress());
            xSerializer.endTag(null"address");
            xSerializer.startTag(null"date");
            xSerializer.text(String.valueOf(smsInfo.getDate()));
            xSerializer.endTag(null"date");
            xSerializer.endTag(null"sms");
        }
        xSerializer.endTag(null"smss");
        xSerializer.endDocument();
        fos.close();
    }
}

三、插入一条短信到系统短信应用中

插入一条记录到系统短信;插入到系统短信应用

    /**
     * 插入一条记录到系统短信应用
     * 
     * @param view
     */
    public void click(View view) {
        ContentResolver resolver = this.getContentResolver();
        ContentValues values = new ContentValues();
        values.put("address""10086");
        values.put("body""您好,您中了5千万!");
        values.put("date", System.currentTimeMillis());
        values.put("type", 1);
        Uri url = Uri.parse("content://sms");
        resolver.insert(url, values);
    }

布局的一点小技巧:

如果是相对布局:

android:layout_centerHorizontal="true" //水平居中

android:layout_centerVertical="true" //垂直居中

线性布局:

相对父窗体水平居中:android:layout_gravity="center_horizontal"

相对父窗体垂直居中:android:layout_gravity="center_vertical"