4

私はAndroid開発にまったく慣れていないので、大学向けにnfcタグ(nexus sを使用)を読み取るための簡単なアプリを作成する必要があります。

私の問題は、ネクサスがタグを発見したときに、アプリが「アクションの選択」ポップアップに表示されないことです。目的は、 http ://developer.android.com/guide/topics/nfc/index.html および http://developer.android.com/resources/samples/ApiDemosで説明されているように、フォアグラウンド ディスパッチ メソッドを使用してタグを読み取ることです。/src/com/example/android/apis/nfc/ForegroundDispatch.html

マニフェストに何かが欠けていると思いますが、何がわかりません。マニフェストは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iforge.android.nfc"
>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
>
<activity android:name=".simulator.FakeTagsActivity"
    android:theme="@android:style/Theme.NoTitleBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity>

    <activity android:name="TagViewer"
        android:theme="@android:style/Theme.NoTitleBar"
    >
        <intent-filter>
            <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
            <data android:mimeType="mime/type" />
        </intent-filter>

        <intent-filter>
            <action android:name="android.nfc.action.TECH_DISCOVERED"/>

        </intent-filter>

        <intent-filter>
            <action android:name="android.nfc.action.TAG_DISCOVERED"/>
        </intent-filter>
    </activity>
</application>
<uses-sdk android:minSdkVersion="10" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />

タグが検出されたときに呼び出されるアクティビティのコードは次のとおりです (これは、Android NFCDemo と ForegroundDispatch-example から構築されています)。

public class TagViewer extends Activity 
{

WebView webView;
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mFilters;
private String[][] mTechLists;

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    mAdapter = NfcAdapter.getDefaultAdapter(this);
    mPendingIntent = 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("*/*");    /* Handles all MIME based dispatches. 
                                       You should specify only the ones that you need. */
    }
    catch (MalformedMimeTypeException e) {
        throw new RuntimeException("fail", e);
    }

    mFilters = new IntentFilter[] {
            ndef,
    };

    mTechLists = new String[][] { new String[] { NfcF.class.getName() } };


    setContentView(R.layout.tag_viewer);
    webView = (WebView) findViewById(R.id.webView1);
    webView.getSettings().setJavaScriptEnabled(true); 
    webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
    webView.getSettings().setPluginsEnabled(false);
    webView.getSettings().setSupportMultipleWindows(false);
    webView.getSettings().setSupportZoom(false);
    webView.setVerticalScrollBarEnabled(false);
    webView.setHorizontalScrollBarEnabled(false);

    resolveIntent(getIntent());
}

@Override
public void onResume() {
    super.onResume();
    mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
}

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

void resolveIntent(Intent intent) 
{
    // Parse the intent
    String action = intent.getAction();
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) 
    {
        // When a tag is discovered we send it to the service to be save. We
        // include a PendingIntent for the service to call back onto. This
        // will cause this activity to be restarted with onNewIntent(). At
        // that time we read it from the database and view it.
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage[] msgs;
        if (rawMsgs != null) 
        {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) 
            {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }
        } 
        else 
        {
            // Unknown tag type
            byte[] empty = new byte[] {};
            NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
            NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
            msgs = new NdefMessage[] {msg};
        }
        // Setup the web-view
        setUpWebView(msgs);
    } 
    else 
    {
        Log.e("ViewTag", "Unknown intent " + intent);
        finish();
        return;
    }
}

void setUpWebView(NdefMessage[] msgs) 
{
    if (msgs == null || msgs.length == 0) return;

    String urlToLoad = MessageParser.parseMessage(msgs[0]);
    if(!urlToLoad.matches("")) webView.loadUrl(urlToLoad);

}

@Override
public void onNewIntent(Intent intent) 
{
    setIntent(intent);
    resolveIntent(intent);
    Log.i("Foreground dispatch", "Discovered tag with intent: " + intent);
}
}

