当前位置: 首页 > 知识库问答 >
问题:

Android NDEF包含两个活动和错误意图内容的消息

文华美
2023-03-14

我刚接触Android的NFC,我正在尝试用NFC制作一种通讯应用。

我有一个第一个活动,在发送时将EditText视图的内容发送到另一部手机,并在另一部手机的TextView上显示传入的消息。这个很好用。

我有另一个活动,用于将联系人添加到联系人登记簿中,其工作原理如下:

  • A想将B添加为联系人,

我的问题是,即使关于通过NFC发送的代码在两个活动之间基本上是相同的,当我在第二个活动上发送时,发送的意图的动作是ACTION_MAIN而不是ACTION_NDEF_DISCOVERED,这有打开第一个活动的效果,因此没有经过正确的治疗。

下面是Main活动的代码

public class MainActivity extends Activity {

    private TextView mTextView;
    private EditText mEdit;

    NfcAdapter nfcAdapter;

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

        Intent intent = getIntent();

        mTextView = (TextView)findViewById(R.id.retour);
        mEdit = (EditText)findViewById(R.id.editText);

        nfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());

        nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
            @Override public NdefMessage createNdefMessage(NfcEvent event) {

                String stringOut = mEdit.getText().toString();

                byte[] bytesOut = stringOut.getBytes();

                NdefRecord ndefRecordOut = new NdefRecord(
                        NdefRecord.TNF_MIME_MEDIA,
                        "text/plain".getBytes(),
                        new byte[] {},
                        bytesOut);

                NdefMessage ndefMessageout = new NdefMessage(ndefRecordOut);

                return ndefMessageout;
            }
        }, this);

        checkAndProcessBeamIntent(intent);

    }

    @Override
    public void onResume() {
        super.onResume();

        Intent intent = getIntent();

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);

        try {
            ndef.addDataType("text/plain");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            e.printStackTrace();
        }

        IntentFilter[] intentFiltersArray = new IntentFilter[] {ndef, };
        nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, null);
    }


    private void checkAndProcessBeamIntent(Intent intent) {
        String action = intent.getAction();

        if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)){
            Parcelable[] parcelables =
                    intent.getParcelableArrayExtra(
                            NfcAdapter.EXTRA_NDEF_MESSAGES);

            NdefMessage inNdefMessage = (NdefMessage)parcelables[0];
            NdefRecord[] inNdefRecords = inNdefMessage.getRecords();
            NdefRecord NdefRecord_0 = inNdefRecords[0];

            String inMsg = new String(NdefRecord_0.getPayload());

            mTextView.setText(inMsg);

        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Toast.makeText(MainActivity.this,
                intent.getAction().toString(),
                Toast.LENGTH_LONG).show();
        checkAndProcessBeamIntent(intent);
    }

    @Override
    public void onPause() {
        super.onPause();
        nfcAdapter.disableForegroundDispatch(this);
    }


    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void generateKeys(){
        Calendar cal = Calendar.getInstance();
        Date now = cal.getTime();
        cal.add(Calendar.YEAR, 1);
        Date end = cal.getTime();

        KeyPairGenerator kpg = null;
        try {
            kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
        try {
            kpg.initialize(new KeyPairGeneratorSpec.Builder(getApplicationContext())
                    .setAlias("Keys")
                    .setStartDate(now)
                    .setEndDate(end)
                    .setSerialNumber(BigInteger.valueOf(1))
                    .setSubject(new X500Principal("CN=test1"))
                    .build());
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }

        kpg.generateKeyPair();
    }

    public void goToAddContact(View view) {
        Intent intent = new Intent(this, AddContactActivity.class);
        intent.setAction("NewActivity");
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(intent);

    }
}

以下是AddConruptActive的代码:

public class AddContactActivity extends Activity{

    NfcAdapter nfcAdapter;
    EditText editText;

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

        editText = (EditText)findViewById(R.id.editText);

        nfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());

        Intent intent = getIntent();

        nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
            @Override public NdefMessage createNdefMessage(NfcEvent event) {

                String stringOut = getMyPublicKey();

                byte[] bytesOut = stringOut.getBytes();

                NdefRecord ndefRecordOut = new NdefRecord(
                        NdefRecord.TNF_MIME_MEDIA,
                        "text/plain".getBytes(),
                        new byte[] {},
                        bytesOut);

                NdefMessage ndefMessageout = new NdefMessage(ndefRecordOut);

                return ndefMessageout;
            }
        }, this);

        checkAndProcessBeamIntent(intent);

    }

    @Override
    public void onResume() {
        super.onResume();

        Intent intent = getIntent();

        Toast.makeText(AddContactActivity.this,
                "onResume : "+intent.getAction().toString(),
                Toast.LENGTH_LONG).show();

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);

        try {
            ndef.addDataType("text/plain");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            e.printStackTrace();
        }

        IntentFilter[] intentFiltersArray = new IntentFilter[] {ndef, };
        nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, null);
    }

    public void addContactDataBase(String publicKey){

        SQLiteHelper sqLiteHelper = new SQLiteHelper(this);
        sqLiteHelper.addUser(new User(editText.getText().toString(), publicKey));
    }

    public void checkUserInDataBase(String publicKey){
        SQLiteHelper sqLiteHelper = new SQLiteHelper(this);
        User u = sqLiteHelper.getUser(publicKey);
        Toast.makeText(AddContactActivity.this,
                ""+u.getName(),
                Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Toast.makeText(AddContactActivity.this,
                "OnNewIntent : "+intent.getAction().toString(),
                Toast.LENGTH_LONG).show();
        checkAndProcessBeamIntent(intent);
    }

    @Override
    public void onPause() {
        super.onPause();
        nfcAdapter.disableForegroundDispatch(this);
    }

    private void checkAndProcessBeamIntent(Intent intent) {
        String action = intent.getAction();

        if(action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)){
            Toast.makeText(AddContactActivity.this,
                    "COUCOU",
                    Toast.LENGTH_LONG).show();
            Parcelable[] parcelables =
                    intent.getParcelableArrayExtra(
                            NfcAdapter.EXTRA_NDEF_MESSAGES);

            NdefMessage inNdefMessage = (NdefMessage)parcelables[0];
            NdefRecord[] inNdefRecords = inNdefMessage.getRecords();
            NdefRecord NdefRecord_0 = inNdefRecords[0];

            String inMsg = new String(NdefRecord_0.getPayload());

            addContactDataBase(inMsg);
            checkUserInDataBase(inMsg);

        }
    }

    public String getMyPublicKey(){
        KeyStore ks = null;
        RSAPublicKey publicKey = null;
        try {
            ks = KeyStore.getInstance("AndroidKeyStore");
            ks.load(null);


            KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry)ks.getEntry("Keys", null);
            publicKey = (RSAPublicKey) keyEntry.getCertificate().getPublicKey();

        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (UnrecoverableEntryException e) {
            e.printStackTrace();
        }
        return publicKey.toString();
    }
}

