挂起意图总是创建新活动

10

我正在尝试制作一个带有NFC功能的应用程序。问题在于当发现NFC标签时,挂起意图始终会创建一个已存在的新活动。我正在使用选项卡主机。 如何在不创建新活动的情况下创建挂起意图。 非常感谢。

 public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);        

            mNfcAdapter = NfcAdapter.getDefaultAdapter(this);                              
            mNfcPendingIntent = PendingIntent.getActivity(this, 0,new Intent(this,
    getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    }

    protected void onResume() {    
            super.onResume();
            mResumed = true;               
            // Sticky notes received from Android
            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {            
                NdefMessage[] messages = getNdefMessages(getIntent());
                byte[] payload = messages[0].getRecords()[0].getPayload();            
                try     { cekNfc(new String(payload)); }
                catch (SQLException e)          { e.printStackTrace(); } 
                catch (NoSuchAlgorithmException e)      {  e.printStackTrace(); }
                catch (UnsupportedEncodingException e)  { e.printStackTrace(); }

                setIntent(new Intent());
            }
            enableNdefExchangeMode();        
        }   
        private void enableNdefExchangeMode() { mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent, mNdefExchangeFilters, null); } 

    NdefMessage[] getNdefMessages(Intent intent) {  // Parse the intent             
            NdefMessage[] msgs = null;        
            String action = intent.getAction();
            //jika ada action
            if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {                      
                Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                if (rawMsgs != null) {
                    msgs = new NdefMessage[rawMsgs.length];
                    for (int i = 0; i < rawMsgs.length; i++) {  msgs[i] = (NdefMessage) rawMsgs[i]; }
                }
            } 
            return msgs;
        }


 public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);        

            mNfcAdapter = NfcAdapter.getDefaultAdapter(this);                              
            mNfcPendingIntent = PendingIntent.getActivity(this, 0,new Intent(this,
    getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    }

    protected void onResume() {    
            super.onResume();
            mResumed = true;               
            // Sticky notes received from Android
            if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {            
                NdefMessage[] messages = getNdefMessages(getIntent());
                byte[] payload = messages[0].getRecords()[0].getPayload();            
                try     { cekNfc(new String(payload)); }
                catch (SQLException e)          { e.printStackTrace(); } 
                catch (NoSuchAlgorithmException e)      {  e.printStackTrace(); }
                catch (UnsupportedEncodingException e)  { e.printStackTrace(); }

                setIntent(new Intent());
            }
            enableNdefExchangeMode();        
        }   
        private void enableNdefExchangeMode() { mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent, mNdefExchangeFilters, null); } 

    NdefMessage[] getNdefMessages(Intent intent) {  // Parse the intent             
            NdefMessage[] msgs = null;        
            String action = intent.getAction();
            //jika ada action
            if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {                      
                Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                if (rawMsgs != null) {
                    msgs = new NdefMessage[rawMsgs.length];
                    for (int i = 0; i < rawMsgs.length; i++) {  msgs[i] = (NdefMessage) rawMsgs[i]; }
                }
            } 
            return msgs;
        }
6个回答

11
在manifest文件中为您的活动(或活动)添加android:launchMode="singleTask"。这样就可以解决问题了。每当系统派发一个NFC intent时,都会创建一个新的Activity。这是NFC intent的唯一性。因此,设置android:launchMode="singleTop"将不起作用,设置PendingIntent中的标志也无济于事。
另一个解决方案是在所有Activity中使用NfcAdapter.enableForegroundDispatch()。这样,您的应用程序直接通过onNewIntent()处理所有NFC意图。

我尝试了android:launchMode="singleTask",但仍然不起作用,并且使用了NfcAdapter.enableForegroundDispatch(),但似乎也没有起作用。 - user1326288
你是如何定义 mNdefExchangeFilters 的? - NFC guy
抱歉,我的意思是:它们的价值是什么。 - NFC guy
“nothing”是一个空列表还是nullnull的值将充当通配符,匹配所有内容。我不确定空列表的结果是什么。也许它会导致不匹配任何内容,因此结果会绕过前台调度。 - NFC guy

3

试试这个:

mNotificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

在您的清单中:

android:launchMode="singleTask"

3
android:launchMode="singleTask"足够了。 - tbruyelle

0

按照以下方式创建您的待处理Intent:

PendingIntent.getActivity(this, 0,new Intent(this,
    getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
    |Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
    |Intent.FLAG_ACTIVITY_REORDER_TO_FRONT), 0);

你是否也尝试在清单文件中将android:launchMode="singleTop"设置为你的活动? - waqaslam

0

请使用这个标志代替。

new Intent(this,
    getClass()).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)

0

在调用“getActivity”方法时,您可以使用标志“PendingIntent.FLAG_UPDATE_CURRENT”。我正在使用它,并没有问题。


我假设你已经在Intent.addFlag中设置了标志,从你的代码和其他答案中看到。它应该放在PendingIntent.getActivity中的最后一个标志“0”之前。 - cagla
另一个建议。这次在创建 Intent 时,在 Intent.addFlags 方法中尝试使用 "Intent.FLAG_ACTIVITY_NEW_TASK"。 - cagla
如果您使用enableForegroundDispatch并调用onNewIntent,则与创建挂起意图无关。我对NFC不是很了解,但很快就会在工作中使用它,所以我很感兴趣。您能告诉我为什么要使用setIntent(new Intent())吗? - cagla
我不知道,我是从Android NFC示例中得到的。我对NFC并不是很了解,我是新手。 - user1326288
我之所以问是因为在StackOverflow的其他帖子中我还没有看到过。我不知道具体细节,但尝试在此活动的第一个调用中调用enableForegroundDispatch方法(可能在onCreate中)。如果未调用此方法,则不会调用onNewIntent方法,因此也不会调用onResume。 - cagla
我的意图过滤器可能有问题吗? - user1326288

0

我遇到了类似的问题,但没有使用TabHost - 每次扫描NFC标签时,我的应用程序都会启动一个新的活动,而不是像我想要的那样触发onNewIntent。我尝试在清单中设置android:launchMode="singleTask"并在我的活动的onResume方法中使用NfcAdapter.enableForegroundDispatch()。相反,我放弃了使用PendingIntent,并在清单中为我的活动设置了意图过滤器,如下所示:

    <activity
        ...
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.nfc.action.NDEF_DISCOVERED" />
            <data android:mimeType="application/vnd.myname.myapp" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.nfc.action.TECH_DISCOVERED" />
        </intent-filter>
        <meta-data
            android:name="android.nfc.action.TECH_DISCOVERED"
            android:resource="@xml/nfc_tech_filter" />
    </activity>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接