区分了两个不同的短信的发送情况报告 [英] Differentiating delivery reports of two seperate SMS's

查看:336
本文介绍了区分了两个不同的短信的发送情况报告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个服务,在一个广播接收器监听递送报告的循环发送的短信时,如何区分每条短信的发送报告发送? 这是类似于: <一href="http://stackoverflow.com/questions/10975792/how-to-get-delivery-report-of-each-sms-sent-in-loop-android">How取得循环机器人发送的每条短信的发送报告?

但我认为他用它在活动中,我使用它的服务,而getIntent()是无济于事的。

编辑2:我的发帖code

 公共类CheckServer扩展服务
{
  公共字符串snumber [] =新的String [10];

  公共JSONArray阵列;

  公众诠释onStartCommand(意向意图,INT标志,INT startid)
  {
    //做有用的事情。

  ServiceAction SA =新ServiceAction();
  SA.execute();

  尝试
  {
      SA.get();
  }
  赶上(InterruptedException的E)
  {
      e.printStackTrace();
  }
  赶上(为ExecutionException E)
  {
      e.printStackTrace();
  }


  新startSending()执行();

  scheduleNextUpdate();

   返回START_STICKY;
}

公共类startSending扩展的AsyncTask&LT;虚空,虚空,虚空&GT;
{
    @覆盖
    保护无效doInBackground(空... PARAMS)
    {
        字符串否,消息;

          尝试
            {
                的for(int i = 0; I&LT; array.length();我++)
                {
                      的JSONObject行;
                      行= array.getJSONObject(我);
                      snumber [I] = row.getString(SNO);
                      无= row.getString(无);
                      消息= row.getString(信息);
                      sendSMS(不,消息,snumber [I]);
                }
            }
            赶上(IllegalStateException异常E)
            {
                e.printStackTrace();
            }
            赶上(JSONException E)
            {
                e.printStackTrace();
            }

        返回null;
    }
}

私人无效scheduleNextUpdate()
{
  意向意图=新的意图(这一点,this.getClass());
  PendingIntent pendingIntent = PendingIntent.getService(此,0,意向,PendingIntent.FLAG_UPDATE_CURRENT);

//更新频率要经常是用户可配置的。这不是。

长的currentTimeMillis = System.currentTimeMillis的();
长nextUpdateTimeMillis =的currentTimeMillis + 1 * DateUtils.MINUTE_IN_MILLIS;
时间nextUpdateTime =新时代();
nextUpdateTime.set(nextUpdateTimeMillis);

  AlarmManager alarmManager =(AlarmManager)getSystemService(Context.ALARM_SERVICE);
  alarmManager.set(AlarmManager.RTC,nextUpdateTimeMillis,pendingIntent);
}

公共类ServiceAction扩展的AsyncTask&LT;虚空,虚空,虚空&GT;
{
@覆盖
保护无效doInBackground(空...为arg0)
{
      HTT presponse响应= NULL;
      HttpClient的客户端=新DefaultHttpClient();
      HTTPGET请求=新HTTPGET();
      尝试
      {
        request.setURI(新的URI(http://www.somesite.com/sms/getsms));
        响应= client.execute(要求);
        字符串结果= convertStreamToString(response.getEntity()的getContent());
        阵列=新JSONArray(结果);
      }
      赶上(的URISyntaxException E)
      {
        e.printStackTrace();
      }
      赶上(ClientProtocolException E)
      {
        e.printStackTrace();
      }
      赶上(IOException异常E)
      {
        e.printStackTrace();
      }
      赶上(JSONException E)
      {
        e.printStackTrace();
      }


    返回null;
}
}

公共静态字符串convertStreamToString(InputStream中的InputStream)抛出IOException异常
{
  如果(的InputStream!= NULL)
  {
      作家作家=新的StringWriter();

      的char []缓冲区=新的char [1024];
      尝试
      {
          读卡器读卡器=新的BufferedReader(新的InputStreamReader(InputStream中,UTF-8),1024);
          INT N;
          而((N = reader.read(缓冲液))!=  -  1)
          {
              writer.write(缓冲液,0,n)的;
          }
      }
      最后
      {
          inputStream.close();
      }
      返回writer.toString();
  }
  其他
  {
      返回 ;
  }
}


公共无效sendSMS(串号,串消息,字符串SERIALNUM)
{
  字符串SENT =SMS_SENT;

  PendingIntent sentPI = PendingIntent.getBroadcast(此,0,
      新的意图(SENT),0);

  // ---当短信已发送---
  registerReceiver(新BroadcastReceiver的()
    {
      @覆盖
      公共无效的onReceive(背景为arg0,意图ARG1){
          开关(的getResult code())
          {
              案例Activity.RESULT_OK:
                  Toast.makeText(getBaseContext(),短信发送
                          Toast.LENGTH_SHORT).show();
                  打破;
              案例SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                  Toast.makeText(getBaseContext(),一般故障,
                          Toast.LENGTH_SHORT).show();
                  打破;
              案例SmsManager.RESULT_ERROR_NO_SERVICE:
                  Toast.makeText(getBaseContext(),无服务,
                          Toast.LENGTH_SHORT).show();
                  打破;
              案例SmsManager.RESULT_ERROR_NULL_PDU:
                  Toast.makeText(getBaseContext(),空的PDU,
                          Toast.LENGTH_SHORT).show();
                  打破;
              案例SmsManager.RESULT_ERROR_RADIO_OFF:
                  Toast.makeText(getBaseContext(),无线电关
                          Toast.LENGTH_SHORT).show();
                  打破;
          }

          unregisterReceiver(本);
      }
  },新的IntentFilter(发送));

  字符串DELIVERED =SMS_DELIVERED;

  意图传递=新的意图(送到);
  delivered.putExtra(MsgNum,SERIALNUM);
  PendingIntent deliveredPI = PendingIntent.getBroadcast(此,的Integer.parseInt(SERIALNUM),交付,0);

    // ---当SMS已交付---
    registerReceiver(新BroadcastReceiver的()
        {
            @覆盖
           公共无效的onReceive(上下文的背景下,意图意图)
           {
                       开关(的getResult code())
                       {
                           案例Activity.RESULT_OK:

                               Toast.makeText(getBaseContext(),SMS递送,Toast.LENGTH_SHORT).show();

                               updateSMSStatus USS =新updateSMSStatus();

                               USS.execute(intent.getStringExtra(Msgnum));

                               打破;

                           案例Activity.RESULT_CANCELED:

                               Toast.makeText(getBaseContext(),短信未交付,Toast.LENGTH_SHORT).show();

                               打破;
                       }

                     unregisterReceiver(本);
            }

        },
        新的IntentFilter(交付));

    ContentValues​​值=新ContentValues​​();
    values​​.put(地址,数量);
    values​​.put(身体,消息);
    。getContentResolver()插入(Uri.parse(内容://短信/发送),价值);

    SmsManager的smsMngr = SmsManager.getDefault();
    smsMngr.sendTextMessage(数字,空,消息,sentPI,deliveredPI);

}

公共类updateSMSStatus扩展的AsyncTask&LT;字符串,太虚,太虚&GT;
{
    @覆盖
    保护无效doInBackground(字符串... PARAMS){

          HTT presponse响应= NULL;
          HttpClient的客户端=新DefaultHttpClient();
          HTTPGET请求=新HTTPGET();
          尝试
          {
            Log.i(短信APP,MyClass.getView() - 序列号=+参数[0]);
            request.setURI(新的URI(http://www.somesite.com/sms/updatesmsstatus?uname=someone&sno=+参数[0]));
            响应= client.execute(要求);
            字符串结果= convertStreamToString(response.getEntity()的getContent());
            Log.i(短信APP,更新SMS状态是:+结果);
          }
          赶上(的URISyntaxException E)
          {
            e.printStackTrace();
          }
          赶上(ClientProtocolException E)
          {
            e.printStackTrace();
          }
          赶上(IOException异常E)
          {
            e.printStackTrace();
          }

        返回null;
    }
}

  @覆盖
  公众的IBinder onBind(意向意图)
  {
     返回null;
  }

}
 

解决方案

您添加的消息数量多余的意图是这样的:

  delivered.putExtra(MsgNum,SERIALNUM);
 

和您尝试提取它是这样的:

  USS.execute(intent.getStringExtra(Msgnum));
 

putExtra()你的大写的N,在 getStringExtra()你使用小写的n

这就是为什么你要的总是使用常数这样的东西。它prevents你花时间试图找到造成印刷错误的错误。

试试这个:

 公共静态最后弦乐EXTRA_MSGNUM =MsgNum;
 

然后使用:

  delivered.putExtra(EXTRA_MSGNUM,SERIALNUM);
 

  USS.execute(intent.getStringExtra(EXTRA_MSGNUM));
 

编辑:添加一些关于产生不同的 PendingIntent S的基于OP的评论

在注释

OP写道:

  

我的坏了错字,感觉就像一只羊,由于这一点,我测试了它,它   不给一个空值了,相反,它给我的序列号   在回路中的所有邮件发送的第一条消息,如果我送17   20 24 21 25 27,它给了我只为所有人提供报告17

您的问题是这样的 PendingIntent 的作品。系统管理 PendingIntent S的游泳池。当你的code的作用:

 字符串DELIVERED =SMS_DELIVERED;
意图传递=新的意图(送到);
delivered.putExtra(MsgNum,SERIALNUM);
PendingIntent deliveredPI = PendingIntent.getBroadcast(这一点,
                    的Integer.parseInt(SERIALNUM),交付,0);
 

这会导致系统搜索 PendingIntent 匹配你传递的参数(在这种情况下,你的意图)。然而,匹配算法 PendingIntent 仅使用比较了某些领域的意图来确定它是否是一个你正在寻找。尤其是,它并不比演员。因此,这意味着你已经创建后的第一个 PendingIntent ,调用 PendingIntent.getBroadcast()总是返回同样 PendingIntent 从池中(而不是创建一个新的,这是你想要的)。

为了使呼叫 PendingIntent.getBroadcast()创建一个新的 PendingIntent 每次调用它,请尝试将传递给调用唯一的参数(例如:通过在意图独特的动作)。此外,由于每种 PendingIntent 旨意只能使用一次,你应该获得的 PendingIntent 这样,当设置FLAG_ONE_SHOT

 字符串DELIVERED =SMS_DELIVERED+ SERIALNUM; //独特的作用,每次
意图传递=新的意图(送到);
delivered.putExtra(MsgNum,SERIALNUM);
PendingIntent deliveredPI = PendingIntent.getBroadcast(这一点,
                    的Integer.parseInt(SERIALNUM),交付,
                    PendingIntent.FLAG_ONE_SHOT);
 

由于该动作将每次调用 PendingIntent.getBroadcast(),这应该解决您的问题。不同的

EDIT2:添加基础上,意见讨论注册广播接收器的替代方法

如果你创建一个继承BroadcastReceiver的一类,你可以添加到清单,然后你并不需要显式注册的广播接收器都​​没有。事情是这样的:

 公共类MessageStatusReceiver扩展的BroadcastReceiver {
    @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){
        //这就是所谓的当您的SMS的状态发生变化(交付或发送状态)
        // ..把你的code在这里..
   }
}
 

声明的接收器在你的清单:

 &LT;接收机器人:名称=。MessageStatusReceiver/&GT;
 

在你的code发送短信,做到这一点:

 字符串DELIVERED =SMS_DELIVERED+ SERIALNUM; //独特的作用,每次
意图传递=新的意图(背景下,MessageStatusReceiver.class);
delivered.setAction(送到); //设置行动,以确保独特的Pen​​dingIntent
delivered.putExtra(MsgNum,SERIALNUM);
PendingIntent deliveredPI = PendingIntent.getBroadcast(这一点,
                    的Integer.parseInt(SERIALNUM),交付,
                    PendingIntent.FLAG_ONE_SHOT);
 

In a service, when sending smses in a loop with a broadcast receiver listening for delivery reports, how to differentiate the delivery report of each sms sent? This is similar to : How to get Delivery Report of each SMS sent in loop android?

except that I think he's using it in an activity and I'm using it in a service where getIntent() is of no avail.

Edit 2: posting my code

public class CheckServer extends Service
{
  public String snumber[] = new String[10];

  public JSONArray array;

  public int onStartCommand(Intent intent,int flags, int startid)
  {
    // Do useful things.

  ServiceAction SA = new ServiceAction();
  SA.execute();

  try 
  {
      SA.get();
  } 
  catch (InterruptedException e) 
  {
      e.printStackTrace();
  } 
  catch (ExecutionException e) 
  {
      e.printStackTrace();
  }


  new startSending().execute();

  scheduleNextUpdate();

   return START_STICKY;
}

public class startSending extends AsyncTask<Void,Void,Void>
{
    @Override
    protected Void doInBackground(Void... params) 
    {
        String no,message;

          try 
            {
                for (int i = 0; i < array.length(); i++) 
                {
                      JSONObject row;
                      row = array.getJSONObject(i);
                      snumber[i] = row.getString("sno");
                      no = row.getString("no");
                      message = row.getString("message");
                      sendSMS(no,message,snumber[i]);
                }
            } 
            catch (IllegalStateException e) 
            {
                e.printStackTrace();
            } 
            catch (JSONException e) 
            {
                e.printStackTrace();
            }

        return null;
    }
}

private void scheduleNextUpdate()
{
  Intent intent = new Intent(this, this.getClass());
  PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

// The update frequency should often be user configurable.  This is not.

long currentTimeMillis = System.currentTimeMillis();
long nextUpdateTimeMillis = currentTimeMillis + 1 * DateUtils.MINUTE_IN_MILLIS;
Time nextUpdateTime = new Time();
nextUpdateTime.set(nextUpdateTimeMillis);

  AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
  alarmManager.set(AlarmManager.RTC, nextUpdateTimeMillis, pendingIntent);
}

public class ServiceAction extends AsyncTask<Void,Void,Void>
{
@Override
protected Void doInBackground(Void... arg0) 
{
      HttpResponse response = null;
      HttpClient client = new DefaultHttpClient();
      HttpGet request = new HttpGet();
      try 
      {
        request.setURI(new URI("http://www.somesite.com/sms/getsms"));
        response = client.execute(request);
        String result = convertStreamToString(response.getEntity().getContent());
        array = new JSONArray(result);
      } 
      catch (URISyntaxException e) 
      {
        e.printStackTrace();
      } 
      catch (ClientProtocolException e) 
      {
        e.printStackTrace();
      } 
      catch (IOException e) 
      {
        e.printStackTrace();
      } 
      catch (JSONException e) 
      {
        e.printStackTrace();
      }


    return null;
}
}

public static String convertStreamToString(InputStream inputStream) throws IOException
{
  if (inputStream != null)
  {
      Writer writer = new StringWriter();

      char[] buffer = new char[1024];
      try
      {
          Reader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"),1024);
          int n;
          while ((n = reader.read(buffer)) != -1)
          {
              writer.write(buffer, 0, n);
          }
      }
      finally
      {
          inputStream.close();
      }
      return writer.toString();
  }
  else
  {
      return "";
  }
}


public void sendSMS(String number,String message,String serialnum) 
{   
  String SENT = "SMS_SENT";

  PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
      new Intent(SENT), 0);

  //---when the SMS has been sent---
  registerReceiver(new BroadcastReceiver()
    {
      @Override
      public void onReceive(Context arg0, Intent arg1) {
          switch (getResultCode())
          {
              case Activity.RESULT_OK:
                  Toast.makeText(getBaseContext(), "SMS sent", 
                          Toast.LENGTH_SHORT).show();
                  break;
              case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                  Toast.makeText(getBaseContext(), "Generic failure", 
                          Toast.LENGTH_SHORT).show();
                  break;
              case SmsManager.RESULT_ERROR_NO_SERVICE:
                  Toast.makeText(getBaseContext(), "No service", 
                          Toast.LENGTH_SHORT).show();
                  break;
              case SmsManager.RESULT_ERROR_NULL_PDU:
                  Toast.makeText(getBaseContext(), "Null PDU", 
                          Toast.LENGTH_SHORT).show();
                  break;
              case SmsManager.RESULT_ERROR_RADIO_OFF:
                  Toast.makeText(getBaseContext(), "Radio off", 
                          Toast.LENGTH_SHORT).show();
                  break;
          }

          unregisterReceiver(this);
      }
  }, new IntentFilter(SENT));

  String DELIVERED = "SMS_DELIVERED";

  Intent delivered = new Intent(DELIVERED);
  delivered.putExtra("MsgNum", serialnum);
  PendingIntent deliveredPI = PendingIntent.getBroadcast(this, Integer.parseInt(serialnum), delivered, 0);

    //---when the SMS has been delivered---
    registerReceiver(new BroadcastReceiver()
        {   
            @Override
           public void onReceive(Context context, Intent intent)
           {
                       switch (getResultCode())
                       {
                           case Activity.RESULT_OK:

                               Toast.makeText(getBaseContext(), "SMS delivered",Toast.LENGTH_SHORT).show();

                               updateSMSStatus USS =  new updateSMSStatus();

                               USS.execute(intent.getStringExtra("Msgnum"));

                               break;

                           case Activity.RESULT_CANCELED:

                               Toast.makeText(getBaseContext(), "SMS not delivered",Toast.LENGTH_SHORT).show();

                               break;                        
                       }

                     unregisterReceiver(this);
            }

        },
        new IntentFilter(DELIVERED)); 

    ContentValues values = new ContentValues();
    values.put("address", number);
    values.put("body", message);
    getContentResolver().insert(Uri.parse("content://sms/sent"), values);

    SmsManager smsMngr = SmsManager.getDefault();
    smsMngr.sendTextMessage(number, null, message, sentPI, deliveredPI);

}

public class updateSMSStatus extends AsyncTask<String,Void,Void>
{
    @Override
    protected Void doInBackground(String... params) {

          HttpResponse response = null;
          HttpClient client = new DefaultHttpClient();
          HttpGet request = new HttpGet();
          try 
          {
            Log.i("SMS APP", "MyClass.getView() — Serial Number = " + params[0]);
            request.setURI(new URI("http://www.somesite.com/sms/updatesmsstatus?uname=someone&sno="+params[0]));
            response = client.execute(request);
            String result = convertStreamToString(response.getEntity().getContent());
            Log.i("SMS APP","Update SMS Status is :"+result);
          } 
          catch (URISyntaxException e)
          {
            e.printStackTrace();
          } 
          catch (ClientProtocolException e) 
          {
            e.printStackTrace();
          } 
          catch (IOException e) 
          {
            e.printStackTrace();
          }

        return null;
    }
}

  @Override
  public IBinder onBind(Intent intent) 
  {
     return null;
  }

}

解决方案

You add the message number extra to the Intent like this:

delivered.putExtra("MsgNum", serialnum);

and you try to extract it like this:

USS.execute(intent.getStringExtra("Msgnum"));

In putExtra() you have uppercase "N", in getStringExtra() you use lowercase "n".

This is why you should always use constants for stuff like this. It prevents you spending hours trying to find errors caused by typographical errors.

Try this:

public static final String EXTRA_MSGNUM = "MsgNum";

then use:

delivered.putExtra(EXTRA_MSGNUM, serialnum);

and:

USS.execute(intent.getStringExtra(EXTRA_MSGNUM));

EDIT: Add something about generating different PendingIntents based on OP's comment

OP wrote in a comment:

My bad for the typo, felt like a sheep due to that, i tested it, it does not give a null value now, instead, it gives me the serial number of the first message sent in the loop for all messages, if i send 17 20 24 21 25 27, it gives me only 17 for all the delivery reports

Your problem is the way PendingIntent works. The system manages a pool of PendingIntents. When your code does:

String DELIVERED = "SMS_DELIVERED";
Intent delivered = new Intent(DELIVERED);
delivered.putExtra("MsgNum", serialnum);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this,
                    Integer.parseInt(serialnum), delivered, 0);

This causes the system to search for a PendingIntent that matches the parameters you've passed in (in this case, your Intent). However, the matching algorithm that PendingIntent uses only compares certain fields of the Intent to determine if it is the one that you are looking for. In particular, it does not compare extras. So this means after you've created the first PendingIntent, the call to PendingIntent.getBroadcast() will always return the same PendingIntent from the pool (and not create a new one, which is what you want).

In order to make the call to PendingIntent.getBroadcast() create a new PendingIntent every time you call it, try making the parameters you pass to the call unique (for example: by making the ACTION in the Intent unique). Also, since each of these PendingIntents will only be used once you should set the FLAG_ONE_SHOT when obtaining the PendingIntent like this:

String DELIVERED = "SMS_DELIVERED" + serialnum; // Unique ACTION every time
Intent delivered = new Intent(DELIVERED);
delivered.putExtra("MsgNum", serialnum);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this,
                    Integer.parseInt(serialnum), delivered,
                    PendingIntent.FLAG_ONE_SHOT);

Since the ACTION will be different for each call to PendingIntent.getBroadcast(), this should solve your problem.

EDIT2: Add alternative method of registering broadcast receivers based on discussion in comments

If you create a class that extends BroadcastReceiver, you can add that to the manifest and then you don't need to explicitly register the broadcast receiver at all. Something like this:

public class MessageStatusReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is called when the status of your SMS changes (delivery or send status)
        // .. put your code here ..
   }
}

Declare the receiver in your manifest:

<receiver android:name=".MessageStatusReceiver" />

In your code that sends the SMS, do this:

String DELIVERED = "SMS_DELIVERED" + serialnum; // Unique ACTION every time
Intent delivered = new Intent(context, MessageStatusReceiver.class);
delivered.setAction(DELIVERED ); // Set action to ensure unique PendingIntent
delivered.putExtra("MsgNum", serialnum);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this,
                    Integer.parseInt(serialnum), delivered,
                    PendingIntent.FLAG_ONE_SHOT);

这篇关于区分了两个不同的短信的发送情况报告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