精华内容
下载资源
问答
  • xposed伪造收到短信
    千次阅读
    2018-03-19 11:27:22

    Android 4.4 之后,开发者不能直接往短信数据库添加短信了,只有系统默认的短信应用才能在收件箱中添加短信,除非将自己的应用设置为默认短信应用,当这种方法不太实用,因为没有那个用户愿意修改自己的默认短信应用,即便是临时的也不靠谱。爬了一堆坑之后勉强找到一个行之有效的方法。

    思路

    在不改变默认短信的情况下,通过发送广播,告诉短信应用收到短信了,然后再通过xposed劫持短信内容intent里的参数,将参数修改为系统接收到短信时的参数格式,这样便能成功伪造短信了。当然,你也可以直接在发送广播时将系统接收到短信时的参数格式带进去,但这样得事先编辑好参数,而且参数内容会非常长,很麻烦,尤其是在终端直接发送广播时,这种方法就不适用了。

    发送广播

    下面开始具体的过程

    首先,发送广播必须通过命令行来发送,直接通过代码会出现没有权限的错误,并且通过命令行发送前,必须先输入“su”来获取root权限,否则短信会接收不到广播

    am broadcast -a android.provider.Telephony.SMS_DELIVER -n com.android.messaging/.receiver.SmsDeliverReceiver  //后面接具体参数

    我这里是先发送广播给SmsDeliverReceiver 类,因为短信最先接收到广播的就是这个类,然后才会发送给 receiver.SmsReceiver 类。参数有三个:sender、receiver、message,参数名可以自己定义,分别代表发送人手机号,接收人手机号和短信内容。

    xposed劫持

    finalClass aClass = XposedHelpers.findClass(
    
    "com.android.messaging.receiver.SmsReceiver", lpparam.classLoader);
    
    XposedBridge.hookAllMethods(aClass,"deliverSmsIntent",newXC_MethodHook() {
    
    @Override
    
    protected voidbeforeHookedMethod(MethodHookParam param)throwsThrowable {
    
    super.beforeHookedMethod(param);
    
    Log.e("hock_sms","hookAllMethods--------开始劫持接收到的短信");
    
    Intent it = (Intent) param.args[1];
    
    byte[] pdu =new byte[0];
    
    try{
    
    String sender =null;
    
    try{
    
    sender = it.getStringExtra("sender");
    
    }catch(Exception e) {
    
    e.printStackTrace();
    
    }
    
    String receiver =null;
    
    try{
    
    receiver = it.getStringExtra("receiver");
    
    }catch(Exception e) {
    
    e.printStackTrace();
    
    }
    
    String message =null;
    
    try{
    
    message = it.getStringExtra("message");
    
    }catch(Exception e) {
    
    return;
    
    }
    
    pdu = SmsUtils.createPduSms(sender, receiver, message);//将参数转换为pdu byte数组
    
    }catch(Exception e) {
    
    e.printStackTrace();
    
    }
    
    Intent intent =newIntent();
    
    intent.setAction(ACTION);
    
    Bundle bundle =newBundle();
    
    byte[][] b =new byte[1][1];
    
    b[0] = pdu;
    
    bundle.putString("format","3gpp");
    
    bundle.putSerializable("pdus", b);
    
    bundle.putString("slot","0");
    
    bundle.putString("phone","0");
    
    bundle.putString("subscription","2");
    
    intent.putExtras(bundle);
    
    param.args[1] = intent;
    
    }
    
    });

    短信的参数中 "format","slot","phone","subscription" 一般没什么变化,具体作用没细究,可以写死。而最重要的一个参数便是 "pdus",它是一个二维byte数组,其中每个数组代表一条短信,pdus里包含一个或多个pdu byte数组。伪造短信最核心的就是如何将发送人、接收人和短信内容转化成固定格式的byte数组了,直接采用getByte() 方法是行不通的,必须采用特定格式的方法才行。转化方式如下:

    public static byte[] createPduSms(String sender,String receiver, String body) {
    
    //Source: http://stackoverflow.com/a/12338541
    
    //Source: http://blog.dev001.net/post/14085892020/android-generate-incoming-sms-from-within-your-app
    
    sender =phoneTpye(sender);
    
    receiver =phoneTpye(receiver);
    
    byte[] pdu =null;
    
    byte[] scBytes = PhoneNumberUtils
    
    .networkPortionToCalledPartyBCD(receiver);
    
    byte[] senderBytes = PhoneNumberUtils
    
    .networkPortionToCalledPartyBCD(sender);
    
    intlsmcs = scBytes.length;
    
    byte[] dateBytes =new byte[7];
    
    Calendar calendar =newGregorianCalendar();
    
    dateBytes[0] =reverseByte((byte) (calendar.get(Calendar.YEAR)));
    
    dateBytes[1] =reverseByte((byte) (calendar.get(Calendar.MONTH) +1));
    
    dateBytes[2] =reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH)));
    
    dateBytes[3] =reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY)));
    
    dateBytes[4] =reverseByte((byte) (calendar.get(Calendar.MINUTE)));
    
    dateBytes[5] =reverseByte((byte) (calendar.get(Calendar.SECOND)));
    
    dateBytes[6] =reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar
    
    .get(Calendar.DST_OFFSET)) / (60*1000*15)));
    
    try{
    
    ByteArrayOutputStream bo =newByteArrayOutputStream();
    
    bo.write(lsmcs);
    
    bo.write(scBytes);
    
    bo.write(0x04);
    
    bo.write((byte) sender.length());
    
    bo.write(senderBytes);
    
    bo.write(0x00);
    
    try{
    
    String sReflectedClassName ="com.android.internal.telephony.GsmAlphabet";
    
    Class cReflectedNFCExtras = Class.forName(sReflectedClassName);
    
    Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod("stringToGsm7BitPacked",newClass[] { String.class});
    
    stringToGsm7BitPacked.setAccessible(true);
    
    byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null, body);
    
    bo.write(0x00);// encoding: 0 for default 7bit
    
    bo.write(dateBytes);
    
    bo.write(bodybytes);
    
    }catch(Exception e) {
    
    try{
    
    // try UCS-2
    
    byte[] bodybytes =encodeUCS2(body,null);
    
    bo.write(0x08);// encoding: 0x08 (GSM_UCS2) for UCS-2
    
    bo.write(dateBytes);
    
    bo.write(bodybytes);
    
    }catch(UnsupportedEncodingException uex) {
    
    Log.e(TAG, String.format("String '%s' encode unknow", body));
    
    }
    
    }
    
    pdu = bo.toByteArray();
    
    }catch(IOException e) {
    
    }
    
    returnpdu;
    
    }
    
    private static bytereverseByte(byteb) {
    
    return(byte) ((b &0xF0) >>4| (b &0x0F) <<4);
    
    }
    private staticString phoneTpye(String phone){
    
    if(TextUtils.isEmpty(phone)){
    
        return"00000000000";
    
        }
    
    returnphone.length()==11?"+86"+phone:phone;
    
    }
    private static byte[] encodeUCS2(String message,byte[] header)
    
    throwsUnsupportedEncodingException {
    
    byte[] userData, textPart;
    
    textPart = message.getBytes("utf-16be");
    
    if(header !=null) {
    
    // Need 1 byte for UDHL
    
    userData =new byte[header.length+ textPart.length+1];
    
    userData[0] = (byte)header.length;
    
    System.arraycopy(header,0, userData,1, header.length);
    
    System.arraycopy(textPart,0, userData, header.length+1, textPart.length);
    
        }
    
    else{
    
    userData = textPart;
    
        }
    
    byte[] ret =new byte[userData.length+1];
    
    ret[0] = (byte) (userData.length&0xff);
    
    System.arraycopy(userData,0, ret,1, userData.length);
    
    returnret;
    
    }

    具体怎么实现的我就不多说了,直接套用就行,只要调用createPduSms() 就可以成功转化,其他几个方法只是辅助方法而已。

    结束

    到此,便可以成功伪造短信了,插件安装重启手机后,就可以通过在终端发送广播或者在应用中通过命令行发送广播就可以实现伪造接收到短信了。



    更多相关内容
  • 原理就是通过Android的ContentProvider组件间接访问系统的短信数据库,获取所有短信内容。下面来演示一下。  布局很简单,如下:   代码如下: public class MainActivity extends Activity { List<Message> ...
  • Android手机

    千次阅读 2021-05-26 11:40:48
    Android手机为例,如何查看/更改短信中心号码在上述的几个情况之中,第一种现象比较普遍。许多用户接收不到信息大多也和短信中心号码有关。在Symbian系统手机,以及Windows Mobile系统机型当中,相对来说还是比较...

    Android手机为例,如何查看/更改短信中心号码

    在上述的几个情况之中,第一种现象比较普遍。许多用户接收不到信息大多也和短信中心号码有关。在Symbian系统手机,以及Windows Mobile系统机型当中,相对来说还是比较容易的就可以找到关于短信中心号码的设置项,在此这两个系统我们也不需要多说。主要讲一下目前越来越火热的Android系统手机,许多用户对它都比较陌生,那么究竟该怎么样去设置Android手机的短信中心号码呢?不妨根据下面的步骤设置一下。

    1,输入“*#*#4636#*#*”

    进入拨号界面,输入引号中的“*#*#4636#*#*”之后,就会自动进入手机测试(工程)模式。共有手机信息,电池信息,电池使用记录,使用情况统计数据,以及WIFI information(无线网络情况)这五个选项。有的手机可能是英文,但是位置一般都相对应,可以参考截图中内容。

    b5836056fdc1cbf903cf91baf406923d.png

    输入*#*#4636#*#*后进入手机信息

    2,找到SMSC后点击刷新

    进入工程模式后点击手机信息,你能够随后看到关于手机的各种信息,包括现在电话号码,当前网络等等。我们需要做的是拉到屏幕的最下方,会有一个标有“SMSC”的名称,后面为一个空白的输入框,这时你点击一下“刷新”按钮,空白框中就会出现当前你手机的短信中心号码。

    5ce7b6106aff39f05cd5417ab0750704.png

    找到SMSC后并点击刷新按钮

    3,显示短信中心号码/如何更改

    正如图中所示,13800100500是北京移动的短信中心号码。如果你无法接收短信,或者是进入查看后发现短信中心号码不正确,这时你就需要更改相应的短信中心号码了。你可以点击输入框,把正确的号码输入在内,然后点击一下更新,就算是完成了对此号码的更改。

    244d95f11142645c5a65d58519ac8b23.png

    左图显示短信中心号码;右图为点击更新更改短信中心号码

    展开全文
  • 1.收到验证码短信后,自动提取短信中的验证码填写到相应输入框 2.可指定一个号码,只读取与他有关短信,避免提取来源错误 3.利用正则表达式,可匹配各种类型验证码 模块集成关键步骤   将auto_getcode_demo中src...
  • Android之修改短信程序

    万次阅读 热门讨论 2012-12-11 15:50:36
    今天搞了个小程序,可以修改你自己android手机的任何一条短信。 直接进入正题,先放两张效果图: 主界面就是四个按钮加一个显示短信的listview: xmlns:tools="http://schemas.and

    今天搞了个小程序,可以修改你自己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() {
    
    			@Override
    			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
    					long arg3) {
    				// TODO Auto-generated method stub
    				ChangeSMSWindow change = new ChangeSMSWindow(SMS.this, list.get(arg2).get(StaticValues.BODY).toString(),
    						(Long) list.get(arg2).get(StaticValues._ID));
    				change.setOkClick(new onOkClick() {
    					
    					@Override
    					public 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{
    
    		@Override
    		public void onClick(View v) {
    			// TODO Auto-generated method stub
    			if(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();
    	}
    
    	@Override
    	public int getCount() {
    		// TODO Auto-generated method stub
    		return list.size();
    	}
    
    	@Override
    	public Object getItem(int arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	@Override
    	public long getItemId(int arg0) {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    
    	@Override
    	public 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{
    
    		@Override
    		public void onClick(View v) {
    			// TODO Auto-generated method stub
    			if(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应用经常会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,通常,用户收到短信需要最小化应用去查看短信再填入验证码,必然比较麻烦,因此有必要能够自动获得下发的短信验证码...
  • 今天大部分时间都在解决一个问题,tester提交了一个bug:终端设备收到一条3GPP2 SMS短信,但是UI number显示的是unknown,如下图 第一感觉应该是PDU没有携带number造成的,原先就遇到过这个问题,收到的3GPP2的PDU...

    今天大部分时间都在解决一个问题,tester提交了一个bug:终端设备收到一条3GPP2 SMS短信,但是UI number显示的是unknown,如下图
    在这里插入图片描述
    第一感觉应该是PDU没有携带number造成的,原先就遇到过这个问题,收到的3GPP2的PDU如下:
    0000021002040903c69a469cdaa0a190060100088b0003200020017c21e980836a0c8e7b1c629c29808a71d27eec5e0b0543b4236a0c8e7a8a2c6d9ff862b6f0018af80480d35e7ac9480190017001ba8a1b5e7b384001880180023802128b42b7eb6a0c8e7a982b3842982ff84001c001828a18017b3847f84ff864ccb33842f80480d3184ac94c5d0c69cff862b6f002a00223169329b00306180925111344
    使用tool解析这个PDU后发现有number,如红色部分。
    在这里插入图片描述
    那就奇怪了,怎么PDU含有number但是,UI怎么不显示呢。马上check一下trace,发现从底层到UI显示因为sensitive信息不能泄露的原因,整个trace没有任何关于sms address的信息。从code检查看是否有针对number length的限制,也没有发现任何线索。这时候才发现没有trace或者log,很难解决任何问题。现在只有一个办法了,看看自己能否复现,如果能复现,那就添加在flow的各个部分添加trace好了。因为短信是网络发送的,只能使用一个work around的复现方法了,当终端设备收到任何短信后,将收到的短信PDU直接替换为上面的PDU即可。修改code后,问题能够复现,后面就是添加trace了,添加trace有一个小技巧,最好一次能够把flow的key point都添加trace,能够节省时间。在等build结束的过程中,对正常显示number的短信PDU也做了解析,居然发现了问题,正常显示number的PDU address是original address,而这个PDU是destination address,马上就猜到原因了,这条短信是收到的短信,address应该是original address(02),而现在是destination address,没有将address进行保存和传递(code中对收到的短信只传递original address)。后面从build好的load复测问题的log也证明了猜测。问题转给更底层,看看为什么传递的PDU不对,皮球就踢走了。
    整个复盘这个BUG,有几个调试BUG的感触:
    1 问题发生后,不用急着马上动手解决,最好能够猜测一下原因,之后进行验证,这样能够使自己能够更了解和熟悉code。
    2 尽快复现问题,如果能够复现问题,那离解决问题就不远了。
    3 如果是不同的owner复现不同的层,那最好在接口处添加trace,那谁解决问题就不用相互推诿,并且能够更快定位是哪层出现了问题。
    4 添加trace应该选择key flow和最关键的地方,开头结束一般也是需要的,如果对log的数量有限制,更应该如此。
    5 最好能够保留正常flow的log,问题发生后,如果分析问题没有方向,最好将fail的log和pass的log进行比对,这样可能发现问题发生的原因。
    6 对于曾经发生过的问题,复现方法,解决方法甚至如何发现root cause进行记录,如果后面发生类似的问题可以找一下曾经是否解决过类似的问题,是否有可以借鉴的地方。

    展开全文
  • 请将你的邮箱开启smtp服务(具体开启方法请在 google 百度一下 163 为smtp.163.com QQ 为smtp.qq.com) 由于代码中发送邮件开启了SSL加密,端口一般默认为465 ...如果读取不到短信,注意授权相关的权限
  • 我们收到任何短信后切勿随便打开短信内容里面的网址,点击短信里的链接后遭受财产损失,类似的事件经常看见媒体报道,短信有风险,打开需谨慎。我们都见识过***的网络手段有多高明,手机里的一条短信就能盗走你的账户。...
  • 会自动截取收到的某特定号码的短信中的第一串数字,一般验证短信中验证码就是其中的第一串数字…… 代码写得比较随意,不过注释挺全的。涉及到循环性多线程控制,多线程更改主线程UI,广播拦截短信,正则表达式等...
  • android 收到短信时,点亮屏幕
  • java发送短信

    2021-03-04 06:03:16
    java发送短信一般步骤一、在中国网建中注册用户:本程序是...二、修改短信签名:注册成功后登陆,用户登陆有首先要修改短信签名,因为中国网建中规定了,发送的短信如果没有正规的签名是不能成功发送的,提示性信...
  • 我们经常会收到各种类型的验证码...企业如何设计验证码短信内容 企业在产品系统中接入了手机短信验证码功能之后,用户输入手机号码然后点击“获取验证码”按钮,系统就会自动生成一条验证码,然后该验证码就会经由...
  • 获取当前短信内容或部分匹配内容

    千次阅读 2015-08-12 16:40:12
    要获取短信内容,首先需要用到ContentObserver这个类;顾名思义就是一个内容的观察者,当有内容变化是就会触发。 改写onchange方法,添加需要做的动作,就是当收到短信后的动作。 Pattern就是要判
  • 在CRM客户关系管理的众多手段里面,短信一直有着举足轻重的地位。假如能利用好短信的即时性、抵达率等优势...在修改内容之前,首要发送方,也就是商家或许企业要理解,发送此条短信的意图是什么?一般来说,不外乎以...
  • 个人收款码支付,本系统仅仅是适用于订单量较小的个人使用,系统有订单需要审核会收到短信和邮箱通知(需配置)Thinkphp 框架开发全开源无加密,支持二开。系统无需安装任何挂机软件,安全绿色无手续费。如果每天...
  • 会自动截取收到的某特定号码的短信中的第一串数字,一般验证短信中验证码就是其中的第一串数字…… 代码写得比较随意,不过注释挺全的。涉及到循环性多线程控制,多线程更改主线程UI,广播拦截短信,正则表达式等...
  • 一、在中国网建中注册用户:本程序是通过中国网建提供的SMS短信平台实现的,该平台新用户注册可以拥有免费5条普通短信和3条彩信,足够进行尝试和体验了。中国网建注册地址:二、...修改用户信息--->保存信息,如...
  • 只要你在互联网上注册过账号,绑定过手机,就一定会收到营销短信,而且这些短信都有一个特点——回复TD退订。 你可能尝试回复过TD,但你一定会发现,一点用都没有! 类似的还有「回复T退订」,当然,不管你回不回复...
  • 接上一篇:android 发送短信sendTextMessage()真机运行报错,退出,在申请SEND_SMS权限的情况下Android send SMS not working uid 。。。 重开一篇,完整讲述我这个半吊子的android 入门人员是怎么做出一个可以...
  • 个人收款码支付,本系统仅仅是适用于订单量较小的个人使用,系统有订单需要审核会收到短信和邮箱通知(需配置)Thinkphp 框架开发全开源无加密,支持二开。系统无需安装任何挂机软件,安全绿色无手续费。如果每天...
  •  // 由于短信数据库已经通过内容提供者暴露出来了 所以我们可以直接通过内容解析者操作数据库  Uri uri = Uri.parse("content://sms/inbox");  ContentValues values = new ContentValues();  values.put(...
  • 文章目录短信服务命令AT+CSMS 选择消息服务(在CDMA网络中无效)AT+CMGF 讯息格式AT+CSCA 服务中心地址(在CDMA网络中无效)AT+CPMS 首选消息存储AT+CMGL 列出短信AT+CMGD Delete MessageAT+CMGR 读短信AT+CMGS 发送...
  • 智能手机用户越来越多,但是智能手机用户也会遇到手机接收不到短信的现象出现,或者是短信会出现延迟接收。手机收不到短信怎么回事?遇到这样的情况,大家也不必着急,下面就来详细介绍下:手机收不到短信怎么回事问题...
  • 短信逻辑漏洞

    2021-09-04 13:12:49
    发送到爆破模块,修改POST请求内容 POST /registerform HTTP/1.1 Host: www.xxx.com.cn User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: application/json, text/...
  • 之前用的一个厂商的,提供了一个封装类就很容易发送短息,因此都是基于HTTP协议做的一个数据发送而已,接触阿里云的短信服务器后,发现阿里云还增加了非常多的参数,其中包括一些秘钥和签名的内容短信发送由于比较...
  • 用阿里云短信服务--发送短信demo

    千次阅读 2020-05-13 16:29:20
    ... 进入RAM 访问控制,新建用户...填写登录名称和显示名称,勾选编程访问(一定要勾选,不然没法通过API编程发送短信) 点击用户组名称 点击组员管理,添加组员,将刚才创建的用户添加到用户组中 ...
  • 手机收到8bit编码的短信无法显示android默认不支持8bit编码,8bit只是数据传输的一种方式,8bit编码并没有定义唯一的字符编码表来指明某个编码表示某个字符,所以没办法唯一去解析它代码可见framework/base/...
  • android_访问系统短信内容提供者

    千次阅读 2016-03-15 17:08:06
    使用内容解析者去访问系统短信内容提供者既然我们需要访问系统短信内容提供者, 首先我们就需要知道口令,还有uriMatcher,和数据库的表结构. 这些都是需要去系统的sms内容提供者里面找的到的(下面会截图出来)...
  • 这让诈骗分子通过监听短信内容获取电话号码变得困难重重,但道高一尺,魔高一丈,他们又发明了主动捕获用户电话号码的新手段。 手机SIM中有个识别码叫IMSI码(国际移动用户识别码),它能对移动手机用户进行区分,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,633
精华内容 11,853
关键字:

修改已收到的短信内容