点击按钮,开始从NFC设备传输数据

时间:2012-04-13 19:07:24

标签: android nfc

我正在开发基于NFC的应用程序,我们从NFC设备获取数据。但是,当我们将支持NFC的Android设备带到NFC设备旁边时,会出现一个对话框,其中列出了所有基于NFC的应用程序,因此其中一个也是我的。当我们从列表中单击我们的应用程序图标时,它会从我的应用程序(名为NfcActivity)打开一个活动,并开始将数据传输到Android手机我不想要。在该Activity中有两个按钮也可以更新和取消。 我想当我们点击更新按钮然后NFC设备开始使用进度条将数据传输到手机时如果数据将完全传输则进度条会自动关闭。我不能这样做,如果您对此有任何建议,请建议我。

提前致谢。

NfcActivity:

package com.a1technology.impak;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.nfc.NfcAdapter;
import android.nfc.tech.IsoDep;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.a1technology.impak.db.DBAdapter;
import com.cypak.mobile.bridge.android.CypakDevice;
import com.cypak.mobile.bridge.android.CypakDeviceListener;
import com.cypak.mobile.bridge.android.NfcTransportService;
import com.cypak.mobile.bridge.android.TransportBinder;



public class NfcActivity extends Activity implements CypakDeviceListener {

    private boolean update = false;

    private String TAG = "NfcExampleActivity";

    List<EventByteGetSet> eventList = new ArrayList<EventByteGetSet>();

    // Required for foreground dispatch
    private String[][] techListsArray = new String[][] { new String[] { IsoDep.class.getName() } };

    private NfcAdapter mAdapter;

    private PendingIntent pendingIntent;

    // Required when binding to NfcTransportService
    private NfcTransportService mService;

