Метод NdefRecord.createTextRecord("en", "string") не работает ниже уровня API 21

Этот код отлично работает, когда я использую его на устройстве с Android Lollipop (5.x) или Marshmallow (6.0):

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public NdefMessage createNdfMessage(String content) {
    NdefRecord record = NdefRecord.createTextRecord("en", content);
    NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
    return msg;
}

Но когда я пытаюсь сделать это на устройстве с Android 4.2.2 (уровень API 17), мое приложение вылетает. Как я могу использовать этот код для создания текстовой записи на уровнях API ниже 21 (это уровень API, где метод NdefRecord.createTextRecord стало доступно)?

2 ответа

Решение

Метод NdefRecord.createTextRecord() был представлен на уровне API 21. Следовательно, он недоступен на платформах ниже этого уровня API. Однако вы можете легко собрать текстовую запись самостоятельно. Полезная нагрузка текстовой записи состоит из байта состояния, поля кода языка и текстового поля:

+ ------------- + --------------- + ------------------- ------- +
| Байт состояния | Код языка | Текст |
| (1 байт)    | (n байт) | (м байт)                 |
+-------------+---------------+--------------------------+
  • Байт состояния указывает кодировку символов текстового поля (0 = UTF-8, 1 = UTF-16) в бите 7 и длине n кода языка в битах 5..0. Бит 6 всегда должен быть нулем.
  • Поданный языковой код содержит код языка IANA, закодированный в US-ASCII (например, "en").

Вы можете создать текстовую запись, используя этот метод:

public static NdefRecord createTextRecord(String language, String text) {
    byte[] languageBytes;
    byte[] textBytes;
    try {
        languageBytes = language.getBytes("US-ASCII");
        textBytes = text.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        throw new AssertionError(e);
    }

    byte[] recordPayload = new byte[1 + (languageBytes.length & 0x03F) + textBytes.length];

    recordPayload[0] = (byte)(languageBytes.length & 0x03F);
    System.arraycopy(languageBytes, 0, recordPayload, 1, languageBytes.length & 0x03F);
    System.arraycopy(textBytes, 0, recordPayload, 1 + (languageBytes.length & 0x03F), textBytes.length);

    return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, null, recordPayload);
}

NdefRecord r = createTextRecord("en", content);

Да, createTextRecord представлен в API 21, поэтому его нельзя вызывать в предыдущих версиях. https://developer.android.com/reference/android/nfc/NdefRecord.html

Проверьте, что ваш уровень API 21, прежде чем вызывать createTextRecord.

public NdfeMessage create(String content){
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP){
        NdefRecord record = NdefRecord.createTextRecord("en", content);
        NdefMessage msg = new NdefMessage(new NdefRecord[]{record});
        return msg;
    } else{
        return null;
    }
}
Другие вопросы по тегам