I am writing a kind of alarm clock for android, it will have to change the text in a TextView after a specified time, as I understand it is necessary to implement it in my class description BroadcastReceiver and get access to TextView in my activity, for this I do a static method in my activity and call it is from BroadcastReceiver, the alarm clock is working, but I think I am doing it all wrong and there is another way. Please tell me how else can you access TextView from BroadcastReceiver`a?

MainActivity code:

public class MainActivity extends AppCompatActivity{ static TextView showTime; EditText editTime; int str; final String LOG_TAG = "ml"; Intent intent; PendingIntent pi; AlarmManager am; static void setText(String text){ showTime.setText(text); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); showTime = (TextView)findViewById(R.id.textView); editTime = (EditText)findViewById(R.id.editText); am = (AlarmManager) getSystemService(ALARM_SERVICE); } Intent createIntent(String action, String extra) { Intent intent = new Intent(this, Receiver.class); intent.setAction(action); intent.putExtra(action,extra); return intent; } public void onClick(View view) { str = Integer.parseInt(editTime.getText().toString()); showTime.setText("your delay is " + str + " ms"); intent = createIntent("extra","qwerty"); pi = PendingIntent.getBroadcast(this,0,intent,0); am.set(AlarmManager.RTC,System.currentTimeMillis() + str,pi); } } 

code of my class Receiver:

 public class Receiver extends BroadcastReceiver { final String LOG_TAG = "ml"; @Override public void onReceive(Context ctx, Intent intent){ Intent r = intent; String s = r.getStringExtra("extra"); MainActivity.setText(s); } } 

    1 answer 1

    Yes, you are doing wrong.

    For example, if the system nails an application, then when calling MainActivity.setText(s); the text field will be null and the application will crash. Those. you should at least have a guarantee that the activation is displayed / functioning at the time the method is called.

    I can offer this option:

    1. Create another BroadcastReceiver activity.
    2. In the onResume/onStart register receiver
    3. In onPause/onStop actitize register.
    4. From your current receiver, send an Intent that will be received by the receiver from clause 1.

    So you will not have mistakes and everything will be, in theory, the rules. Here is the code from here:

     public class ToastDisplay extends Activity { public static String BROADCAST_ACTION = "com.unitedcoders.android.broadcasttest.SHOWTOAST"; private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT); } }; @Override protected void onResume() { IntentFilter filter = new IntentFilter(); filter.addAction(BROADCAST_ACTION); registerReceiver(receiver, filter); super.onResume(); } @Override protected void onPause() { unregisterReceiver(receiver); super.onPause(); } } 

    From the first receiver, send the intent for the receiver to activate it like this:

     Intent broadcast = new Intent(); broadcast.setAction(ToastDisplay.BROADCAST_ACTION); sendBroadcast(broadcast); 

    To make static View fields in activit is evil. Do not do it this way)

    • Why not immediately make the first (and only) receiver active? - eugeneek
    • @eugeneek, because the receiver will not accept messages when it arrives - YuriySPb
    • But after all, in this particular example, the receiver does nothing except to change the text in the activation. They brought activism, nothing to do. - eugeneek
    • I do not know what the purpose of the author of the question is, we just assumed that once the alarm clock is in the title, it is better to do so in order not to depend on the activity - YuriySPb