Odebranie SMS nie zmienia treści textView (nie chodzi o dymek TOAST)

0

Mam takie zadanie, aby po otrzymaniu SMS-a zmienić treść textView(po wielu próbach nie chodzi).

Jeżeli zrobię na bazie Toast, oddzielną klasę rozszerzającą BroadcastReceiver (wcześniej rejestrując ją w manifeście) to dymek się pojawia, ale z tego poziomu nie mogę zmieniać textView, bo nie działa mi "findViewById". Natomiast mogę zmieniać textView z MainActivity na przykład po odłączeniu zasilania od telefonu, ale nie reaguje na SMS-RECEIVED.

Poniżej mój kod. W Manifeście mam dołożone:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />

package com.example.dominik.smsonlyinactivity;

import android.content.BroadcastReceiver; //importuje klasę BroadcastReceiver
import android.content.Context; //importuje klasę Context
import android.content.Intent; //importuje klasę Intent
import android.content.IntentFilter; //importuje klasę IntentFilter
import android.provider.Telephony;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.TextView; //rozpoznaje widget-a

public class MainActivity extends AppCompatActivity {


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

        //program który wyświetla text w textView, w klasie zagnieżdżonej

        final TextView textView = (TextView) findViewById(R.id.textView); // używamy final bo jest w innej klasie
        final TextView textView2 = (TextView) findViewById(R.id.textView2); // używamy final bo jest w innej klasie


        //zmiana treści po odłączeniu zasilania do telefonu - to działa
        BroadcastReceiver myReceiver1=new BroadcastReceiver() {//umieszczenie w klasie zagnieżdżonej
            @Override
            public void onReceive(Context context, Intent intent) {
                textView.setText("Tel. jest w trakcie Ładowania...");

            }
        };
        //zmiana treści po odłączeniu zasilania od telefonu - to działa
        BroadcastReceiver myReceiver2=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                textView.setText("Tel. nie jest podłączony do Ładowarki...");
            }
        };

        //test - sprawdzanie czy sms przyszedł - to nie działa
        BroadcastReceiver myReceiver3=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                textView2.setText("odebrano SMS-a");
            }
        };

        registerReceiver(myReceiver1, new IntentFilter(Intent.ACTION_POWER_CONNECTED));//to działa OK
        registerReceiver(myReceiver2, new IntentFilter(Intent.ACTION_POWER_DISCONNECTED)); //to działa OK
        registerReceiver(myReceiver3, new IntentFilter("android.provider.Telephony.SMS_RECEIVED")); //to nie jest wykonywane
        
    }
}


0

Musisz zarejestrować BroadcastReceivera w manifeście (w tym celu również stworzyć oddzielną klasę dla tego receivera):

   <receiver android:name=".MainActivity.nowaKlasa">
        <intent-filter>
            <action android:name="android.provider.telephony.SMS_RECEIVED"></action>
        </intent-filter>
    </receiver>

TextView sobie przekaż przez konstruktor. Z tego co się nie mylę, to nie będzie tam z tym problemu, bo kod będzie wykonywany w wątku UI - będziesz mógł z poziomu klasy BroadcastReceivera manipulować TextView.

Pozdrawiam, gjm

0

OK, utworzyłem osobną klasę MyReceiver:
screenshot-20190101150526.png

W manifeście utworzyłem klasę,
screenshot-20190101145943.png

ale bez MainActvity przed klasą, bo inaczej jest błąd:
screenshot-20190101150230.png

Jak przekazać TextView przez konstruktor?

0

public class MyReceiver extends BroadcastReceiver {
private TextView label;

 public MyReceiver(TextView label) {
    this.label = label;
 }

onReceive().............
}

Przy tworzeniu klasy wtedy: new MyReceiver(twojTextView)

1

Nie można czegoś takiego zrobić. Jeżeli BroadcastReceiver jest rejestrowany przez manifest, to jest tworzony za pomocą konstruktora domyślnego przez framework.

Autor może przykładowo utworzyć własny Intent, który będzie wysyłany po przetworzeniu danych SMS odebranych za pomocą receivera z manifestu i potem nasłuchiwać w aktywności na ten konkretny Intent już w dowolny sposób. A najlepiej nie korzystać z rejestrowania w manifeście tylko własny receiver zrobić od razu w aktywności.

0

Niestety po wielu próbach nadal nie działa.
Dodatkowo przy takim kodzie:

package com.example.dominik.simplesmsreceiverdn;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.TextView;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
    private TextView text;
    public MyReceiver(TextView text) {
        this.text = text;
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals("android.intent.action.SMS_RECEIVED")){
            //final TextView textView = (TextView) findViewById(R.id.textView);
            //textView1.setText("SMS odebrano");
            //Toast.makeText(context, "przyszedł sms", Toast.LENGTH_LONG).show();
        }
    }
}

w manifeście pojawia się błąd:
screenshot-20190101210612.png

Gdzie i jak zapisać "new MyReceiver(twojTextView)"?

1 użytkowników online, w tym zalogowanych: 0, gości: 1