这是清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.bsauzet.testnfc" >

    <uses-permission android:name="android.permission.NFC" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        <activity
            android:name=".AddContactActivity"
            android:label="@string/title_activity_add_contact"
            android:launchMode="singleTop">

            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>

        </activity>
    </application>

</manifest>

共有2个答案

彭星津
2023-03-14

在接收到NFC事件时,使用ACTION_MAIN而不是ACTION_NDEF_DISCOVERED获取意图通常表明收到了包含Android应用程序记录(AAR)的NDEF消息,并且NDEF消息的第一条记录的数据类型未与任何意图过滤器匹配。

您的CreateNdeMessageCallback.createNDefMessage()方法显然没有向NDEF消息添加AAR。因此,您仍然会收到包含AAR的NDEF消息的唯一原因是createNdeMessage()引发了一个未处理的异常。在这种情况下,NFC堆栈将自动生成包含播放存储链接和AAR的NDEFhtml" target="_blank">消息。

最有可能导致createNdefmessage()引发未处理异常的地方是getMyPublicKey()(因为这是MainActivityAddContactActivity之间唯一不同的部分)。

因此,我们可以将问题追溯到代码的这一部分:

ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry)ks.getEntry("Keys", null);
publicKey = (RSAPublicKey) keyEntry.getCertificate().getPublicKey();

这个代码也是

  • 引发一个未处理的运行时异常(例如,如果kskeyEntrykeyEntry.get证书()为null,或者如果ks.getEntry("Keys",null)无法强制转换为KeyStore. Private ateKeyEntry),或者
  • 引发任何已处理的异常,这将导致public Keynull,这将在尝试调用toString()(在返回public Key.toString();中)时导致未处理的NullPointerExctive
葛威
2023-03-14

检查你的appCompat库。appCompat库的损坏可能会导致错误的异常意图。尤其是当你从另一台PC或工作区(和/或IDE)移动你的项目时。

 类似资料:
  • 我已将要首先运行的活动从更改为另一个活动。我通过编辑Android清单并复制: 去我想要的活动。现在,当我运行或调试我的应用程序在我的android设备上成功安装,但它不会自动启动像之前我必须点击图标,我得到下面的错误,如果我运行它在模拟器正确的活动启动只在第一次安装后,它只是忽略该活动,并且总是启动。 请帮忙。 我的全部清单:

  • 我有一个活动,可以在收藏夹列表中添加书签。每个宠儿都有一个按钮。当我点击那个按钮时,我必须进入那个特定的活动。但它显示了一个错误。应用程序不会崩溃,但书签活动不会从单击开始。 以下是“收藏夹”活动的代码: 错误是onClick方法,具体如下: 它给我一个ClassNotFoundExc0019。 似乎有了这段代码,我就可以启动这个包中的活动了。但问题是,我想开始的活动在另一个包中。logcat说它

  • 我试图在一个新项目中运行一些java文件。所以我做了一个项目,把文件放在里面,我试着运行主文件,这样我的游戏就开始了。 null 我很确定它一定有效,因为我几个小时前在学校运行过它。我怎么让它工作?提前感谢!

  • 以下是我用来实现上述布局的代码: 我省略了用于样式设置的代码。你可以在钢笔里看到所有的东西。 上述方法有效,但当区域的内容溢出时,会使整个页面滚动。我只希望内容区域本身滚动,因此我将添加到div。 现在的问题是,柱本身并没有超出其父高度,因此边界也在那里被切断。 这是显示滚动问题的笔。 如何将区域设置为独立滚动,同时使其子项延伸到框的高度之外?

  • 我正在尝试启用设备管理,这样我就可以在Android9中创建二级用户。 首先,使用ACTION_ADD_DEVICE_ADMIN发送一个意图,如下所示: deviceAdminReceiver必须在manifest.xml中预先定义,并使用适当的意图筛选器: 注意:我遵循了以下谷歌Android指南https://developer.Android.com/guide/topics/admin/d

  • 本文向大家介绍请你为一款5v5射击游戏进行一个运营活动,包含活动标题口号,活动内容。相关面试题,主要包含被问及请你为一款5v5射击游戏进行一个运营活动,包含活动标题口号,活动内容。时的应答技巧和注意事项,需要的朋友参考一下