在Android ICS与NFC_EXTRAS启用CardEmulation [英] Enabling CardEmulation on Android ICS with NFC_EXTRAS

查看:468
本文介绍了在Android ICS与NFC_EXTRAS启用CardEmulation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要NFC和Android的帮助。

做了很多的研究,以使4K的Mifare在Android上的仿真之后,我发现,存在的唯一的补丁是为2.3.4。在这里,计算器,NFCGuy告诉我们,由于Android的API 14这不是neccesary补丁的ROM,这样我们就可以使用隐藏Nfc_extras包上卡模拟转。

我编译一个APK使用NFC_EXTRAS与反思,并增加了我的签名,封装到nfcee_access.xml。

在我设置cardEmulationRoute为ON_WHEN_SCREEN_ON,我得到了logcat中告诉我,NFCEE为ON,NFC_CC为ON,但是当我把我的Nexus S接近ACR122不检测的仿真MIFARE 4K的2.3.4输出贴片生产商可以得到。我可以得到一个无法识别的智能卡(我想,这是SE像一个智能卡),但我需要使用仿真MIFARE。

我是否需要修改LIB-NFC,因为它是修改2.3.4的补丁来获取小应用程序的工作(的Mifare经理)?或用我的应用程序accesing该包应足够多?

我下载Android源端口的2.3.4补丁4.1,但看着自己发布的差异,也只有4.1 LIB-NFC库的差异。 (A定义注释,用于卡仿真理论)

也许这不是necesary重新编译修改的ROM和我失去了一小步来获取仿真MIFARE 4K。

感谢您的帮助,在这里StackOverflow的所有的人。

问候

 私人无效getSecureElement(){
    尝试{
        // Obtenemos拉化酶NFCAdapterExtras
        类nfcExtrasClazz =的Class.forName(com.android.nfc_extras.NfcAdapterExtras);

        如果(nfcExtrasClazz == NULL){
            Log.w(EnableCardEmu,无existe拉化酶额外);
            返回;
        }

        Log.w(EnableCardEmu,Existe拉化酶);

        // Obtenemos EL方法方法获得德DICHA化酶
        方法GetMethod的= nfcExtrasClazz.getMethod(获取,的Class.forName(android.nfc.NfcAdapter));

        如果(GetMethod的== NULL){
            Log.w(EnableCardEmu,无existe埃尔方法方法);
        } 其他 {
            Log.w(EnableCardEmu,Existe埃尔方法方法);
            // Obtenemos埃尔经理德尔componente NFC德尔dispositivo
            NfcAdapter适配器= NfcAdapter.getDefaultAdapter(本);

            如果(适配器== NULL)
                Log.w(EnableCardEmu,变压器ES空);
            其他 {
                // Instancia德尔SecureElement
                Log.w(EnableCardEmu,适配器否上课空);
                nfcExtras = getMethod.invoke(空,适配器);

                方法getEEMethod = nfcExtras.getClass()。GetMethod的(getEmbeddedExecutionEnvironment
                        (等级[])NULL);
                embebbed = getEEMethod.invoke(nfcExtras,(对象[])NULL);
            }
        }
    }赶上(的InvocationTargetException EE){
        Log.w(EnableCardEmu,ee.getTargetException());
    }
    赶上(例外五){
        Log.w(EnableCardEmu,e.getClass()的getName()+/+ e.getMessage());
        一个StackTraceElement [] A = e.getStackTrace();
        对于(StackTraceElement的AA:1){
            Log.w(EnableCardEmu,aa.toString());
        }
    }
}

    私人无效deactivateCardEmulation(){
    尝试{
        类CLSS =的Class.forName(com.android.nfc_extras.NfcAdapterExtras);
        类[] CS = clss.getDeclaredClasses();
        / *
        对于(CC级:CS){
            Log.w(EnableCardEmu,cc.getName())
        } * /

        //类路径=的Class.forName(com.android.nfc_extras.NfcAdapterExtras $ CardEmulationRoute);
        构造函数C = CS [0] .getConstructor(Integer.TYPE,的Class.forName(com.android.nfc_extras.NfcExecutionEnvironment));
        对象routeOn = c.newInstance(1,NULL);

        CLS级= nfcExtras.getClass();
        方法的mtd = cls.getMethod(setCardEmulationRoute,CS [0]);
        mtd.invoke(nfcExtras,routeOn);
    }赶上(的InvocationTargetException EE){
        Log.w(EnableCardEmu,ee.getTargetException());
    }赶上(例外五){
        Log.w(EnableCardEmu,e.getClass()的getName()+/+ e.getMessage());
    }
}

    私人无效activateCardEmulation(){
    尝试{

        类CLSS =的Class.forName(com.android.nfc_extras.NfcAdapterExtras);
        类[] CS = clss.getDeclaredClasses();
        / *
        对于(CC级:CS){
            Log.w(EnableCardEmu,cc.getName())
        } * /

        //类路径=的Class.forName(com.android.nfc_extras.NfcAdapterExtras $ CardEmulationRoute);
        构造函数C = CS [0] .getConstructor(Integer.TYPE,的Class.forName(com.android.nfc_extras.NfcExecutionEnvironment));
        对象routeOn = c.newInstance(2,embebbed);

        CLS级= nfcExtras.getClass();
        方法的mtd = cls.getMethod(setCardEmulationRoute,CS [0]);
        mtd.invoke(nfcExtras,routeOn);
    }赶上(的InvocationTargetException EE){
        Log.w(EnableCardEmu,ee.getTargetException());
    }赶上(例外五){
        Log.w(EnableCardEmu,e.getClass()的getName()+/+ e.getMessage());
    }
}
 

