android - Android 中自动检测短信

标签 android broadcastreceiver sms android-service one-time-password

我正在尝试从短信中自动检测 OTP 并将 OTP 填充到 EditText 中。我试图通过接收器服务对此进行存档,但它给出的日志为“它为空”,并且不会自动填充 EditText(etLastOtp)。

这是我的服务类别:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.SmsMessage;
import android.util.Log;

public class SmsListener extends BroadcastReceiver {

    public OnSmsReceivedListener listener = null;
    public Context context;

    public SmsListener()
    {

    }

    public void setOnSmsReceivedListener(Context context) {
        Log.d("Listener","SET");
        this.listener = (OnSmsReceivedListener) context;
        Log.d("Listener","SET SUCCESS");
    }

    public interface OnSmsReceivedListener {
        public void onSmsReceived(String otp);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
            Bundle bundle = intent.getExtras();           //---get the SMS message passed in---
            SmsMessage[] msgs = null;
            String msg_from;
            if (bundle != null){
                //---retrieve the SMS message received---
                try{
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    msgs = new SmsMessage[pdus.length];
                    for(int i=0; i<msgs.length; i++){
                        msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                        msg_from = msgs[i].getOriginatingAddress();
                        String msgBody = msgs[i].getMessageBody();

                        Log.d("MsgBody", msgBody);

                            String otpSMS=msgBody.substring(36,36+4);


                        if (listener != null) {
                            listener.onSmsReceived(otpSMS);
                        }
                        else
                        {
                            Log.d("Listener", "Its null");
                        }

                    }
                }catch(Exception e){
                    Log.d("Exception caught", e.getMessage());
                }
            }
        }
    }
}

这是我的 Activity 类:

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;

public class MobileVerifySMS extends AppCompatActivity implements SmsListener.OnSmsReceivedListener {

    ImageButton btnBack;
    private boolean mIsInForegroundMode;

    Button btnVerify;
    String userName,email,password,currency,role,isind,timeZone;
    TextView tvTryAgain;
    public EditText etLastOTP;
    String lastOTP;
    Button btnSkip;
    TLConstants tlConstants;
    DatabaseHandler databaseHandler;
    TLAPI tlapi;

    private SmsListener receiver;

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

        receiver = new SmsListener();
        receiver.setOnSmsReceivedListener(this);


        btnBack=(ImageButton)findViewById(R.id.btnBack);

        etLastOTP=(EditText)findViewById(R.id.etOtpEnd);
        btnVerify=(Button)findViewById(R.id.btnVerify);
        btnSkip=(Button)findViewById(R.id.btnSkip);
        tvTryAgain=(TextView)findViewById(R.id.tryAgain);

        btnVerify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(etLastOTP.getText().toString().length()==4) {

//verify otp
                }
                else
                {
                    Toast.makeText(getApplicationContext(),"Enter 4 digit OTP",Toast.LENGTH_SHORT).show();
                }
            }
        });

        mIsInForegroundMode=true;
    }

    @Override
    public void onSmsReceived(String otp) {
        try
        {
            etLastOTP.setText(otp);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }


    @Override
    protected void onPause() {
        super.onPause();

        mIsInForegroundMode = false;
    }
    @Override
    protected void onResume() {
        super.onResume();
        mIsInForegroundMode = true;

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        this.finish();
        overridePendingTransition(R.anim.hj_enter_left_anim_2, R.anim.hj_exit_left_anim);

    }

    @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_mobile_verify, 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);
    }
}

最佳答案

您没有显示任何注册您的 BroadcastReceiver 的代码,所以我要冒险猜测您添加了 <intent-filter>BroadcastReceiver 的 list 条目,在收到短信时触发。这可以解释你的问题。

如果您有 <intent-filter>为您BroadcastReceiver ,收到短信后,Android 将自动创建您的 BroadcastReceiver 的新实例。并调用onReceive()在那个新实例上。由于该实例是由 Android 创建的,因此未在其上设置监听器。

要解决此问题,您需要删除 <intent-filter>从 list 中,您需要注册您的 BroadcastReceiver创建后动态地。在你的Activity ,创建 BroadcastReceiver 后,调用registerReceiver() 。您需要创建一个 IntentFilter描述广播 Intent您想要接收。

关于android - Android 中自动检测短信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36310923/

相关文章:

android - 服务- Activity 沟通

android - 如何知道蓝牙何时断开连接

Android BroadcastReceiver处理多条消息

android - Network Changed Broadcast Receiver 在一加手机中不执行

java - 使用 AT 命令发送短信的名称而不是号码

android - 模拟器上未收到二进制数据短信

Android 锁屏 settext 应用程序崩溃

android-actionbar - Android 平板电脑在带有图像的操作栏中更改应用程序名称

c++ - 从 Windows 应用程序发送短信

java - 获取 API,Android Studio 静态