私はたくさん試しましたが、何もうまくいきません。誰かが私に欠けているものを教えてくれれば幸いです。時間がなくなってきました:-(

お願いします

ありがとう

4

4 に答える 4

5

IntentFilterフォアグラウンドディスパッチでは、適切に構成されたアクティビティを明示的に使用する必要があります。フォアグラウンドディスパッチにAndroidManifest.xmlで設定されたsを使用できるようには見えません(アプリは実際にフォアグラウンドにある必要があります。つまり、実行中です)。あなたがまだ興味を持っている場合(私が探していたものでした)、以下のコードは正しく機能しているようです(私はちょうどそれをテストしましたACTION_TAG_DISCOVERED):

private NfcAdapter mAdapter;
    private PendingIntent pendingIntent;
    private IntentFilter[] mFilters;
    private String[][] mTechLists;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        setContentView(R.layout.main);

        mAdapter = NfcAdapter.getDefaultAdapter(this);
        pendingIntent = PendingIntent.getActivity(
          this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

     // Setup an intent filter for all MIME based dispatches
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try {
            ndef.addDataType("*/*");
        } catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        IntentFilter td = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
        mFilters = new IntentFilter[] {
                ndef, td
        };

        // Setup a tech list for all NfcF tags
        mTechLists = new String[][] { new String[] { 
                NfcV.class.getName(),
                NfcF.class.getName(),
                NfcA.class.getName(),
                NfcB.class.getName()
            } };
    }

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

        mAdapter.enableForegroundDispatch(this, pendingIntent, mFilters, mTechLists);
    }

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

    @Override
    public void onNewIntent(Intent intent){
        // fetch the tag from the intent
        Tag t = (Tag)intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String tlist = getTechList(t);
        android.util.Log.v("NFC", "Discovered tag ["+tlist+"]["+t+"] with intent: " + intent);
        android.util.Log.v("NFC", "{"+t+"}");
}
于 2012-06-28T21:10:38.817 に答える
4

マニフェスト ファイルは、次のように、tech によって検出されたインテントを個別の tech フィルター xml で処理する必要があります。

<intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
     </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" />
            <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED"/>
            </intent-filter>

次に、 res/xml/nfc_tech_filter.xml で、必要な nfc 技術を次のように処理する必要があります。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.MifareUltralight</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
</resources>

各技術ノードは AND のように機能しますが、技術リスト ノードは AND のように機能します。技術者を知るために、NFC タグ リーダーなどのツールでタグをスキャンすることをお勧めします。

次に、Java コードで、他のサイトのようにフォアグラウンド ディスパッチ システムを有効/無効にすることができます。xml で行ったのと同じ技術を次のように設定します。

private void setUpForegroundDispatchSystem()
    {
        this.nfcAdapter = NfcAdapter.getDefaultAdapter(this);

        this.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("*/*");    /* Handles all MIME based dispatches. 
                                           You should specify only the ones that you need. */
          ndef.addDataScheme("http");
        }
        catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        this.intentFiltersArray = new IntentFilter[] {ndef};
        this.techListsArray = new String[][] { new String[] { MifareUltralight.class.getName(), Ndef.class.getName(), NfcA.class.getName()},
                                               new String[] { MifareClassic.class.getName(), Ndef.class.getName(), NfcA.class.getName()}};

    }

Pause メソッドと Resume メソッドでこれを有効または無効にする必要があります。この情報がお役に立てば幸いです。

于 2011-05-31T14:19:40.000 に答える
0

アクティビティを開始してforegroudnディスパッチを登録する場合、必要なのはACTION_TAG_DISCOVEREDのインテントフィルターを登録することだけです。これは最も低いフィルターであり、検出されたすべてのタグと一致します。より具体的にしたい場合は、タグテクノロジーまたはndefを含むタグのインテントフィルターを登録します。

ただし、タップしてタグを使用してホーム画面からアプリを起動する場合は、別の方法で行う必要があります。MIMEメッセージをタグに正常に配置し、そのMIMEタイプをアクティビティに登録しました。もう1つの方法は、タグにURLを配置してから、スキームとホストを計算するインテントフィルターを登録することです。mimeの場合、これが必要です。

これを一致させるには、タグに、説明されているようにmimeを含むNDEFmimeメッセージが必要です。

于 2011-05-11T08:01:40.633 に答える