解决方案

我想问题可能是对象routeOn = c.newInstance(2 embebbed)。它看起来像这样的对象是错误的类型(我不是读书的反射code的专家,虽然)。

这是我如何做到这一点,没有反思,并能正常工作(同时具有ISO 14443-4A卡和MIFARE经典卡是通过同时在设备仿真):

 上下文mContext; //初始化此
NfcAdapterExtras mAdapterExtras =
  NfcAdapterExtras.get(NfcAdapter.getDefaultAdapter(mContext));
NfcExecutionEnvironment MEE = mAdapterExtras.getEmbeddedExecutionEnvironment();
mAdapterExtras.setCardEmulationRoute(
  新CardEmulationRoute(CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON,MEE));
 

没有必要修改libnfc-NXP这一点。

I need help with NFC and Android.

After making a lot of research to enable the emulation of a Mifare 4K on Android, I've found that the only patch that exists was made for 2.3.4. Here in StackOverFlow, NFCGuy told us since API 14 of Android it's not neccesary patch the ROM, so we can turn on card emulation using the hidden Nfc_extras package.

I've compiled an APK using NFC_EXTRAS with reflection, and added my signature and package to the nfcee_access.xml.

After I set cardEmulationRoute to ON_WHEN_SCREEN_ON, I get an output in logcat telling me that NFCEE is ON and NFC_CC is ON, but when I get my Nexus S close to a ACR122 it does not detect the Emulated Mifare 4K that 2.3.4 patch makers could get. I can get an unrecognized Smart Card (I suppose that it's the SE acting like a smartcard) but i need to use the emulated Mifare.

Do I need to modify lib-nfc as it was modify in 2.3.4 patch to get that applet working (Mifare Manager)? Or with my app accesing that package should be enought?

I'm downloading the android source to port the 2.3.4 patch to 4.1, but looking at the diff they've posted, there is only a difference with 4.1 on lib-nfc library. (A define commented, used for card emulation in theory)

Maybe it's not necesary to recompile a modified ROM and I'm missing a small step to get the emulated Mifare 4k.

Thanks for your help to all people here in StackOverFlow

Regards

    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());
    }
}

解决方案

I think the problem could be in Object routeOn = c.newInstance(2, embebbed). It looks like this object is of the wrong type (I am not an expert on reading reflection code, though).

This is how I do it, without reflection, and it works fine (both an ISO 14443-4A card and a MIFARE Classic card are emulated by the device simultaneously):

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));

No need to modify libnfc-nxp for this.

这篇关于在Android ICS与NFC_EXTRAS启用CardEmulation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