0

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

提前致谢。

Nfc活动:

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

1 回答 1

0

看起来你在resolveIntent()打电话onCreate()。当您从应用程序选择器中选择您的应用程序时,NFC DiscoveredIntent将传递给您的Activityvia onCreate(),我假设您在调用时立即处理它mService.handleIntent(intent);。因此,每次您的应用程序从 NFC Discovery 启动时,您都会立即将 Intent 传递给您的Service. 从您的问题来看,您似乎想在收到 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");
    }
}

因此您最终会立即将 NFC 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 {
            // HERE: you are handling the NFC Intent via onCreate()
            mService.handleIntent(intent);
        }
        catch (IOException e) {
            Log.w(TAG, "Failed to detect device", e);
        }

    }
}

难道你不想等到用户点击你的回调方法之前的按钮,deviceDiscovered()被调用?

于 2012-04-13T19:19:51.357 回答