    private boolean bound = false;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.nfc_activity);

        findViewById(R.id.cancel_button).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                finish();
            }
        });
        findViewById(R.id.update_button).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                update = true;
            }
        });
        // Required for foreground dispatch
        pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), NfcActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        mAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());// Connecting
                                                // to
                                                // the
                                                // adapter

        resolveIntent(getIntent());

        Intent intent = new Intent(this, NfcTransportService.class);
        // Bind to the service
        if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
            Log.e(TAG, "Failed to bind service");
        }
    }


    @Override
    protected void onPause() {

        super.onPause();
        // finish();
        // Required for foreground dispatch
        mAdapter.disableForegroundDispatch(this);

    }


    @Override
    protected void onDestroy() {

        super.onDestroy();

        if (bound) {
            unbindService(mConnection);
            bound = false;
        }
    }


    @Override
    protected void onResume() {

        super.onResume();

        // Required for foreground dispatch
        mAdapter.enableForegroundDispatch(this, pendingIntent, null, techListsArray);
    }


    @Override
    protected void onNewIntent(Intent intent) {

        super.onNewIntent(intent);
        setIntent(intent);
        resolveIntent(intent);
    }


    private void resolveIntent(Intent intent) {

        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())// need
                                                // to
                                                // find
                                                // what
                                                // action
                                                // is
                                                // coming
            && mService != null) {
            // Let NfcTransportService handle the Nfc Intent
            try {
                mService.handleIntent(intent);
            }
            catch (IOException e) {
                Log.w(TAG, "Failed to detect device", e);
            }

        }
    }

    /**
     * Defines callbacks for service binding, passed to bindService(). Only
     * needed if binding to MyMaxTransportService
     * */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {

            // We've bound to NfcTransportService, cast the IBinder and
            // get NfcTransportService instance
            Log.v(TAG, "Service connected");
            TransportBinder binder = (TransportBinder) service;
            mService = (NfcTransportService) binder.getService();
            bound = true;

            mService.registerDeviceListener(NfcActivity.this);
        }


        @Override
        public void onServiceDisconnected(ComponentName name) {

            Log.v(TAG, "Service disconnected");
            bound = false;
        }
    };


    @Override
    public void deviceDiscovered(CypakDevice device) {

        // String hex = "1";
        // byte[] byteClear= hex.getBytes();
        //

        if (!update) {
            return;
        }
        else
            try {
                // byte[] byteData= device.sendAppCommand((byte)
                // 0x11, byteClear);
                NFCDataHandler mNfcDataHandler = new NFCDataHandler(this);
                byte[] byteStatusData = device.sendAppCommand((byte) 0x00, new byte[0]);
                String stateHCC = mNfcDataHandler.getStatus(byteStatusData);
                if (stateHCC.equalsIgnoreCase("04")) {
                    byte[] byteQueLogData = device.sendAppCommand((byte) 0x05, new byte[0]);
                    if (byteQueLogData.length < 6) {
                        ShowMessage("Warning", "Card is Empty");
                        return;
                    }
                    mNfcDataHandler.getQueLog(byteQueLogData);
                }
                else {
                    ShowMessage("Warning", "Card is not Active");
                    return;

                }

                Log.v("Value", "");
            }
            catch (com.cypak.mobile.bridge.android.AppCommandErrorCodeException e) {
                Log.e(TAG, "AppCommandErrorCodeException, error code " + e.getErrorCode(), e);
            }
            catch (com.cypak.mobile.bridge.android.AppCommandException e) {
                Log.e(TAG, "AppCommandException", e);
            }
            catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        // Toast.makeText(getApplicationContext(), "Device found! " +
        // device, Toast.LENGTH_LONG).show();
    }


    @Override
    public void invalidDeviceDiscovered(CypakDevice device) {

        Toast.makeText(getApplicationContext(), "Invalid device!", Toast.LENGTH_SHORT).show();
    }


    @Override
    public void deviceLost() {

        Toast.makeText(getApplicationContext(), "Device lost!", Toast.LENGTH_SHORT).show();
    }


    protected Date dateFromlongBuffer(long bb) {

        return new Date((long) 1000 * (long) bb);
    }


    protected Date dateFromByteBuffer(ByteBuffer bb) {

        return new Date((long) 1000 * (long) bb.getInt());
    }

    static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b',
            (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' };


    public static String getHexString(byte[] raw) throws UnsupportedEncodingException {

        byte[] hex = new byte[2 * raw.length];
        int index = 0;

        for (byte b : raw) {
            int v = b & 0xFF;
            hex[index++] = HEX_CHAR_TABLE[v >>> 4];
            hex[index++] = HEX_CHAR_TABLE[v & 0xF];
        }
        return new String(hex, "ASCII");
    }


    public static int hex2decimal(String s) {

        String digits = "0123456789ABCDEF";
        s = s.toUpperCase();
        int val = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            int d = digits.indexOf(c);
            val = 16 * val + d;
        }
        return val;
    }


    private void ShowMessage(String title, String message) {

        AlertDialog.Builder b = new AlertDialog.Builder(this);
        AlertDialog a = b.create();
        a.setTitle(title);
        a.setMessage(message);
        a.setButton("Ok", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {

                finish();
            }
        });

        a.show();
    }
}

1 个答案:

答案 0 :(得分:0)

您似乎在resolveIntent()中呼叫onCreate()。当您从应用选择器中选择应用时,已发现的NFC Intent已通过Activity传递到您的onCreate(),我认为您在呼叫时{{1}正在处理它}}。因此,每当您的应用程序从NFC Discovery启动时,您立即将Intent传递给mService.handleIntent(intent);。根据您的问题,您似乎希望在收到NFC数据时将其从Service中取出,存储该数据,然后在按下“更新”按钮时调用您的服务。

Intent

因此,您最终会立即将NFC Intent传递给您的服务:

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.nfc_activity);

    findViewById(R.id.cancel_button).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            finish();
        }
    });
    findViewById(R.id.update_button).setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            update = true;
        }
    });
    // Required for foreground dispatch
    pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), NfcActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    mAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());// Connecting
                                            // to
                                            // the
                                            // adapter
    // HERE, this could be the Intent from the NFC Discovery
    **resolveIntent(getIntent());**

    Intent intent = new Intent(this, NfcTransportService.class);
    // Bind to the service
    if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
        Log.e(TAG, "Failed to bind service");
    }
}

您是否要等到用户在您的回调方法private void resolveIntent(Intent intent) { if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())// need // to // find // what // action // is // coming && mService != null) { // Let NfcTransportService handle the Nfc Intent try { // HERE: you are handling the NFC Intent via onCreate() mService.handleIntent(intent); } catch (IOException e) { Log.w(TAG, "Failed to detect device", e); } } } 被调用之前点击该按钮?