在 android java 中从广播接收器发送短信到服务器

问题描述 投票:0回答:0

嗨,我正在尝试创建这个搜索短信的应用程序,并在回收站视图中显示它们,当用户点击短信时,我实际上使用广播接收器,它会在用户同意的情况下获取短信,并通过网络发送它通过发布请求说一个简单的 python api,但我在实现这个方面遇到了问题。我有权限拒绝问题。我已经通读了很多,也尝试了很多,但我仍然看不出真正的问题是什么。这是我目前的设置。

我得到的错误

  E  FATAL EXCEPTION: Thread-2
                                                                                                    Process: com.jaay.smsforwarder, PID: 3351
                                                                                                    java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SMS_RECEIVED from pid=3351, uid=10228
                                                                                                        at android.os.Parcel.createException(Parcel.java:2071)
                                                                                                        at android.os.Parcel.readException(Parcel.java:2039)
                                                                                                        at android.os.Parcel.readException(Parcel.java:1987)
                                                                                                        at android.app.IActivityManager$Stub$Proxy.broadcastIntent(IActivityManager.java:5207)
                                                                                                        at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1069)
                                                                                                        at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:453)
                                                                                                        at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:453)
                                                                                                        at com.jaay.smsforwarder.ChooseSMSActivity$3$1.run(ChooseSMSActivity.java:266)
                                                                                                        at java.lang.Thread.run(Thread.java:919)
                                                                                                    Caused by: android.os.RemoteException: Remote stack trace:
                                                                                                        at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:15603)
                                                                                                        at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:15469)
                                                                                                        at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:16291)
                                                                                                        at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2113)
                                                                                                        at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2900)

这是我的清单文件

<uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />


    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SMSForwarder"
        android:usesCleartextTraffic="true"
        >

        <receiver
            android:name=".backend.SMSReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action
                    android:name="android.provider.Telephony.SMS_RECEIVED"
                    />
            </intent-filter>
        </receiver>

        <activity
            android:name=".ChooseSMSActivity"
            android:exported="true"
            android:enabled="true"
            android:permission="android.permission.BROADCAST_SMS"
            android:theme="@style/Theme.SMSForwarder.NoActionBar">
        </activity>

我的广播接收器

public class SMSReceiver extends BroadcastReceiver {
    private final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    //Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
    //URL url = new URL("http://127.0.0.1:8080");

    String msg, sender, timestamp, device;

    public SMSReceiver() throws MalformedURLException {
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.d("Broadcast Receiver", "Intent received");
        if (intent.getAction() == SMS_RECEIVED){
            Bundle dataBundle = intent.getExtras();
            if (dataBundle != null){
                Object[] myObjects = (Object[]) dataBundle.get("pdus");
                final  SmsMessage[] message = new SmsMessage[myObjects.length];
                for (int i=0; i<myObjects.length; i++){
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                        String format = dataBundle.getString("format");
                        message[i] = SmsMessage.createFromPdu((byte[])myObjects[i], format);

                    }else {
                        message[i] = SmsMessage.createFromPdu((byte[])myObjects[i]);
                    }
                    msg = message[i].getMessageBody();
                    sender = message[i].getOriginatingAddress();
                    timestamp = millisToDate(message[i].getTimestampMillis());
                    Context applicationContext = MainActivity.getContextOfApplication();
                    SharedPreferences sharedPref;
                    sharedPref =  applicationContext.getSharedPreferences(Constants.SMSFORWARDER, MODE_PRIVATE);
                    device = sharedPref.getString(Constants.DEVICEID, "");
                    Map<String, String> allPref = (Map<String, String>) sharedPref.getAll();
                    for (Map.Entry<String,String> entry : allPref.entrySet()) {

                        System.out.println("Key = " + entry.getKey() +
                                ", Value = " + entry.getValue());
                        if(entry.getValue().equals(sender)) {
                            Thread thread;
                            thread = new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    new HttpPostThread(url,msg, sender, timestamp, device);
                                }
                            });
                            thread.start();
                        }
                    }
                    Toast.makeText(context, msg + "" +sender, Toast.LENGTH_SHORT).show();
                }

            }
        }
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public String millisToDate(long currentTime) {
        String finalDate;
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(currentTime);
        Date date = calendar.getTime();
        finalDate = date.toString();
        return finalDate;
    }
}

这里是发送post请求的http方法

public class HttpPostThread implements Runnable {

    private static final String TAG = HttpPostThread.class.getName();

    public HttpPostThread(URL url, String message, String sender, String timestamp, String device) {
        
        this.url = url;
        this.message = message;
        this.sender = sender;
        this.timestamp = timestamp;
        this.device = device;
        //run();
    }


    /*public HttpPostThread(URL url, String uniqueCode, String device) {
        this.url = url;
        this.uniqueCode = uniqueCode;
        this.device = device;
        run();
    }*/


