在Android中发送短信并将短信数据添加到SMS电话数据库

5
我尝试按照这个问题的方法编写程序来发送短信。虽然短信成功发送了,但是我的短信内容并没有保存到手机的短信数据库中,并且当我打开手机上的短信应用程序时,我也看不到我发送过的信息。
所以问题是:有没有办法在通过程序发送短信后将其保存到手机的短信数据库中?
2个回答

4

我找到了一个很好的例子,你可以在其中读取用户发送/接收的消息。

以下是代码:

这是安全方面的内容:

public class StringCryptor 
{
    private static final String CIPHER_ALGORITHM = "AES";
    private static final String RANDOM_GENERATOR_ALGORITHM = "SHA1PRNG";
    private static final int RANDOM_KEY_SIZE = 128;

    // Encrypts string and encode in Base64
    public static String encrypt( String password, String data ) throws Exception 
    {
        byte[] secretKey = generateKey( password.getBytes() );
        byte[] clear = data.getBytes();

        SecretKeySpec secretKeySpec = new SecretKeySpec( secretKey, CIPHER_ALGORITHM );
        Cipher cipher = Cipher.getInstance( CIPHER_ALGORITHM );
        cipher.init( Cipher.ENCRYPT_MODE, secretKeySpec );

        byte[] encrypted = cipher.doFinal( clear );
        String encryptedString = Base64.encodeToString( encrypted, Base64.DEFAULT );

        return encryptedString;
    }

    // Decrypts string encoded in Base64
    public static String decrypt( String password, String encryptedData ) throws Exception 
    {
        byte[] secretKey = generateKey( password.getBytes() );

        SecretKeySpec secretKeySpec = new SecretKeySpec( secretKey, CIPHER_ALGORITHM );
        Cipher cipher = Cipher.getInstance( CIPHER_ALGORITHM );
        cipher.init( Cipher.DECRYPT_MODE, secretKeySpec );

        byte[] encrypted = Base64.decode( encryptedData, Base64.DEFAULT );
        byte[] decrypted = cipher.doFinal( encrypted );

        return new String( decrypted );
    }

    public static byte[] generateKey( byte[] seed ) throws Exception
    {
        KeyGenerator keyGenerator = KeyGenerator.getInstance( CIPHER_ALGORITHM );
        SecureRandom secureRandom = SecureRandom.getInstance( RANDOM_GENERATOR_ALGORITHM );
        secureRandom.setSeed( seed );
        keyGenerator.init( RANDOM_KEY_SIZE, secureRandom );
        SecretKey secretKey = keyGenerator.generateKey();
        return secretKey.getEncoded();
    }
}

接下来,

当您收到任何消息时,以下是它的处理方式:

public class SmsReceiver extends BroadcastReceiver 
{

    public static final String SMS_EXTRA_NAME = "pdus";
    public static final String SMS_URI = "content://sms";

    public static final String ADDRESS = "address";
    public static final String PERSON = "person";
    public static final String DATE = "date";
    public static final String READ = "read";
    public static final String STATUS = "status";
    public static final String TYPE = "type";
    public static final String BODY = "body";
    public static final String SEEN = "seen";

    public static final int MESSAGE_TYPE_INBOX = 1;
    public static final int MESSAGE_TYPE_SENT = 2;

    public static final int MESSAGE_IS_NOT_READ = 0;
    public static final int MESSAGE_IS_READ = 1;

    public static final int MESSAGE_IS_NOT_SEEN = 0;
    public static final int MESSAGE_IS_SEEN = 1;

    // Change the password here or give a user possibility to change it
    public static final byte[] PASSWORD = new byte[]{ 0x20, 0x32, 0x34, 0x47, (byte) 0x84, 0x33, 0x58 };

