Android之修改短信程序
16lz
2021-01-26
今天搞了个小程序,可以修改你自己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;}}
<?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" />
大功告成,现在就完成需求了。
更多相关文章
- Android(安卓)SDK下载和更新失败的解决方法!!!
- 修改apk调用蓝牙无明确提示
- Android5.1.1-APK签名校验分析和修改源码绕过签名校验
- Android点划线自定义View
- android:Adapter中无法设置textview字体颜色(解决)
- Android(安卓)JWT 简单使用
- Android(安卓)2.2 Eclipse 源码工程 调试
- Android监听收到的短信
- Android(安卓)repo/git server 建立过程