ANDROID 内置阅读器禁用问题

问题描述 投票:0回答:1

`你好, 我正在制作一个 NFC 计时应用程序,我遇到了一个无法克服的问题,如果有人有任何想法,我会很高兴听到。 当我扫描 NFC 标签时,Android 的内置 NFC 读取器不断弹出。 如果我将意图过滤器放入清单文件中,它不会弹出,但每次触摸时它都会一次又一次地拉入我设置的活动,这是不合适的,我还会将 nfc 用于其他活动,所以这不是一个解决方案。 有没有办法阻止内置 nfc 阅读器出现? NFC 芯片只有一个 ID,没有其他内容,并且无法再更改。 🙁 预先非常感谢您的帮助! 代码:

package eu.obsys.staffkeeper.ui.worklogin;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcF;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

import eu.obsys.staffkeeper.FirstPageActivity;
import eu.obsys.staffkeeper.R;
import eu.obsys.staffkeeper.data.JsonObjectAsyncResponse;
import eu.obsys.staffkeeper.data.Repository;
import eu.obsys.staffkeeper.model.GpsLocation;
import eu.obsys.staffkeeper.util.GlobalFunction;

public class WorkLogInActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback {

    private SharedPreferences sharedPreferences;
    private Context context;
    private Button logInToWorkCard,logOutToWorkCard, backToMenu, loginButton;
    private ImageView thumbnail;
    private String bitmapString;
    private TextView nfcContent,txtType;
    private int employeeId = 0;
    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1888;
    private Drawable sampleImage;

    //NFC
    public static final String MIME_TEXT_PLAIN = "text/plain";
    public static final String TAG = "NfcDemo";
    private Tag detectedTag;
    private NfcAdapter mNfcAdapter;
    PendingIntent pendingIntent;
    IntentFilter[] readTagFilters;

    private String baseUrl;
    private static final String GLOBAL_DATA     = "globalShared";
    String[] perms = {"android.permission.NFC"};

    int permsRequestCode = 200;

    IntentFilter[] intentFiltersArray;

    String[][] techListsArray;
    IntentFilter ndef = new IntentFilter();

    int loginStatus = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_work_log_in);
        requestPermissions(perms, permsRequestCode);
        pendingIntent = PendingIntent.getActivity(
                this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
                PendingIntent.FLAG_MUTABLE);
        initVariable();
        initNFC();
        initListener();
    }

    public void initVariable() {
        context                 = getApplicationContext();
        sharedPreferences       = context.getSharedPreferences("placeObject", Context.MODE_PRIVATE);
        baseUrl                 = sharedPreferences.getString("baseUrl", "https://mng.ob-sys.eu/");

        logInToWorkCard         = findViewById(R.id.loginToWorkCard);
        logOutToWorkCard        = findViewById(R.id.logoutFromWorkCard);
        loginButton             = findViewById(R.id.loginButton);
        backToMenu              = findViewById(R.id.bacToMenuButton);
        thumbnail               = findViewById(R.id.PhotoThumbnail);
        nfcContent              = findViewById(R.id.nfcContent);
        nfcContent              = findViewById(R.id.nfcContent);
        nfcContent              = findViewById(R.id.nfcContent);


        sampleImage             = thumbnail.getDrawable();

        PackageManager packageManager = context.getPackageManager();
        if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) == false){
            Toast.makeText(context, "This device does not have a camera.", Toast.LENGTH_LONG)
                    .show();
            return;
        }
    }

    public void takePictureAndStoreEmployeeId(int employeeIdLocal) {
        mNfcAdapter.disableReaderMode(this);
        JSONObject jsonResponse = new Repository().getUserByNFC(baseUrl, employeeIdLocal, WorkLogInActivity.this, new JsonObjectAsyncResponse() {
            @Override
            public void processFinished(JSONObject jsonObject) {
                try {
                    if(jsonObject.getInt("success") == 1) {
                        employeeId = employeeIdLocal;
                        loginStatus = jsonObject.getInt("loginStatus");
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        intent.putExtra("android.intent.extras.CAMERA_FACING", 1);
                        intent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true);

                        startActivityForResult(intent,
                                CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


    public void initListener() {

        backToMenu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(WorkLogInActivity.this, FirstPageActivity.class);
                startActivity(intent);
                finish();
            }
        });


        logInToWorkCard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                logInToWorkCard.setVisibility(View.INVISIBLE);
                Context context = getApplicationContext();
                final int duration                    = Toast.LENGTH_LONG;
//                GpsLocation gpsLocation     = GlobalFunction.getLocation(context);
                new Repository().setLoginStatus(
                        baseUrl,
                        employeeId,
                        1,
                        sharedPreferences.getInt("placeId", 0),
                        bitmapString,
                        WorkLogInActivity.this,
                        new JsonObjectAsyncResponse() {
                            @Override
                            public void processFinished(JSONObject _jsonObject) {
                                try {
                                    if(_jsonObject.getInt("success") == 1) {
                                        logInToWorkCard.setVisibility(View.VISIBLE);
                                        resetPage();
                                    } else {
                                        logInToWorkCard.setVisibility(View.VISIBLE);
                                        String text                   = context.getResources().getString(R.string.faultAction) + " Listener";
                                        Toast toast                   = Toast.makeText(context, text, duration);
                                        toast.show();
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                );
            }
        });

        logOutToWorkCard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                logOutToWorkCard.setVisibility(View.INVISIBLE);
                Context context             = getApplicationContext();
                final int duration          = Toast.LENGTH_SHORT;
                //GpsLocation gpsLocation     = GlobalFunction.getLocation(context);
                new Repository().setLoginStatus(
                        baseUrl,
                        employeeId,
                        0,
                        sharedPreferences.getInt("placeId", 0),
                        bitmapString,
                        WorkLogInActivity.this,
                        new JsonObjectAsyncResponse() {
                            @Override
                            public void processFinished(JSONObject _jsonObject) {
                                try {
                                    if(_jsonObject.getInt("success") == 1) {
                                        logOutToWorkCard.setVisibility(View.VISIBLE);
                                        resetPage();
                                    } else {
                                        logOutToWorkCard.setVisibility(View.VISIBLE);
                                        String text                   = context.getResources().getString(R.string.faultAction) + " Listener";
                                        Toast toast                   = Toast.makeText(context, text, duration);
                                        toast.show();
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                );
            }
        });

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {

                Bitmap bmp = (Bitmap) data.getExtras().get("data");
                ByteArrayOutputStream stream = new ByteArrayOutputStream();

                bmp.compress(Bitmap.CompressFormat.PNG, 30, stream);
                byte[] byteArray = stream.toByteArray();

                // convert byte array to Bitmap
                bitmapString = Base64.encodeToString(byteArray, Base64.DEFAULT);
                Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
                        byteArray.length);
                if(loginStatus == 1) {
                    logInToWorkCard.setVisibility(View.INVISIBLE);
                    logOutToWorkCard.setVisibility(View.VISIBLE);
                } else {
                    logInToWorkCard.setVisibility(View.VISIBLE);
                    logOutToWorkCard.setVisibility(View.INVISIBLE);
                }
//                loginButton.setVisibility(View.INVISIBLE);
                thumbnail.setImageBitmap(bitmap);
            }
        }
    }

    public void resetPage() {
        thumbnail.setImageDrawable(sampleImage);
        logInToWorkCard.setVisibility(View.INVISIBLE);
        logOutToWorkCard.setVisibility(View.INVISIBLE);
    }

    public void initNFC() {
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try {
            ndef.addDataType("*/*");    /* Handles all MIME based dispatches.
                                       You should specify only the ones that you need. */
        }
        catch (IntentFilter.MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        intentFiltersArray = new IntentFilter[] {ndef, };
        techListsArray = new String[][] { new String[] { NfcF.class.getName() } };

        try {
            if (!mNfcAdapter.isEnabled()) {
                txtType.setText("NFC is disabled.");
            } else {
                //txtType.setText("érkngorbgobrogb");
            }

        } catch (NullPointerException e) {
            Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        /**
         * It's important, that the activity is in the foreground (resumed). Otherwise
         * an IllegalStateException is thrown.
         */
        if(mNfcAdapter!= null) {

            //mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
            Bundle options = new Bundle();
            // Work around for some broken Nfc firmware implementations that poll the card too fast
            options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);

            // Enable ReaderMode for all types of card and disable platform sounds
            mNfcAdapter.enableReaderMode(this,
                    this,
                    NfcAdapter.FLAG_READER_NFC_A |
                            NfcAdapter.FLAG_READER_NFC_B |
                            NfcAdapter.FLAG_READER_NFC_F |
                            NfcAdapter.FLAG_READER_NFC_V |
                            NfcAdapter.FLAG_READER_NFC_BARCODE |
                            NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
                    options);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        /**
         * Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
         */
        if(mNfcAdapter!= null)
            mNfcAdapter.disableReaderMode(this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    }

    @Override
    public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(permsRequestCode, permissions, grantResults);

        switch (permsRequestCode) {

            case 200:

                boolean nfcAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;

                break;

        }

    }

    public void onTagDiscovered(Tag tag) {

        // Read and or write to Tag here to the appropriate Tag Technology type class
        // in this example the card should be an Ndef Technology Type
        Ndef mNdef = Ndef.get(tag);

        // Check that it is an Ndef capable card
        if (mNdef != null) {

            // If we want to read
            // As we did not turn on the NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK
            // We can get the cached Ndef message the system read for us.

            NdefMessage mNdefMessage = mNdef.getCachedNdefMessage();
            String anyad = "";
            NdefRecord[] records = mNdefMessage.getRecords();
            for (NdefRecord ndefRecord : records) {
                //if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
                byte[] payload = ndefRecord.getPayload();

                // Get the Text Encoding
                String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";

                // Get the Language Code
                int languageCodeLength = payload[0] & 0063;

                // String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
                // e.g. "en"

                // Get the Text
                try {
                    anyad = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // }
            }
            // Or if we want to write a Ndef message

            // Create a Ndef Record
            //NdefRecord mRecord = NdefRecord.createTextRecord("en", "2");

            // Add to a NdefMessage
//            NdefMessage mMsg = new NdefMessage(mRecord);
//
            // Catch errors
            try {
                mNdef.connect();
//                mNdef.writeNdefMessage(mMsg);
                    takePictureAndStoreEmployeeId(Integer.parseInt(anyad));
                    Toast toast = new Toast(getApplicationContext());
                    toast.makeText(getApplicationContext(),"Read NFC Success", Toast.LENGTH_SHORT).show();

                // Make a Sound
                try {
                    Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                    Ringtone r = RingtoneManager.getRingtone(getApplicationContext(),
                            notification);
                    r.play();
                } catch (Exception e) {
                    // Some error playing sound
                }

            //} catch (FormatException e) {
                // if the NDEF Message to write is malformed
            } catch (TagLostException e) {
                // Tag went out of range before operations were complete
            } catch (IOException e) {
                // if there is an I/O failure, or the operation is cancelled
            } finally {
                // Be nice and try and close the tag to
                // Disable I/O operations to the tag from this TagTechnology object, and release resources.
                try {
                    mNdef.close();
                } catch (IOException e) {
                    // if there is an I/O failure, or the operation is cancelled
                }
            }

        }

    }
}
android nfc
1个回答
0
投票

这个问题很难回答,因为您没有提供卡上数据的完整详细信息。

但问题可能是您在从

disableReaderMode
调用的
takePictureAndStoreEmployeeId
方法中
onTagDiscovered
,因此一旦您读取 NFC 标签一次,您将永远不会再次读取 NFC 标签,因为读取器模式永远不会重新启用。

请记住,当您出示标签时,可以多次触发 NFC 交互。 发生的情况很可能是您呈现它触发的标签

onTagDiscovered
,然后
disableReaderMode
,然后在第二次触发时,系统可以自由显示默认系统 NFC 对话框,因为您已告诉它您不再有兴趣接收NFC 触发器。

解决方案可能不是

disableReaderMode
takePictureAndStoreEmployeeId

此外,您的代码中也有很多未使用的内容,您设置了旧的前台 NFC 方法

enableForegroundDispatch
,该方法从未使用过(因为它被使用
enableReaderMode
替换,并且您不应该同时使用两者)

© www.soinside.com 2019 - 2024. All rights reserved.