Android监听手机短信

Android监听手机短信的方法有两种,分别为:

1、接受系统的短信广播:当手机收到新消息时,会发送一条广播,通过该广播就可以获取短信内容;

2、监听短信数据库:利用观察者模式监听短信数据库,当短信数据库改变时就可以触发观察者模式的onChange()方法,但是onChang回调或获取短信不是最新,以及获取重复短信问题。


sms主要结构:

  _id: 短信序号,如100

  thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的

  address: 发件人地址,即手机号,如+86138138000

  person: 发件人,如果发件人在通讯录中则为具体姓名,陌生人为null

  date: 日期,long型,如1346988516,可以对日期显示格式进行设置

  protocol: 协议0SMS_RPOTO短信,1MMS_PROTO彩信

  read: 是否阅读0未读,1已读

  status: 短信状态-1接收,0complete,64pending,128failed

  type: 短信类型1是接收到的,2是已发出

  body: 短信具体内容

  service_center:短信服务中心号码编号,如+8613800755500


第一种方式接收系统的短信广播: A、这种方式只对新收到的短消息有效,运行代码,并不会读取收件箱中已读或未读的消息,只有当收到新来的短消息时,才会执行onReceive()方法。

B、并且这个广播是有序广播,如果当别的程序先读取到了这个广播,然后拦截掉了个这个广播,你将接收不到。当然我们可以通过设置priority的数值,其实有时是不管用的,现在在一些定制的系统或是有安全软件的情况下,往往短消息都被截取到,并被干掉。

<uses-permission android:name="android.permission.RECEIVE_SMS" /> <!-- 接收短信权限 -->
<uses-permission android:name="android.permission.READ_SMS" /> <!-- 读取短信权限 -->

<receiver android:name="com.example.smslistenerdemo.SmsReceiver" >
            <intent-filter android:priority="2147483647" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
 </receiver>
public class SmsReceiver extends BroadcastReceiver {
//    private static MessageListener mMessageListener;

    private Context mContext;
    public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    public static final String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER";

    @Override
    public void onReceive(Context context, Intent intent) {
        this.mContext = context;
     
        Toast.makeText(context, "接收短信执行了.....", Toast.LENGTH_LONG).show();
        Log.e("日志:广播::onReceive", isOrderedBroadcast() + "");
        Log.e("日志:onReceive...", "-接收短信执行了......"+intent.getStringExtra("sele"));
        String action = intent.getAction();
        if (SMS_RECEIVED_ACTION.equals(action) || SMS_DELIVER_ACTION.equals(action) ) {
           
            Log.e("日志:onReceive。。。", "开始接收短信.....");
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                Object[] pdus = (Object[]) bundle.get("pdus");
                if (pdus != null && pdus.length > 0) {
                    SmsMessage[] messages = new SmsMessage[pdus.length];
                    for (int i = 0; i < pdus.length; i++) {
                        byte[] pdu = (byte[]) pdus[i];
                        messages[i] = SmsMessage.createFromPdu(pdu);
                    }
                    for (SmsMessage message : messages) {
                        String content = message.getMessageBody();// 得到短信内容
                        String sender = message.getOriginatingAddress();// 得到发信息的号码
                        Date date = new Date(message.getTimestampMillis());
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        format.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
                        String dateContent = format.format(date);

                    if ((sender.equals("8610086") || sender.equals(Constant.phone))){
                        Log.e("日志:短信时间::: ", format.format(date) + " ");
                        Log.e("日志:发信息的号码 ", sender + " ");
                        Log.e("日志:得到短信内容 ", content + " ");
                        this.abortBroadcast();// 中止
                    }

                    }
                }

            }
        }
    }
}

开启Service实现锁屏监听

在Activity中监听短信,当应用被放入后台或者屏幕锁定一段时间后就无法继续将短信内容上传服务器,所以需要启动一个Service,在Service中监听短信,就可以在锁屏后继续监听短信

要启动Service,首先需要在申请android.permission.FOREGROUND_SERVICE权限,该权限为普通权限,所以只要在AndroidManifest.xml中声明即可

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

之后还需要在AndroidManifest.xml中添加Service类对应的<service>标签,其中三条属性值的含义分别为:

android:name为pakagename+Service类名,pakagename可以省略;

android:enabled表示是否可以被系统实例化;

android:exported表示其它应用的组件是否可以唤醒service或者和这个service进行交互;

<service
  android:name=".MyService"
  android:enabled="true"
  android:exported="true"\>
public class SmsObserver extends ContentObserver {

    public Context mContext;
    public SmsHandler smsHandler;
    private static int id=0; //这里必须用静态的,防止程序多次意外初始化情况
    String _id;
    public SmsObserver(Context context, SmsHandler handler) {
        super(handler);
        this.mContext = context;
        this.smsHandler = handler;
    }
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);

        Log.i("日志:SmsObserver", "SmsObserver ------短信有改变------");