    @Override
    public void run() {
        HttpURLConnection connection = null;
        try {
            Context applicationContext = MainActivity.getContextOfApplication();
            SharedPreferences sharedPref;
            sharedPref =  applicationContext.getSharedPreferences(Constants.SMSFORWARDER, MODE_PRIVATE);
            String Url = sharedPref.getString(Constants.URL, "");
            if (!Url.equals("")){
                this.url = new URL(Url);
            }else{
                connection = (HttpURLConnection)this.url.openConnection();
                connection.setDoOutput(true);
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                Map<String,String> arguments = new HashMap<>();
                arguments.put("device", device);
                arguments.put("message", message);
                arguments.put("timestamp", timestamp);
                arguments.put("sender",sender);
                //StringJoiner arguments = new StringJoiner("&");
                String data = String.valueOf(new JSONObject(arguments));
                DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                out.writeBytes(data);
                out.flush();
                int status = connection.getResponseCode();
                setStatus(status);
                Log.i(TAG, "Server replied with HTTP status: " + status);
                out.close();
            }

        }
        catch (IOException e) {
            Log.w(TAG, "Error communicating with HTTP server", e);
        }
        finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
    public void setStatus(int status){
        this.status = status;
    }
    public int getStatus(){
        return status;
    }
    private URL url;
    private final String message;
    private final String sender;
    private final String timestamp;
    private final String device;
    private int status;

    //private final String uniqueCode;
}

这是我初始化广播接收器的地方

IntentFilter intentFilter;
    SMSReceiver receiver;
    boolean isSelected = false;
    AppCompatButton sendSMSButton;
    TextView selectedSMSCount;
    List<SMSModel> selectedItems = new ArrayList<>();

    public ChooseSMSActivity() throws MalformedURLException {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_smsactivity);
        List<SMSModel> items = getSMS();
        Toolbar toolbar = (Toolbar) findViewById(R.id.tool);
        setSupportActionBar(toolbar);
        sendSMSButton = new AppCompatButton(this);
        selectedSMSCount = new TextView(this);
        sendSMSButton.setVisibility(View.INVISIBLE);
        sendSMSButton.setVisibility(View.INVISIBLE);
        try {
            receiver = new SMSReceiver();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
        registerReceiver(receiver, intentFilter);

这是我发送广播对话界面的地方,用户说是,然后发出发布请求,我也在这里发送广播接收器。如果有人告诉我我做错了什么,我会很高兴。

public void showAlertDialog(int position, View v, List<SMSModel> items) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setMessage("Do you agree to always forward sms from this sender.");
        alertDialogBuilder.setPositiveButton("Yes",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        thread = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                HttpPostThread httpPostThread = new HttpPostThread(url, items.get(position).getBody(), items.get(position).getSender(), items.get(position).getDate(), items.get(position).getDeviceID());
                                httpPostThread.run();

                                if(httpPostThread.getStatus() == 200){
                                    showErrorSnackBar("message has been sent successfully.", false);

                                }else if (httpPostThread.getStatus() != 200){
                                    showErrorSnackBar("message not sent", true);
                                }
                                SharedPreferences sharedPref;
                                sharedPref = getSharedPreferences(Constants.SMSFORWARDER, MODE_PRIVATE);
                                SharedPreferences.Editor myEdit = sharedPref.edit();
                                myEdit.putString(Constants.DEVICEID, items.get(position).getDeviceID());
                                myEdit.commit();
                                //sharedPref.getAll();
                                if (sharedPref.getString(Constants.SENDER_1, "").equals("")){
                                    myEdit.putString(Constants.SENDER_1, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_2, "").equals("")){
                                    myEdit.putString(Constants.SENDER_2, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_3, "").equals("")){
                                    myEdit.putString(Constants.SENDER_3, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_4, "").equals("")){
                                    myEdit.putString(Constants.SENDER_4, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_5, "").equals("")){
                                    myEdit.putString(Constants.SENDER_5, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_6, "").equals("")){
                                    myEdit.putString(Constants.SENDER_6, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_7, "").equals("")){
                                    myEdit.putString(Constants.SENDER_7, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_8, "").equals("")){
                                    myEdit.putString(Constants.SENDER_8, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_9, "").equals("")){
                                    myEdit.putString(Constants.SENDER_9, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_10, "").equals("")){
                                    myEdit.putString(Constants.SENDER_10, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                else if (sharedPref.getString(Constants.SENDER_11, "").equals("")){
                                    myEdit.putString(Constants.SENDER_11, items.get(position).getSender());
                                    myEdit.commit();
                                }
                                Log.d("CallRR", "Calling Receiver");
                                Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVED");
                                sendBroadcast(intent, Manifest.permission.RECEIVE_SMS);
                            }
                        });
                        thread.start();
                    }
                });

我可以回答更多

post android-intent broadcastreceiver sharedpreferences android-sms
© www.soinside.com 2019 - 2024. All rights reserved.