Подтвердить что ты не робот

Android BroadcastReceiver onReceive Update TextView в MainActivity

В MainActivity у меня есть TextView: textV1. У меня также есть метод в MainActivity, который обновляет это textview:

public void updateTheTextView(final String t) {
    MainActivity.this.runOnUiThread(new Runnable() {
        public void run() {
            TextView textV1 = (TextView) findViewById(R.id.textV1);
            textV1.setText(t);
        }
    });
}

В BroadcasrReceiver мне нужно обновить текст в textV1 в MainActivity.

public class NotifAlarm extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
            // other things done here like notification

            // NEED TO UPDATE TEXTV1 IN MAINACTIVITY HERE
    }
}

Как это можно сделать? BroadcastReceiver запускается из службы. Этот код я не могу изменить. Могу ли я получить доступ и изменить textV1 в MainActivity от onReceive()? Я пробовал много вещей, но все провалилось.

4b9b3361

Ответ 1

В MainActivity инициализируйте переменную класса MainActivity, как показано ниже.

public class MainActivity extends Activity {
    private static MainActivity ins;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ins = this;     
    }

    public static MainActivity  getInstace(){
        return ins;
    }

    public void updateTheTextView(final String t) {
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                TextView textV1 = (TextView) findViewById(R.id.textV1);
                textV1.setText(t);
            }
        });
    }
}


public class NotifAlarm extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            MainActivity  .getInstace().updateTheTextView("String");
        } catch (Exception e) {

        }           
    }
}

Ответ 2

создайте экземпляр класса, а затем передайте значение функции, которая изменит значение TextView, выполните следующие действия: в вашем методе BroadcastReceiver overRide onReceive и вставьте эти строки или тему изменений, как вы пожелаете

private Handler handler = new Handler(); // Handler used to execute code on the UI thread
// Post the UI updating code to our Handler
handler.post(new Runnable() {
    @Override
    public void run() {
    //Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show();
    YourActivityToUpdate.updateTheTextView(message);
    YourActivityToUpdateinst = YourActivityToUpdate.instance();
        if(inst != null)  { // your activity can be seen, and you can update it context
        inst.updateTheTextView(message);
        }
    }
});

теперь мы объясняем updateTheTextView и inst в классе YourActivityToUpdate Вставьте эти строки, пожалуйста,

private static SignUpVerify mInst;

public static SignUpVerify instance() {
        return mInst;
}
@Override
public void onStart() {
    super.onStart();
    mInst = this;
}

@Override
public void onStop() {
    super.onStop();
    mInst = null;
}

и это метод updateTheTextView, который должен быть помещен в класс YourActivityToUpdate

public void updateTheTextView(final String verifyCodeValue) {
                Log.i("verifyCodeValue", verifyCodeValue);
                YourTextViewToUpdate.setText(verifyCodeValue);
    }

Я думаю, что это лучший способ благодаря "кевин-рыси"

Ответ 3

Если кто-то ищет это точное решение, но в Котлине, сделайте следующее:

class MainActivity : AppCompatActivity() {

    companion object {
        var ins: MainActivity? = null
        fun getInstance(): MainActivity? {
            return ins
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ins = this
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ins = this;     
    }

    fun updateTheTextView(t: String) {
        [email protected] {
            val textV1 = findViewById<TextView>(R.id.textV1)
            textV1.text = t
        }
    }
}

class NotifAlarm : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        try {
            MainActivity.getInstance()?.updateTheTextView("The String")
        } catch (e: Exception) {

        }
    }
}

Ответ 4

Используйте интерфейс

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

Следуй этим шагам:
1) Создать интерфейс

public interface MyBroadcastListener{

    public void doSomething(String result);

}

2) Инициализировать слушателя в BroadCastReceiver

public class NotifAlarm extends BroadcastReceiver {

    private MyBroadcastListener listener;

    @Override
    public void onReceive(Context context, Intent intent) {

        listener = (MyBroadcastListener)context;

        // other things done here like notification

        // NUPDATE TEXTV1 IN MAINACTIVITY HERE
        listener.doSomething("Some Result");
    }
}

3) Реализовать интерфейс в Activity и переопределить метод

public YourActivity extends AppCompatActivity implements MyBroadcastListener{

    // Your Activity code 

    public void updateTheTextView(String t) {
        TextView textV1 = (TextView) findViewById(R.id.textV1);
        textV1.setText(t);
    }

    @Override
    public void doSomething(String result){
         updateTheTextView(result);          // Calling method from Interface
    }

 }

Преимущество использования интерфейса?

  • Когда у вас есть BroadcastReceiver в другом файле
  • Развязанный BroadcastReceiver

Использование интерфейсного подхода делает BroadcastReceiver независимым от любой активности. Допустим, в будущем вы захотите использовать этот BroadCastReceiver с другим действием, которое берет результат из BroadcastReceiver и запускает DetailActivity с результатом. Это совершенно другая задача, но вы будете использовать Same BroadcastReceiver, даже не меняя код внутри BroadcastReceiver.

Как это сделать?
Реализуйте интерфейс в Activity и переопределите метод. Это!

public ListActivity extends AppCompatActivity implements MyBroadcastListener{

    // Your Activity code 

    public void startDetailActivity(String title) {
        Intent i = new Intent(ListActivity,this, DetailActivity.class);
        i.putExtra("Title", title);
        startActivity(i);
    }

    @Override
    public void doSomething(String result){
         startDetailActivity(String title);    // Calling method from Interface
    }

 }