7

NFCとAndroidのサポートが必要です。

AndroidでMifare4Kのエミュレーションを可能にするために多くの調査を行った後、存在する唯一のパッチが2.3.4用に作成されていることがわかりました。ここStackOverFlowで、NFCGuyは、AndroidのAPI 14以降、ROMにパッチを適用する必要がないため、非表示のNfc_extrasパッケージを使用してカードエミュレーションをオンにできると語っています。

リフレクション付きのNFC_EXTRASを使用してAPKをコンパイルし、署名とパッケージをnfcee_access.xmlに追加しました。

cardEmulationRouteをON_WHEN_SCREEN_ONに設定した後、logcatに、NFCEEがオンでNFC_CCがオンであることを示す出力が表示されますが、Nexus SをACR122に近づけると、2.3.4パッチメーカーが検出できるエミュレートされたMifare4Kが検出されません。得る。認識されないスマートカードを入手できますが(SEはスマートカードのように機能していると思います)、エミュレートされたMifareを使用する必要があります。

アプレットを機能させるには、2.3.4パッチで変更されたlib-nfcを変更する必要がありますか(Mifare Manager)?または、私のアプリにアクセスすると、そのパッケージで十分なはずですか?

2.3.4パッチを4.1に移植するためにAndroidソースをダウンロードしていますが、投稿された差分を見ると、lib-nfcライブラリの4.1との違いしかありません。(コメント付きの定義、理論的にはカードエミュレーションに使用されます)

おそらく、変更されたROMを再コンパイルする必要はなく、エミュレートされたMifare4kを取得するための小さなステップがありません。

StackOverFlowのすべての人にご協力いただきありがとうございます

よろしく

    private void getSecureElement(){
    try{
        //Obtenemos la clase NFCAdapterExtras
        Class nfcExtrasClazz = Class.forName("com.android.nfc_extras.NfcAdapterExtras");

        if (nfcExtrasClazz == null){
            Log.w("EnableCardEmu", "No existe la clase Extras");
            return;
        }

        Log.w("EnableCardEmu", "Existe la clase");

        //Obtenemos el método "get" de dicha clase
        Method getMethod = nfcExtrasClazz.getMethod("get", Class.forName("android.nfc.NfcAdapter"));

        if (getMethod == null) {
            Log.w("EnableCardEmu", "No existe el método");
        } else {
            Log.w("EnableCardEmu", "Existe el método");
            //Obtenemos el manager del componente NFC del dispositivo
            NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);

            if (adapter == null)
                Log.w("EnableCardEmu", "Adapter es null");
            else {
                //Instancia del SecureElement
                Log.w("EnableCardEmu", "Adapter NO es null");
                nfcExtras = getMethod.invoke(null, adapter);

                Method getEEMethod = nfcExtras.getClass().getMethod("getEmbeddedExecutionEnvironment", 
                        (Class[]) null);
                embebbed = getEEMethod.invoke(nfcExtras , (Object[]) null);
            }
        }
    } catch (InvocationTargetException ee){
        Log.w("EnableCardEmu", ee.getTargetException());
    }
    catch (Exception e){
        Log.w("EnableCardEmu", e.getClass().getName() + " / " + e.getMessage());
        StackTraceElement[] a = e.getStackTrace();
        for (StackTraceElement aa : a){
            Log.w("EnableCardEmu", aa.toString());
        }
    } 
}

    private void deactivateCardEmulation(){
    try{
        Class clss = Class.forName("com.android.nfc_extras.NfcAdapterExtras");
        Class[] cs = clss.getDeclaredClasses();
        /*          
        for (Class cc : cs){
            Log.w("EnableCardEmu", cc.getName();)
        }*/

        //Class route = Class.forName("com.android.nfc_extras.NfcAdapterExtras$CardEmulationRoute");
        Constructor c = cs[0].getConstructor(Integer.TYPE, Class.forName("com.android.nfc_extras.NfcExecutionEnvironment"));
        Object routeOn = c.newInstance(1, null);

        Class cls = nfcExtras.getClass();           
        Method mtd = cls.getMethod("setCardEmulationRoute", cs[0]);
        mtd.invoke(nfcExtras, routeOn);
    } catch (InvocationTargetException ee){
        Log.w("EnableCardEmu", ee.getTargetException());
    } catch (Exception e){
        Log.w("EnableCardEmu", e.getClass().getName() + " / " + e.getMessage());
    }
}

    private void activateCardEmulation(){
    try{

        Class clss = Class.forName("com.android.nfc_extras.NfcAdapterExtras");
        Class[] cs = clss.getDeclaredClasses();
        /*          
        for (Class cc : cs){
            Log.w("EnableCardEmu", cc.getName();)
        }*/

        //Class route = Class.forName("com.android.nfc_extras.NfcAdapterExtras$CardEmulationRoute");
        Constructor c = cs[0].getConstructor(Integer.TYPE, Class.forName("com.android.nfc_extras.NfcExecutionEnvironment"));
        Object routeOn = c.newInstance(2, embebbed);

        Class cls = nfcExtras.getClass();           
        Method mtd = cls.getMethod("setCardEmulationRoute", cs[0]);
        mtd.invoke(nfcExtras, routeOn);
    } catch (InvocationTargetException ee){
        Log.w("EnableCardEmu", ee.getTargetException());
    } catch (Exception e){
        Log.w("EnableCardEmu", e.getClass().getName() + " / " + e.getMessage());
    }
}
4

2 に答える 2

3

問題はにあると思いますObject routeOn = c.newInstance(2, embebbed)。このオブジェクトのタイプが間違っているようです(ただし、私はリフレクションコードの読み取りの専門家ではありません)。

これは私が反射することなくそれを行う方法であり、それは正常に機能します(ISO14443-4AカードとMIFAREクラシックカードの両方がデバイスによって同時にエミュレートされます):

Context mContext; // initialize this
NfcAdapterExtras mAdapterExtras =
  NfcAdapterExtras.get(NfcAdapter.getDefaultAdapter(mContext));
NfcExecutionEnvironment mEe = mAdapterExtras.getEmbeddedExecutionEnvironment();
mAdapterExtras.setCardEmulationRoute(
  new CardEmulationRoute(CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, mEe));

このためにlibnfc-nxpを変更する必要はありません。

于 2012-10-18T21:26:47.980 に答える
3

コードでカードエミュレーションモードが適切に有効になっているはずです。私も同じことを試みていましたが、MIFARE互換のRFIDリーダーで電話を検出できないという同様の問題が発生しました。

原因となったのは、私が使用していた電話がNFCをサポートしていましたが、安全な要素が組み込まれていなかったためです。代わりにセキュアエレメントはSIMカード上にあり、ICS 4.0.3に組み込まれているNFCサポートは、そのセキュアエレメントを見つけて使用することができませんでした。

この同じブランド/モデルの電話には、一部の携帯電話プロバイダーを通じて販売された場合に安全な要素が組み込まれていますが、私のプロバイダーを通じては販売されていません。

NfcExecutionEnvironmentのインスタンスで「オープン」を実行しようとしたときに、これが原因であるという最初のヒントが得られ、次の出力がログキャットに表示されました。

D/NFC JNI (  911): phLibNfc_SE_GetSecureElementList()
D/NFC JNI (  911): 
D/NFC JNI (  911): > Number of Secure Element(s) : 0
E/NFC JNI (  911): phLibNfc_SE_GetSecureElementList(): No SMX detected
于 2012-12-06T01:52:37.527 に答える