    public void onReceive( Context context, Intent intent ) 
    {
        // Get SMS map from Intent
        Bundle extras = intent.getExtras();

        String messages = "";

        if ( extras != null )
        {
            // Get received SMS array
            Object[] smsExtra = (Object[]) extras.get( SMS_EXTRA_NAME );

            // Get ContentResolver object for pushing encrypted SMS to incoming folder
            ContentResolver contentResolver = context.getContentResolver();

            for ( int i = 0; i < smsExtra.length; ++i )
            {
                SmsMessage sms = SmsMessage.createFromPdu((byte[])smsExtra[i]);

                String body = sms.getMessageBody().toString();
                String address = sms.getOriginatingAddress();

                messages += "SMS from " + address + " :\n";                    
                messages += body + "\n";

                // Here you can add any your code to work with incoming SMS
                // I added encrypting of all received SMS 

                putSmsToDatabase( contentResolver, sms );
            }

            // Display SMS message
            Toast.makeText( context, messages, Toast.LENGTH_SHORT ).show();
        }

    }

保存数据的方法:

private void putSmsToDatabase( ContentResolver contentResolver, SmsMessage sms )
    {
        // Create SMS row
        ContentValues values = new ContentValues();
        values.put( ADDRESS, sms.getOriginatingAddress() );
        values.put( DATE, sms.getTimestampMillis() );
        values.put( READ, MESSAGE_IS_NOT_READ );
        values.put( STATUS, sms.getStatus() );
        values.put( TYPE, MESSAGE_TYPE_INBOX );
        values.put( SEEN, MESSAGE_IS_NOT_SEEN );
        try
        {
            String encryptedPassword = StringCryptor.encrypt( new String(PASSWORD), sms.getMessageBody().toString() ); 
            values.put( BODY, encryptedPassword );
        }
        catch ( Exception e ) 
        { 
            e.printStackTrace(); 
        }

        // Push row into the SMS table
        contentResolver.insert( Uri.parse( SMS_URI ), values );
    }

现在,要读取存储在数据库中的值,
public void onClick( View v ) 
{
    ContentResolver contentResolver = getContentResolver();
    Cursor cursor = contentResolver.query( Uri.parse( "content://sms/inbox" ), null, null, null, null);

    int indexBody = cursor.getColumnIndex( SmsReceiver.BODY );
    int indexAddr = cursor.getColumnIndex( SmsReceiver.ADDRESS );

    if ( indexBody < 0 || !cursor.moveToFirst() ) return;

    smsList.clear();

    do
    {
        String str = "Sender: " + cursor.getString( indexAddr ) + "\n" + cursor.getString( indexBody );
        smsList.add( str );
    }
    while( cursor.moveToNext() );


    ListView smsListView = (ListView) findViewById( R.id.SMSList );
    smsListView.setAdapter( new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, smsList) );
    smsListView.setOnItemClickListener( this );
}

基本上,在此情况下,当您点击刷新时,列表视图将更新为最新值。希望这回答了您的问题。

没问题,我只是分享了一些好的信息,很高兴能帮到你。 :) - mike20132013

2
您需要将消息存储到短信存储中:
    ContentValues values = new ContentValues();
    values.put("address", number);
    values.put("body", message);
    values.put("read", readState);
    values.put("date", dateTime);
    mActivity.getContentResolver().insert(Uri.parse("content://sms/sent"), values);

请注意,从Android 4.4开始,如果您的应用程序未注册为默认短信应用程序(请参见SMS Provider章节),则不支持此功能。
编辑:添加了缺少的右括号。

如果这种方法在4.4上不起作用,是否有其他方法将短信添加到数据库中? - Sergey Shustikov
不,你的应用程序必须在短信存储中注册为默认短信应用程序,才能插入/更新/删除短信。另外,请查看以下链接:http://android-developers.blogspot.de/2013/10/getting-your-sms-apps-ready-for-kitkat.html - Trinimon
我认为readState01,而dateTime是一个Date实例 :) 附:请查看这个链接:http://sermojohn.wordpress.com/2012/03/05/sms-content-providers-and-delivery-reports/ - Trinimon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接