Android 4.4 以上添加系统信息数据

在Android4.4之前的版本,往短信箱插入信息很方便,所以这个对用户来说很有威胁的漏洞,在Android4.4得到了修复。Android4.4中只有手机默认的消息App才能处理和短信相关的操作,而手机默认的消息App一般就是手机里自带的官方App,当然用户可以在设置里面,手动地将自己信任的消息App设置为默认App,总的来说,短信的操作控制权掌握到用户自己的手中。


让你的应用成为默认短信

在Android 4.4上,只有一个应用能接收到新增的SMS_DELIVER_ACTION intent,这个intent是当系统接收到新短信时用来发送广播的。哪个应用接收这个广播取决于用户在系统设置里选择了哪个应用作为默认短信应用。同样的,也只有默认的短信应用能在系统接收到新彩信的时候接收到Android 4.4新增加的WAP_PUSH_DELIVER_ACTION intent。

其他只想读取新信息的应用可以接收SMS_RECEIVED_ACTION广播,这个广播也是系统接收到新短信时发送的。但是只有接收到SMS_DELIVER_ACTION的应用(用户指定的默认短信应用)可以写入由android.provider.Telephony类和子类定义的SMS Provider。因此,尽快升级你的短信应用让它可以成为默认短信应用是很重要的,因为就算你现有的应用不会在Android 4.4的设备上crash,但它尝试写入SMS Provider的时候会在没有提示的情况下失败。

为了让你的应用在系统设置中作为一个可选的默认短信应用,你的manifest文件必须声明一些特定的内容。所以你必须为你的应用更新以下内容:

  • 在一个broadcast receiver中包含一个SMS_DELIVER_ACTION("android.provider.Telephony.SMS_DELIVER")的intent filter。这个broadcast receiver同样需要BROADCAST_SMS权限。

    这让你的应用可以直接接收到进来的短信。

  • 在一个broadcast receiver包含一个WAP_PUSH_DELIVER_ACTION("android.provider.Telephony.WAP_PUSH_DELIVER")的intent filter,MIME类型是"application/vnd.wap.mms-message"。这个broadcast receiver同样需要BROADCAST_WAP_PUSH权限。

    这让你的应用可以直接接收到进来的彩信。

  • 在你用来发送新信息的activity中包含一个ACTION_SENDTO("android.intent.action.SENDTO")的intent filter,schemas为sms:, smsto:, mms:, 和mmsto:。

    这让你的应用可以接收到其他想发送信息的应用请求的intent。

  • 在一个service里面包含一个ACTION_RESPONSE_VIA_MESSAGE("android.intent.action.RESPOND_VIA_MESSAGE")的intent filter,schemas是sms:, smsto:, mms:, 和 mmsto:。这个service同样需要SEND_RESPOND_VIA_MESSAGE权限。

    这让用户在来电的时候用你的应用进行即时的短信息回复。

例: Demo工程

manifest文件



    
    
    

    
    
        
            
                

                

                
                
                

                
                

                
                
                
                
                

            
        

        
        
        
            
                
            
        

        
        
            
                

                
            
        

        
        
            
                

                

                
                
                
                
            
        
        
    





MainActivity.java

package tina.messagebox;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Telephony;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.method.MovementMethod;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.text.SimpleDateFormat;
import java.util.Date;


public class MainActivity extends ActionBarActivity {
    private String defaultSmsPkg;
    private String mySmsPkg;
    private TextView mMessageView=null;
    private EditText mPhoneNumber=null;
    private EditText mMsg=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPhoneNumber=(EditText)findViewById(R.id.editText);
        mMsg=(EditText)findViewById(R.id.editText2);
        mMessageView=(TextView)findViewById(R.id.textView3);
        mMessageView.setMovementMethod(ScrollingMovementMethod.getInstance()); //设置滚动
        defaultSmsPkg= Telephony.Sms.getDefaultSmsPackage(this);
        mySmsPkg= this.getPackageName();

