嗨,我正在尝试创建这个搜索短信的应用程序,并在回收站视图中显示它们,当用户点击短信时,我实际上使用广播接收器,它会在用户同意的情况下获取短信,并通过网络发送它通过发布请求说一个简单的 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();
}
});
我可以回答更多