//        Cursor mCursor = mResolver.query(Uri.parse("content://sms/inbox"),
//                null, null, null, "date desc");
        Cursor mCursor = mContext.getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, "date desc");

        if (mCursor == null) {
            return;
        } else {
            if (mCursor.moveToFirst()){
                SmsInfo _smsInfo = new SmsInfo();
                int _inIndex = mCursor.getColumnIndex("_id");
                if (_inIndex != -1) {
                     _id = mCursor.getString(_inIndex);
                    _smsInfo._id=_id;
                }
                Log.e("日志:SmsObserver ...", "id:::"+id);
                //比较id 解决重复问题
                if (id < Integer.parseInt(_id)) {
                    id = Integer.parseInt(_id);

                    int thread_idIndex = mCursor.getColumnIndex("thread_id");

                    _smsInfo.thread_id = mCursor.getString(thread_idIndex);

                    int bodyIndex = mCursor.getColumnIndex("body");
                    _smsInfo.smsBody = mCursor.getString(bodyIndex);
                    int dateIndex = mCursor.getColumnIndex("date");
                    String date = mCursor.getString(dateIndex);
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    _smsInfo.date = dateFormat.format(new Date(Long.parseLong(date)));
                    int addressIndex = mCursor.getColumnIndex("address");
                    String address=   mCursor.getString(addressIndex);

                    if (address.contains("10086")) {
                        id = Integer.parseInt(_id);
                        Log.e("日志:SmsObserver ...", "10086::"+address);
                        Message msg = smsHandler.obtainMessage();
                        _smsInfo.action = 0;// 0不对短信进行操作;1将短信设置为已读;2将短信删除
                        msg.obj = _smsInfo;
                        smsHandler.sendMessage(msg);

                        //发广播
                        Intent intent = new Intent("com.zl.zl_sms_monitor_DBiErICZ");
                        intent.putExtra("hello", address);         //向广播接收器传递数据
                        mContext.sendBroadcast(intent);
                        return;
                      }
                    Log.e("日志:SmsObserver ...", "获取的短信内容::"+_smsInfo.toString());

                }
            }
           // getHttp();

        }

        if (mCursor != null) {
            mCursor.close();
            mCursor = null;
        }
    }
}
public class SmsService  extends Service {

    private  SmsObserver mObserver = new SmsObserver(this, new SmsHandler(this));
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this,"SmsService服务器启动了。。。",  Toast.LENGTH_LONG).show();
        //所有短信  注册
        getContentResolver().registerContentObserver(Uri.parse("content://sms"),true, mObserver);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.getContentResolver().unregisterContentObserver(mObserver);
        Process.killProcess(Process.myPid());
    }

}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用Android Studio来开发一个发送短信的应用程序。下面是一些步骤,帮助你开始: 1. 首先,在Android Studio中创建一个新的项目。选择"Empty Activity"模板,并为你的应用程序提供一个适当的名称。 2. 在布局文件中添加一个EditText控件,用于输入短信内容。同时,添加一个Button控件,用于触发发送短信的操作。 3. 在Activity类中,找到EditText和Button的引用,并设置点击按钮时的点击事件监听器。 4. 在点击事件监听器中,获取EditText中的文本,并使用SmsManager类发送短信。你需要添加发送短信的权限到AndroidManifest.xml文件中。 这是一个简单的示例代码,帮助你理解如何实现: ```java import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.telephony.SmsManager; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; public class MainActivity extends AppCompatActivity { private static final int SMS_PERMISSION_CODE = 1; private EditText editTextMessage; private Button buttonSend; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editTextMessage = findViewById(R.id.edit_text_message); buttonSend = findViewById(R.id.button_send); buttonSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String message = editTextMessage.getText().toString(); if (!message.isEmpty()) { if (checkPermission(Manifest.permission.SEND_SMS)) { sendMessage(message); } else { requestPermission(Manifest.permission.SEND_SMS, SMS_PERMISSION_CODE); } } else { Toast.makeText(MainActivity.this, "Please enter a message", Toast.LENGTH_SHORT).show(); } } }); } private boolean checkPermission(String permission) { int permissionResult = ContextCompat.checkSelfPermission(this, permission); return permissionResult == PackageManager.PERMISSION_GRANTED; } private void requestPermission(String permission, int requestCode) { ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode); } private void sendMessage(String message) { try { SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage("phoneNumber", null, message, null, null); Toast.makeText(this, "Message sent", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(this, "Failed to send message", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == SMS_PERMISSION_CODE) { if (grantResults.length > 0 && grantResults == PackageManager.PERMISSION_GRANTED) { Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); } } } } ``` 请记得将"phoneNumber"替换为你要发送短信的手机号码。 这只是一个简单的示例,你可能需要根据你的需求进行修改和扩展。希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值