NFC Deaktivieren in onNewIntent

  • Antworten:32
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 09:55:04 via Website

Hallo, ich habe eine frage, wie kann man man NFC Pausieren nachdem ein NFC Tag eingegangen ist.

Mein Problem ist folgendes, ich habe ein Tag der mehrmals in der Minute erkannt wird.
Mein ziel ist es das ein 3 Sekunden lag wartet bevor er wider liest.

Ich versuchte schon disableForegroundDispatch in onNewIntent aufzurufen, mit geringen erfolg.
Es kam nur die Meldung :
java.lang.IllegalStateException: You must disable foreground dispatching while your activity is still resumed

Ich hoffe ihr könnt helfen.

Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

19.07.2018, 09:57:52 via App

Willst du komplett das Lesen verhindert oder reicht es, wenn die App das gelesene für 3 Sek ignoriert?

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 09:58:20 via Website

Hallo,

das Problem gibt es nur bei einigen Devices , nicht alle haben die Macke und ist Hardware/Kernel bedingt.

Bastel dir einen Workaround mit einem Compare, - so habe ich es gelöst.

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 10:13:56 via Website

Danke fürs Reagieren.

Kannst du mir genauer erläutern mit dem Workaround .

Ignorieren wäre auch eine Möglichkeit er muss nicht umdingt komplett aufhören.

ich habe auch schon sowas ausprobiert :

protected void onNewIntent(Intent intent)//Eintretende NFC Tag's
{
if ((last_time > 0 && (System.currentTimeMillis() - last_time) < 3000L)) {
        return;
    }
    last_time = System.currentTimeMillis();
    .....

Aber dennoch blinkt meine Aktivity, so als wurde sie neu erzeugt werden und das will ich ja vermeiden, wen ein tag ignoriert werden soll, sonst wäre es mir egal .

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 10:35:31 via Website

Hallo
mit dem Code schaltest du ja nicht das NFC aus sondern reagirst nur eine Zeit nicht auf gescante Tag.
Gelesen werden sie vom Handy weiter nur du verabeistest sie für 3 sec nicht.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 10:48:49 via Website

Ich mache einen Compare auf den Tag Inhalt in einem eigenen Thread.
Erst dann , wenn der sich ändert, löse ich einen Listener aus .

P.S.
Das mit deinem "Blinken" deiner Activity habe ich nicht verstanden - warum soll die blinken oder neu
starten ? (Resume ?)
Lagere das NFC Geraffel in eine gesonderte Klasse aus und warte in einem Thread auf was Neues ,
und dann erst ein Listener-Callback an die Activity.

— geändert am 19.07.2018, 10:52:58

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 11:18:25 via Website

Bei jedem Stempel tritt er in onResume() rein, ich weis aber auch nicht warum er das tut.

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 11:20:32 via Website

Ich habe eben die Funktion nfcAdapter.ignore() gefunden, sie funktioniert echt super, aber sie läuft leider nur ab Nugat.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 11:23:16 via Website

Und deshalb habe ich dir oben schon das Workaround erklärt.
Dir wird für eine vernünftige Entwicklung nichts Anderes übrig bleiben. (OOP)

— geändert am 19.07.2018, 11:25:12

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 11:35:11 via Website

Danke für deine bisherige Hilfe , könntest du ein beispiele mir gegeben wie das aussehen würde?

Wäre hilfreich, da ich mir das gerade nicht vorstellen kann.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 11:46:25 via Website

a) Du bastelst Dir eine eigene Klasse, die in einem Thread das gesamte NFC Handling behandelt.
b) In diese Klasse baust du dir einen Listener ein.
c) Du initiierst eine Instanz dieser Klasse in deiner MainActivity und implementierst dort den Listener /Callback
d) Bekommst du einen NFC-Tag so schickst du den Callback an deine Activity und sicherst den in eine Variable.
e) Kommt eine NFC Lesung, comparst du den Inhalt, ob dieser anders ist, Wenn ja, dann ab an deine Activity.

Kannst auch mit Setter/Getter arbeiten , macht aber m.E. wenig Sinn.

Somit umgehst du alle Hardware/Kernel-Macken und bleibst abwärts-Kompatibel

— geändert am 19.07.2018, 11:47:25

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Jokel
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 12:46:24 via Website

Wie startest du den NFC Listener in einem Thread?
NFC will doch immer eine Activity , wo auch die Resultate eintrete, oder verstehe ich da jetzt falsch?

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 12:56:33 via Website

a) Natürlich Im Constructor der Klasse