        if(!defaultSmsPkg.equals(mySmsPkg)){
//            如果这个App不是默认的Sms App,则修改成默认的SMS APP
//            因为从Android 4.4开始,只有默认的SMS APP才能对SMS数据库进行处理
            Intent intent=new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
            intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,mySmsPkg);
            startActivity(intent);
        }

        Button button=(Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mySmsPkg.equals(Telephony.Sms.getDefaultSmsPackage(MainActivity.this))){
                    if(mPhoneNumber.getText().toString().isEmpty()){
                        Toast.makeText(MainActivity.this,"Phone number cannot be empty!",Toast.LENGTH_LONG).show();
                        return;
                    }
                    if(mMsg.getText().toString().isEmpty()){
                        Toast.makeText(MainActivity.this,"Message cannot be empty!",Toast.LENGTH_LONG).show();
                        return;
                    }
                    System.out.println("My App is default SMS App.");
                    //        对短信数据库进行处理
                    ContentResolver resolver=getContentResolver();

                    ContentValues values=new ContentValues();
                    values.put(Telephony.Sms.ADDRESS,mPhoneNumber.getText().toString());
                    values.put(Telephony.Sms.DATE, System.currentTimeMillis());
                    long dateSent=System.currentTimeMillis()-5000;
                    values.put(Telephony.Sms.DATE_SENT,dateSent);
                    values.put(Telephony.Sms.READ,false);
                    values.put(Telephony.Sms.SEEN,false);
                    values.put(Telephony.Sms.STATUS, Telephony.Sms.STATUS_COMPLETE);
                    values.put(Telephony.Sms.BODY, mMsg.getText().toString());
                    values.put(Telephony.Sms.TYPE, Telephony.Sms.MESSAGE_TYPE_INBOX);

                    Uri uri=resolver.insert(Telephony.Sms.CONTENT_URI,values);
                    if(uri!=null){
                        long uriId= ContentUris.parseId(uri);
                        System.out.println("uriId "+uriId);
                    }

                    Toast.makeText(MainActivity.this, "Insert a short Message.",
                            Toast.LENGTH_LONG).show();

//            对短信数据库处理结束后,恢复原来的默认SMS APP
                    Intent intent=new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                    intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,defaultSmsPkg);
                    startActivity(intent);
                    System.out.println("Recover default SMS App");

//                    打印出收件箱里的最新5条短信
                    Cursor cursor=getContentResolver().query(Telephony.Sms.CONTENT_URI,null,null,null,null);
                    String msg="";
                    while ((cursor.moveToNext()) &&
                            (cursor.getPosition()<5)){
                        int dateColumn=cursor.getColumnIndex("date");
                        int phoneColumn=cursor.getColumnIndex("address");
                        int smsColumn=cursor.getColumnIndex("body");

                        System.out.println("count "+cursor.getCount()+" position "+cursor.getPosition());
//                        把从短信中获取的时间戳换成一定格式的时间
                        SimpleDateFormat sfd=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        Date date=new Date(Long.parseLong(cursor.getString(dateColumn)));
                        String time=sfd.format(date);
                        msg=msg+time+" "+cursor.getString(phoneColumn)+":"+cursor.getString(smsColumn)+"\n";
                        mMessageView.setText(msg);
                    }

                }
                else{
                    Toast.makeText(MainActivity.this,"Sorry,the App is not default Sms App.",
                            Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

MmsReceiver.java

package tina.messagebox;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Created by Tina on 2015/8/11.
 */
public class MmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}

SmsReceiver.java

package tina.messagebox;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Created by Tina on 2015/8/11.
 */
public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}

SmsSendService.java

package tina.messagebox;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class SmsSendService extends Service {
    public SmsSendService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return null;
    }
}


效果如下:
Android 4.4 以上添加系统信息数据_第1张图片


你可能感兴趣的:(测试工具开发,Android,Studio)