今天搞了个小程序,可以修改你自己android手机的任何一条短信。

直接进入正题,先放两张效果图:




主界面就是四个按钮加一个显示短信的listview:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/linearlayout"    android:layout_width="match_parent"    android:layout_height="match_parent"     android:orientation="vertical"    ><LinearLayout     android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    >    <Button         android:id="@+id/btnAll"        android:layout_weight="1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="所有短信"        />    <Button         android:id="@+id/btnInbox"        android:layout_weight="1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="收件箱短信"        /></LinearLayout><LinearLayout     android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    >    <Button         android:id="@+id/btnSend"        android:layout_weight="1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="发件箱短信"        />    <Button         android:id="@+id/btnDraft"        android:layout_weight="1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="草稿箱短信"        /></LinearLayout>    <ListView         android:id="@+id/listview"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:clickable="true"        /></LinearLayout>

还有一个StaticValues类放置一些常量

package com.jackchan.sms;public class StaticValues {//android系统短信数据库的字段public static final String _ID = "_id";public static final String PERSON = "person";public static final String BODY = "body";public static final String ADDRESS = "address";public static final String DATE = "date";public static final String TYPE = "type";}

主类代码如下,重点在getSmsInPhone()这个方法,通过ContentResolver分别传入收件箱、发件箱、草稿的Uri获取你想要的字段,

sms相关的字段如下:

_id 一个自增字段,从1开始 ,每条短信_id都不一样,根据这个唯一性可以修改短信
thread_id 序号,同一发信人的id相同
address 发件人手机号码
person 联系人列表里的序号,陌生人为null
date 发件日期
protocol 协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read 是否阅读 0未读, 1已读
status 状态 -1接收,0 complete, 64 pending, 128 failed
type
ALL = 0;
INBOX = 1;
SENT = 2;
DRAFT = 3;
OUTBOX = 4;
FAILED = 5;
QUEUED = 6;

body 短信内容
service_center 短信服务中心号码编号
subject 短信的主题
reply_path_present TP-Reply-Path


package com.jackchan.sms;import java.sql.Date;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.jackchan.sms.ChangeSMSWindow.onOkClick;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.database.sqlite.SQLiteException;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.Button;import android.widget.ListView;public class SMS extends Activity {private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>(); //已发送信息列表private SMSAdapter adapter;private Button btnAll;private Button btnInbox;private Button btnSend;private Button btnDraft;public static String url;private ListView listView;private final String SMS_URI_ALL   = "content://sms/";      private final String SMS_URI_INBOX = "content://sms/inbox";    private final String SMS_URI_SEND  = "content://sms/sent";    private final String SMS_URI_DRAFT = "content://sms/draft";    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        initComponet();        setBtnClick();        url = SMS_URI_ALL;//默认获取全部短信        adapter = new SMSAdapter(this, getSmsInPhone());        listView.setAdapter(adapter);        listView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {// TODO Auto-generated method stubChangeSMSWindow change = new ChangeSMSWindow(SMS.this, list.get(arg2).get(StaticValues.BODY).toString(),(Long) list.get(arg2).get(StaticValues._ID));change.setOkClick(new onOkClick() {@Overridepublic void dataChange() {listChange();}});change.showAtLocation(listView,//LayoutInflater.from(context).inflate(R.layout.main, null), Gravity.CENTER_HORIZONTAL|Gravity.CENTER_VERTICAL, 0, 0);}        });    }    private void initComponet(){    listView = (ListView)findViewById(R.id.listview);        btnAll = (Button)findViewById(R.id.btnAll);        btnInbox = (Button)findViewById(R.id.btnInbox);        btnSend = (Button)findViewById(R.id.btnSend);        btnDraft = (Button)findViewById(R.id.btnDraft);    }        private void setBtnClick(){    btnAll.setOnClickListener(click);    btnInbox.setOnClickListener(click);    btnSend.setOnClickListener(click);    btnDraft.setOnClickListener(click);    }    /*     * listview数据发生改变     */    private void listChange(){    adapter.clearList();adapter.changeList(getSmsInPhone());adapter.notifyDataSetChanged();    }    private btnClick click = new btnClick();    private class btnClick implements OnClickListener{@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(v == btnAll){url = SMS_URI_ALL;}else if(v == btnInbox){url = SMS_URI_INBOX;}else if(v == btnSend){url = SMS_URI_SEND;}else if(v == btnDraft){url = SMS_URI_DRAFT;}listChange();}        }    /*     * 获取指定类型短信     */    public List<Map<String, Object>> getSmsInPhone()        {            try{                ContentResolver cr = getContentResolver();                String[] projection = new String[]{"_id", "address", "person",                         "body", "date", "type"};                Uri uri = Uri.parse(url);                Cursor cur = cr.query(uri, projection, null, null, "date desc");                       if (cur.moveToFirst()) {            long id;                String name;                     String phoneNumber;                           String smsbody;                    String date;                    String type;                                    int idColumn = cur.getColumnIndex(StaticValues._ID);                int nameColumn = cur.getColumnIndex(StaticValues.PERSON);                    int phoneNumberColumn = cur.getColumnIndex(StaticValues.ADDRESS);                    int smsbodyColumn = cur.getColumnIndex(StaticValues.BODY);                    int dateColumn = cur.getColumnIndex(StaticValues.DATE);                    int typeColumn = cur.getColumnIndex(StaticValues.TYPE);                                     do{                 id = cur.getLong(idColumn);                    name = cur.getString(nameColumn);                                     phoneNumber = cur.getString(phoneNumberColumn);                        smsbody = cur.getString(smsbodyColumn);                                                SimpleDateFormat dateFormat = new SimpleDateFormat(                                "yyyy-MM-dd hh:mm:ss");                        Date d = new Date(Long.parseLong(cur.getString(dateColumn)));                        date = dateFormat.format(d);                                                int typeId = cur.getInt(typeColumn);                        if(typeId == 1){                            type = "接收";                        } else if(typeId == 2){                            type = "发送";                        }else if(typeId == 3){                            type = "草稿";                        } else {                            type = "";                        }                    if(smsbody == null)                     smsbody = "";                    Map<String, Object> map = new HashMap<String, Object>();                    map.put(StaticValues._ID, id);                    map.put(StaticValues.PERSON, name);                    map.put(StaticValues.ADDRESS, phoneNumber);                    map.put(StaticValues.BODY, smsbody);                    map.put(StaticValues.DATE, date);                    map.put(StaticValues.TYPE, type);                    list.add(map);                }while(cur.moveToNext());                  cur.close();            }           } catch(SQLiteException ex) {                Log.d("SQLiteException in getSmsInPhone", ex.getMessage());            }            return list;        }   }

listview中item.xml的布局文件如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <TextView         android:id="@+id/person"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="姓名:"        /><TextView         android:id="@+id/address"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="地址:"        /><TextView         android:id="@+id/body"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="内容:"        /><TextView         android:id="@+id/date"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="日期:"        /><TextView         android:id="@+id/type"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="类型:"        /></LinearLayout>


然后还有一个类用来适配主界面的listview

package com.jackchan.sms;import java.util.List;import java.util.Map;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;public class SMSAdapter extends BaseAdapter{private Context context;//当前上下文内容private List<Map<String, Object>> list; //已发送信息列表private class ViewHolder{ TextView person;TextView address;TextView body;TextView date;TextView type;}public SMSAdapter(Context context, List<Map<String, Object>> list) {super();this.context = context;this.list = list;}public void changeList(List<Map<String, Object>> list){this.list = list;}public void clearList(){list.clear();}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if(convertView == null){viewHolder = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.item, null);viewHolder.person = (TextView)convertView.findViewById(R.id.person);viewHolder.address = (TextView)convertView.findViewById(R.id.address);viewHolder.body = (TextView)convertView.findViewById(R.id.body);viewHolder.date = (TextView)convertView.findViewById(R.id.date);viewHolder.type = (TextView)convertView.findViewById(R.id.type);convertView.setTag(viewHolder);}else{viewHolder = (ViewHolder)convertView.getTag();}//获取短信基本信息viewHolder.person.setText("姓名:" + list.get(position).get(StaticValues.PERSON));viewHolder.address.setText("号码:" + list.get(position).get(StaticValues.ADDRESS));viewHolder.body.setText("内容:" + list.get(position).get(StaticValues.BODY));viewHolder.date.setText("日期:" + list.get(position).get(StaticValues.DATE));viewHolder.type.setText("类型:" + list.get(position).get(StaticValues.TYPE));return convertView;}}


修改信息在一个弹出的popupwindow里实现,弹出窗口的布局文件dialog.xml如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:background="@drawable/bg_popupwindow"    android:orientation="vertical" >    <TextView         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="输入修改后的内容:"        android:textColor="#000000"        android:textSize="20sp"        /><EditText    android:id="@+id/edittext"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:selectAllOnFocus="true"    /><LinearLayout     android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    >    <Button        android:id="@+id/btnOk"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_weight="1"        android:text="确认"        />    <Button        android:id="@+id/btnCancel"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_weight="1"        android:text="取消"        /></LinearLayout></LinearLayout>

弹出界面背景bg_popupwindow.xml

<?xml version="1.0" encoding="utf-8"?><shape  xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="rectangle"  ><!-- android:shape="" 表示是圆角矩形还是椭圆等等 -->  <solid  android:color="#FFFF00"/>  <!-- 四个角的弧度 -->  <corners android:radius="4dip"/>  <!-- padding 表示内部空间距离背景图片内部边距 的距离 --></shape>

弹出界面实现代码

package com.jackchan.sms;import android.content.ContentValues;import android.content.Context;import android.net.Uri;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.PopupWindow;/* * 修改短信内容弹出框 * @author:jack chan */public class ChangeSMSWindow extends PopupWindow{private Context context;private EditText editText;private Button btnOk;private Button btnCancel;private ContentValues cv = new ContentValues(); //存放修改信息private String body = null;//短信内容private long id = -1;//短信编号public ChangeSMSWindow(Context context, String body, long id) {super(context);this.context = context;this.body = body;this.id = id;LayoutInflater inflater = LayoutInflater.from(context);View view = inflater.inflate(R.layout.dialog, null);setContentView(view);this.setFocusable(true);this.setOutsideTouchable(true);editText = (EditText)view.findViewById(R.id.edittext);btnOk = (Button)view.findViewById(R.id.btnOk);btnCancel = (Button)view.findViewById(R.id.btnCancel);this.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);this.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);editText.setText(body);btnClick click = new btnClick();btnOk.setOnClickListener(click);btnCancel.setOnClickListener(click);}private class btnClick implements OnClickListener{@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(v.getId() == R.id.btnOk){cv.put(StaticValues.BODY, editText.getText().toString());context.getContentResolver().update(Uri.parse(SMS.url), cv, StaticValues._ID + "=?", new String[]{id+""});if(okClick != null)okClick.dataChange();}if(isShowing())dismiss();}}public interface onOkClick{void dataChange();}private onOkClick okClick;public void setOkClick(onOkClick okClick) {this.okClick = okClick;}}

最后在Mainfiest里添加读写权限

<uses-permission android:name="android.permission.READ_SMS" /><uses-permission android:name="android.permission.WRITE_SMS" />

大功告成,现在就完成需求了。



更多相关文章

  1. Android(安卓)SDK下载和更新失败的解决方法!!!
  2. 修改apk调用蓝牙无明确提示
  3. Android5.1.1-APK签名校验分析和修改源码绕过签名校验
  4. Android点划线自定义View
  5. android:Adapter中无法设置textview字体颜色(解决)
  6. Android(安卓)JWT 简单使用
  7. Android(安卓)2.2 Eclipse 源码工程 调试
  8. Android监听收到的短信
  9. Android(安卓)repo/git server 建立过程

随机推荐

  1. Android应用开发揭秘 第一章
  2. Android使用NotificationManager进行消息
  3. Android Asynchronous Http Client-Andro
  4. Android中Drawable Resource学习
  5. Android 解决tools:replace=android:appC
  6. 优秀的android开源项目
  7. Android灭亡论之Firefox OS操作系统出现
  8. 代码虚拟的[小代码]在Android和PHP之间的
  9. 转载:Android 获取ROOT权限原理解析
  10. Android 深入解析用户界面(一)