b) Seit wann benötigt NFC eine Activity ?

Siehe API Docu
https://developer.android.com/guide/topics/connectivity/nfc/nfc

References :
https://developer.android.com/reference/android/nfc/package-summary

— geändert am 19.07.2018, 13:06:40

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 13:12:14 via Website

Könntest du mir einen Code Ausschnitt zeigen, wie ein Start aussehen sollte?
ich fühl mich gerade zu dämlich. :?

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 13:31:29 via Website

a) Mit getDefaultAdapter (Context)
b) und danach wendest du einen der Listener an

https://developer.android.com/reference/android/nfc/NfcAdapter

Dennoch :

Aber auch bei der herkömmlichen Weise mit dem Override onNewIntent in deiner MainActivity müsste es eigentlich einwandfrei Funktionieren, wenn dir die OOP Variante von mir zu aufwendig ist.

Auch dürfte da kein OnResume kommen und dort kannst du auch das oben besagte Compare durchführen.
Was hast du denn noch in dem Callback drinnen ? ( ausser deinem Zeitvergleich)

— geändert am 19.07.2018, 13:34:35

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 13:44:07 via Website

Wenn die onResume aufgerufen wird muss deine Activity ja irgendwie in den Hintergrund treten und durch den Tag wider in den Vordergrund sonst wird onResume normalerweise nicht angesprungen.

Was machst du weil die Activity im Hintergrund ist?

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 13:55:27 via Website

In der onNewIntent wird der Tag in die Datenbank gepeichert ,ja nach Tag ID wird auch eine neue Activity geöffnet, das entscheidet dies entscheidet sich auch über ein abgleich in der Datenbank.

In der Logik selbst wird auch recreate() aufgerufen.

Das verhalten das es in onResume() auftritt entsteht ist auch wenn ich alles aus kommentiere.

Das ist aber dann nicht beabsichtigt.

Ich biete dir mal mein NFC Start dar :

  private void startNFC() {
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
        IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        IntentFilter techDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        IntentFilter[] nfcIntentFilter = new IntentFilter[]{techDetected, tagDetected, ndefDetected};

        Context context = getApplicationContext();

        Intent intent = new Intent(context,ScannerActivity.this.getClass());
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,0);
        if (nfcAdapter != null) {
            nfcAdapter.enableForegroundDispatch(ScannerActivity.this, pendingIntent, nfcIntentFilter, null);
        }
Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 14:42:07 via Website

Frage wieso startest du eine neue Activity um Daten in einer DB zu speichern oder zuvergleichen ?

Hilfreich?
swa00
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 14:43:40 via Website

Und eigentlich hatte mich der newIntent Part interessiert, nicht der Init Teil.

Aber ich denke auch , dass im Aufruf der "DB-Activity" der Hund begraben ist.

— geändert am 19.07.2018, 14:44:44

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Jokel
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 14:52:33 via Website

Ich habe alles aus Kommentiert was in newIntent drin war, das Ereignis taucht dennoch auf ,es kommt in onResume()

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 14:55:01 via Website

Dann elimiere mal deine DB Activity und sonstige und lass nur mal den NFC Part stehen ...

P.S gehe nach dem Ausschlussverfahren vor - Bastel dir hierzu NUR eine Activity, die nichts Weiters macht , als NFC zu lesen - kein UI geraffel, nichts.

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 15:11:23 via Website

Es ist eigentlich logisch das die onResume aufgerufen wird wenn du zum speichern eine neue Activity startest.
Wenn in der Zeit ein Teg gefunden wird startet Android wieder deine Activity 1 wider und durchläuft dabei die onResume. Auch wenn du nach den Speichen zurück zu esten Activity gehst wird die onResume aufgerufen.
Activity LifeCycle.
Aber teste es so wie swa00 es gesagt hat.
Mir war nur wichtig das du verstehst warum deine onResume aufgerufen wird.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 15:29:30 via Website

Ich denke , so langsam kommen wir hinter sein Geheimnis ...

.

Anmerkung :

Wenn du Dir dein Konzept nur bruchstückweise aus der Nase ziehen lässt , dann wird das Mühsam für uns. Unsere Kristallkugel ist auch nur beschränkt leistungsfähig.
(zumal wir die Hilfe in unserer "übrigen" Zeit freischaufeln)

Sei also bitte so lieb und lass dich nicht zweimal fragen was wo und wann passiert oder poste direkt den ganzen relevanten Code und wir müssen nicht Rätseln.

Danke

