2016-09-16 43 views
1

我试图检测收到的SMS并通过texttospeech读取它。当在清单中声明时,RECEIVE_SMS的广播接收器不工作(静态地)

当我宣布广播接收器在manifest它不起作用。但是它在一个活动中动态完成时会起作用。

我知道某些广播操作无法在清单中声明并需要一个活动(如here所述)时被捕获到接收方中,但在here中看到有人在清单中使用RECEIVE_SMS。

我不知道我在做什么错。任何帮助将不胜感激!

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="com.bulsy.smstalk1"> 
     <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.READ_CONTACTS" /> 

     <application 
      android:allowBackup="true" 
      android:icon="@mipmap/ic_launcher" 
      android:label="@string/app_name" 
      android:supportsRtl="true" 
      android:theme="@style/AppTheme"> 
      <activity android:name=".MainActivity"> 
       <intent-filter> 
        <action android:name="android.intent.action.MAIN" /> 
        <category android:name="android.intent.category.LAUNCHER" /> 
       </intent-filter> 
      </activity> 
      <receiver android:name="com.bulsy.smstalk1.SmsListener" 
        android:enabled="true" 
        android:permission="android.permission.BROADCAST_SMS" 
        android:exported="true"> 
       <intent-filter android:priority="2147483647">//this doesnt work 
        <category android:name="android.intent.category.DEFAULT" /> 
        <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
       </intent-filter> 
      </receiver> 
     </application> 
    </manifest> 

SmsListener.java

public class SmsListener extends BroadcastReceiver{ 

    private SharedPreferences preferences; 
    TextToSpeech textToSpeech; 
    String msg_from; 
    public SmsListener() 
    { 

    } 

    @Override 
    public void onReceive(final 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; 

      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(); 
         final String msgBody = msgs[i].getMessageBody(); 
         textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() { 
          @Override 
          public void onInit(int status) { 
           if(status != TextToSpeech.ERROR) { 
            textToSpeech.setLanguage(Locale.UK); 
            String fromName = getContactName(context,msg_from); 
            fromName = fromName==null? msg_from:fromName; 
            textToSpeech.speak("You have a text message from " + fromName + ". Content: " + msgBody , TextToSpeech.QUEUE_FLUSH, null); 
           } 
          } 
         } 
         ); 


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

MainActivity.java

public class MainActivity extends AppCompatActivity { 

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

     SmsListener smsListener = new SmsListener();//Dynamically setting the receiver. this works. 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction("android.provider.Telephony.SMS_RECEIVED"); 
     this.registerReceiver(smsListener,filter); 
    } 
} 
+1

你确定''的'name'指向正确的地方吗?当您测试清单Receiver时,是否在安装后至少启动一次“MainActivity”?顺便说一句,''在''中是不必要的,''上不需要'enabled'和'exported'属性。 –

+0

接收器应该指向正确的位置。 com.bulsy.smstalk1.SmsListener。 'com.bulsy.smstalk1'是我的包名,'SmsListener'是我的类名。甚至用'.SmsListener'和'SmsListener'试过。没有工作。我删除了'启用导出的类别'属性。仍然没有工作。 –

+1

是的,'','exported'和'enabled'不会阻止它的工作。我只是说你不需要他们。如果Receiver和MainActivity位于同一个文件夹/包中,那么这些'name'属性都可以。另外,我的其他问题呢?当您测试清单Receiver时,您是否在安装后运行一次'Activity'? –

回答

1

的根这里的问题是清单注册的Receiver实例的生命周期。这种Receiver的实例只有在onReceive()方法完成之前才会有效。 TextToSpeech对象在接收器死亡之前没有准备好,并且没有接收器工作的任何其他指示,则看起来好像接收器刚刚失败。

解决的办法是将TextToSpeech功能移动到Service,您可以从接收器运行,并将用于启动它的Intent上的必要信息作为额外信息传递。