2014-02-06 4 views
3

Я хочу, чтобы сообщение Тост, всякий раз, когда получен sms.Intent фильтр не отменяет регистрацию даже программно

Я попытался с явно поставив фильтр намерений в очевидном, и я отчасти удалось, за исключением того, что я не хочу, чтобы вызвать его, когда приложение будет убит, так с советом некоторых программистов здесь, я пытался сделать радиопередачу приемник программно, поместив две кнопки в моем пользовательском интерфейсе, а именно register и unregister, поэтому их единственная цель - зарегистрировать и отменить регистрацию широковещательного приемника.

Моя основная цель - запустить приемник вещания, даже если приложение является фоном (соответствует состоянию, пользователю нажата регистрация и после использования другого приложения).
Я использовал этот учебник: http://www.javacodegeeks.com/2012/09/android-broadcast-receiver.html, но в основном модифицировал его с помощью sms-приемника.

вот мой код:

package gates.apps.automaticmessageresponder; 

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.IntentFilter; 
import android.content.pm.PackageManager; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 

public class MainActivity extends Activity { 

SmsReceiver broadcastReceiver=new SmsReceiver(); 

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

public void register(View view){ 

    this.registerReceiver(broadcastReceiver, new IntentFilter(
      "android.provider.Telephony.SMS_RECEIVED")); 
    Log.e("register","pressed"); 

} 
public void unRegister(View view){ 

    this.unregisterReceiver(broadcastReceiver); 
    Log.e("unregister","pressed"); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

} 

А другой класс

package gates.apps.automaticmessageresponder; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.telephony.SmsManager; 
import android.telephony.SmsMessage; 
import android.util.Log; 
import android.widget.Toast; 

public class SmsReceiver extends BroadcastReceiver { 

// Get the object of SmsManager 
final SmsManager sms = SmsManager.getDefault(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    // Retrieves a map of extended data from the intent. 
    final Bundle bundle = intent.getExtras(); 

    try { 

     if (bundle != null) { 

      final Object[] pdusObj = (Object[]) bundle.get("pdus"); 

      for (int i = 0; i < pdusObj.length; i++) { 

       SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); 
       String phoneNumber = currentMessage.getDisplayOriginatingAddress(); 

       String senderNum = phoneNumber; 
       String message = currentMessage.getDisplayMessageBody(); 

       Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message); 


       // Show alert 
       int duration = Toast.LENGTH_LONG; 
       Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", message: " + message, duration); 
       toast.show(); 

      } // end for loop 
      } // bundle is null 

    } catch (Exception e) { 
     Log.e("SmsReceiver", "Exception smsReceiver" +e); 

    } 

} 

} 

я не изменял файл манифеста за исключением того, что я добавил разрешение на получить смс. Даже я вхожу в журнал, регистр нажат и не нажат. Я думаю, что проблема заключается в том, что кнопка регистрации регистра вызывает вызов даже без щелчка, это ненормальное поведение? или мое восприятие неверно?

ответ

3

Вместо того, чтобы объявить BroadcastReceiver в явной попытке следующим образом в вашей деятельности, что будет связывать его с Activity жизненного цикла (Не забудьте добавить разрешения в файле манифеста):

public class ExampleMainActivity extends Activity { 

    //Activity Stuff 

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, final Intent intent) { 

      //Do things you want with message. 

      AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); 
      builder.setTitle("Title"); 
      builder.setMessage("You may add your things here"); 
      builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 

        dialog.dismiss(); 
       } 
      }); 
      builder.show(); 
     } 
    }; 

    protected void onResume() { 
     super.onResume(); 

     // OR YOU CAN REGISTER UNREGISTER AS YOU WANT 

     this.registerReceiver(broadcastReceiver, new IntentFilter(
       "android.provider.Telephony.SMS_RECEIVED")); 
    }; 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     // OR YOU CAN REGISTER UNREGISTER AS YOU WANT 

     this.unregisterReceiver(broadcastReceiver); 
    } 
} 

Редактировать :

Вы можете проверить это попеременное решение с помощью настройки приложения:

package gates.apps.automaticmessageresponder; 

import android.app.Activity; 
import android.content.ComponentName; 
import android.content.IntentFilter; 
import android.content.pm.PackageManager; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 

public class MainActivity extends Activity { 

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

public void register(View view){ 

    SharedPreferences preferences = context.getSharedPreferences("FILE_NAME", Context.MODE_PRIVATE); 
    Editor edit = preferences.edit(); 
    edit.putBoolean("isRegistered", true); 
    edit.commit(); 

    Log.e("register","pressed"); 

} 
public void unRegister(View view){ 

    SharedPreferences preferences = context.getSharedPreferences("FILE_NAME", Context.MODE_PRIVATE); 
    Editor edit = preferences.edit(); 
    edit.putBoolean("isRegistered", false); 
    edit.commit(); 

    Log.e("unregister","pressed"); 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

} 

И

package gates.apps.automaticmessageresponder; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.telephony.SmsManager; 
import android.telephony.SmsMessage; 
import android.util.Log; 
import android.widget.Toast; 

public class SmsReceiver extends BroadcastReceiver { 

// Get the object of SmsManager 
final SmsManager sms = SmsManager.getDefault(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    // Retrieves a map of extended data from the intent. 
    final Bundle bundle = intent.getExtras(); 

    try { 

     if (bundle != null) { 

      final Object[] pdusObj = (Object[]) bundle.get("pdus"); 

      for (int i = 0; i < pdusObj.length; i++) { 

       SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); 
       String phoneNumber = currentMessage.getDisplayOriginatingAddress(); 

       String senderNum = phoneNumber; 
       String message = currentMessage.getDisplayMessageBody(); 

       Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message); 

     SharedPreferences preferences = context.getSharedPreferences("FILE_NAME", Context.MODE_PRIVATE); 
     boolean isRegistered = preferences.getBoolean("isRegistered", false); 

       if(isRegistered) { 
        // Show alert 
        int duration = Toast.LENGTH_LONG; 
        Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", 
             message: " + message, duration); 
        toast.show(); 
     } 

      } // end for loop 
      } // bundle is null 

    } catch (Exception e) { 
     Log.e("SmsReceiver", "Exception smsReceiver" +e); 

    } 

} 

} 
2

Причина, по которой это не работает, заключается в том, что регистр/регистрация не привязана к жизненному циклу активности, что может привести к регистрации нескольких широковещательных приемников. Рассмотрите этот сценарий:

Пользователь переходит к MainActivity и затем нажимает кнопку Register. Затем пользователь оставляет действие (без регистрации), и приложение может не быть убито. Обратите внимание, что ваш ретранслятор Broadcast все еще зарегистрирован.

Затем, спустя некоторое время, пользователь переходит к действию и регистрируется снова. Теперь у вас есть два разных приемника вещания, которые прослушивают действие. Вы довольно сильно просочились в приемник.

О решении: Зарегистрируйте ваш приемник в манифесте. Используйте общую пару ключей/значений приоритета, чтобы сохранить нажатие кнопки регистрации. Затем, когда вы вызываете onReceive, используйте состояние пары ключ/значение, чтобы определить, хотите ли вы Toast или нет.

+0

Я думаю, что это правильный ответ.Вот почему я использую singleton для регистрации и отмены регистрации «BroadcastReceiver's» и проверки их регистрации, чтобы избежать создания новых экземпляров, когда это не так, как вы хотите. – slinden77

+0

@WindsurferOak: OK проблема, о которой вы упомянули, кажется потенциальной, но мое приложение вызывается, даже если оно не находится в onResume(), и без меня нужно нажать кнопку регистрации –

Смежные вопросы