广播接收器中的异步任务onReceive方法没有运行?

3

我有一个可以将应用程序输入文本字段中的字符串数据发送到我的PC上的TCP服务器的工作应用程序。我添加了BroadcastReceiver类,以便在接收到消息时向计算机发送消息。应用程序接收到消息(Toast正在工作),但我无法使其将接收到的消息发送到PC。

没有错误。应用程序只是跳过所调用的方法。

如何在onReceive内调用方法?

非常感谢您的任何帮助!

public class SmsReceiver extends BroadcastReceiver {
String phone;
String message;

@Override
public void onReceive(Context context, Intent intent) {
    Bundle intentExtras = intent.getExtras();

    if (intentExtras != null) {
        // Get Messages
        Object[] sms = (Object[]) intentExtras.get("pdus");

        for (int i = 0; i < sms.length; ++i) {
            // Parse Each Message
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);

            phone = smsMessage.getOriginatingAddress();
            message = smsMessage.getMessageBody().toString();
            System.out.println("Message is: "+message);
            Log.i("sth","message "+message);

            //What i have tried
            sendMessage(message);

            //creating instance
            MessageSender messageSender = new MessageSender();
            messageSender.execute(message);

            //calling metod from MainActivity
            ((MainActivity)context.getApplicationContext()).send2(message);

            MainActivity.send2(message);

            //toast is working fine
            Toast.makeText(context,"Alert:"+ phone + ": " + message, Toast.LENGTH_SHORT).show();
        }
    }
}
public void sendMessage(String s)
{
    MessageSender messageSender = new MessageSender();
    messageSender.execute(s);
}

主活动

public class MainActivity extends AppCompatActivity {

EditText e1;

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

    e1 = (EditText)findViewById(R.id.editText);
    //This works
    MessageSender messageSender = new MessageSender();
    messageSender.execute("App launched!");
}

//On Button click. Working good.
public void send(View v)
{
    MessageSender messageSender = new MessageSender();
    messageSender.execute(e1.getText().toString());
}
//For test purposes
public static void send2(String s)
{
    MessageSender messageSender = new MessageSender();
    messageSender.execute(s);
}

消息发送器

public class MessageSender extends AsyncTask<String,Void,Void>
{
Socket s;
DataOutputStream dos;
PrintWriter pw;

@Override
public Void doInBackground(String... voids) {

    String message = voids[0];
try {
    s = new Socket("192.168.1.69", 7800);
    pw = new PrintWriter(s.getOutputStream());
    pw.write(message);
    pw.flush();
    pw.close();
    s.close();

}catch(IOException e)
{
    e.printStackTrace();
}
    return null;
}

添加服务端代码:

  public class MyServerFrame extends javax.swing.JFrame 
  {
  static Socket s;
   static ServerSocket ss;
  static InputStreamReader isr;
  static BufferedReader br;
  static String message;public MyServerFrame() 
 {

}

public static void main(String args[]) 
{   
    try 
    {
        ss = new ServerSocket(7800);
        while(true)
        {
            s=ss.accept();
            isr = new InputStreamReader(s.getInputStream());
            br = new BufferedReader(isr);
            StringBuilder everything = new StringBuilder();
            String line;
            while( (line = reader.readLine()) != null) 
            {
               everything.append(line);
            }
            message = everything.toString();//multiple to onelinestring 
            System.out.println(message);
        }   
    }catch (IOException e) 
    {
        e.printStackTrace();
    }
}

}


你认为应用程序为什么会跳过这个方法?你能把你在电脑上的服务器代码贴出来吗? - undefined
谢谢您的回复!已添加服务器代码。在接收消息时我没有收到任何错误,但是我也没有收到来自服务器的消息。另一方面,Toast功能正常工作,所以消息字符串不为空。 - undefined
我会非常感激任何想法或可能的解决方案。 - undefined
可以在按下按钮时从文本字段或任何其他字符串发送已键入的文本。当Android接收到短信消息时,onReceive会显示toast,但不会将消息发送到个人电脑。 - undefined
我会尝试您的建议,并在解决后告诉您。 - undefined
显示剩余6条评论
2个回答

3
问题在于,由于您正在使用onReceive方法中的异步任务执行网络请求,因此由于异步任务是异步的,在AsyncTask执行之前,onReceive方法就返回了。因此,运行onRequest方法的进程变得优先级较低,因为onReceive方法已经返回,并且操作系统将在您的异步任务实际执行之前将其终止。
以下是两种解决方案:
首先确保接收器在Android清单中声明,然后执行以下操作之一。
  1. Instead of calling an Async Task to execute your network request, create a service and use the service to run the network code.

  2. You can call the goAsync() method in the onReceive method to tell the system to give the receiver more time to execute its Async Task. The code for this would be something like this:

    @Override
    public void onReceive(final Context context, final Intent intent) {
    //create a pending intend that you will pass to the Async task so you can tell the system when the Async Task finished so that it can recycle.
    final PendingResult pendingResult = goAsync();
     AsyncTask<String, Integer, String> asyncTask = new AsyncTask<String,  Integer, String>() {
        @Override
        protected String doInBackground(String... params) {
            //put the network calling code in here
    
            // Must call finish() so the BroadcastReceiver can be recycled.
            pendingResult.finish();
            return data;
        }
    };
    asyncTask.execute();
     }
    
我认为第二种方法更简单,因此建议使用它,因为它不需要您创建一个全新的服务。

首先,我想为浪费您的时间而道歉。您的第二个解决方案就像我在问题中所提到的那样,只是简单的方法调用。原因是-接收器在清单文件中没有声明。我甚至没有想到去检查它,因为接收器的Toast在AVD上工作得很好(不知道为什么)。现在一切都正常了。 - undefined
感谢您的努力,对不起我缺乏Android编程经验。 - undefined
如果我们实现了onPostExecute方法,那么pendingResult.finish()应该放在哪里? - undefined
我遇到了这个错误:“由java.lang.IllegalStateException引起:广播已经完成 在android.content.BroadcastReceiver$PendingResult.sendFinished(BroadcastReceiver.java:248) 在android.content.BroadcastReceiver$PendingResult.finish(BroadcastReceiver.java:233)” - undefined

0
感谢SteelToe带领我找到了这个简单的解决方案:

在清单文件中未声明接收器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接