— geändert am 19.07.2018, 15:31:29

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 15:44:02 via Website

Ich habe mal ein Test Projekt geöffnet und das seht drin.
` public class Start extends AppCompatActivity
{
NfcAdapter nfcAdapter;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start);
    nfcAdapter = NfcAdapter.getDefaultAdapter(this);
}
@Override
protected void onNewIntent(Intent intent)
{
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    if(tag != null)
    {

// Ndef ndef = Ndef.get(tag);
// if(ndef != null) {
// try {
// ndef.connect();
// NdefMessage ndefMessage = ndef.getNdefMessage();
// String message = new String(ndefMessage.getRecords()[0].getPayload()).substring(3);
// ndef.close();
// }
// catch (IOException | FormatException e) {
// e.printStackTrace();
//
// }
// }
// else {
// textView.setText("Keine Daten forhanden!");
// }
}
}

// private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
// public static String bytesToHex(byte[] bytes) {
// char[] hexChars = new char[bytes.length * 2];
// for ( int j = 0; j < bytes.length; j++ ) {
// int v = bytes[j] & 0xFF;
// hexChars[j * 2] = hexArray[v >>> 4];
// hexChars[j * 2 + 1] = hexArray[v & 0x0F];
// }
// return new String(hexChars);
// }

@Override
protected void onResume() {
    super.onResume();
    IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
    IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    IntentFilter techDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
    IntentFilter[] nfcIntentFilter = new IntentFilter[]{techDetected,tagDetected,ndefDetected};

    PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    if(nfcAdapter!= null)
        nfcAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilter, null);

}

@Override
protected void onPause() {
    super.onPause();
    if(nfcAdapter!= null)
        nfcAdapter.disableForegroundDispatch(this);
}

}
`
Das Problem ist dennoch da.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 15:54:43 via Website

Jetzt wird auch der Zusammenhang klar, Du benutzt Techniken an Stellen , die nicht dahin gehören.

Darf ich fragen warum du beim Resume das gesamte Init (wiederholt) machst ?
Beschränke dich mal Bitte nur auf enable und im onPause auf disable.

Alles Andere bitte in die onCreate.

Schau dir mal bitte dazu dieses Beispiel hier an, da wird es deutlich, was du verwechselst.
http://www.codexpedia.com/android/android-nfc-read-and-write-example/

— geändert am 19.07.2018, 15:55:12

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 16:18:25 via Website

Auch die Intentfilter soltest du besser im Manifest definieren nicht zur laufzeit in der onResume.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 16:24:27 via Website

Oder viel besser in die Manifest - das hat da eigentlich auch nichts zu suchen

EDIT : Sorry, Blöd ausgedrückt von mir :-)

— geändert am 19.07.2018, 17:07:19

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 16:30:37 via Website

@saw00

Oder viel besser in die Manifest - das hat da eigentlich auch nichts zu suchen

wie meinst du das sagte doch das er es in das Manifest schreiben soll ? oder wohin sonst kann dir da nicht richtig folgen.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 16:36:38 via Website

auch das wird wohl nicht gehn.
"nfcAdapter" wird wohl nicht null sein zumindestens nicht beim ersten start nach onCreate.
auch sonst denke ich ist sie nicht Null somit fukionirt dein ein und ausschalten nicht
in dem Beispiel von swa00 wird dies mit einer Flag Variablen gelöst.

if(nfcAdapter!= null)
nfcAdapter.disableForegroundDispatch(this);

if(nfcAdapter!= null)
nfcAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilter, null);

— geändert am 19.07.2018, 23:08:11

Hilfreich?
swa00
Kommentieren
swa00
  • Forum-Beiträge: 3.704

19.07.2018, 16:43:35 via Website

< intent-filter >
< action android:name="android.nfc.action.NDEF_DISCOVERED" / >
< meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" / >

— geändert am 19.07.2018, 16:45:25

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 16:56:54 via Website

Ok also doch im Manifest

@saw00 schaue bitte wer die Frage stellt, wollte nur wissen wo das deiner Meinung nach hin soll wie steht ja im Beispiel.
lg J.

— geändert am 19.07.2018, 23:06:53

Hilfreich?
Kommentieren
FrankenDerStein
  • Forum-Beiträge: 25

19.07.2018, 17:00:03 via Website

Hallo und danke für eure Hilfe, es läuft jetzt alles ohne das grausige blinken.

Eure Ratschläge waren echt hilfreich, danke dafür.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.527

19.07.2018, 17:01:47 via Website

Schön :)

Hilfreich?
Kommentieren