您的位置:首页 > 其它

工程项目CPU卡读取数据信息。

2017-12-08 08:10 274 查看
/**

 * 设备服务,用于在后台运行,发送命令和接收数据

 * 在服务初始化时,执行串口打开,设备电源开启,

 * 获取串口输入输出流

 * 启动读数据线程

 *DeviceService 类

【布局文件】

<?xml version="1.0" encoding="UTF-8"?>

<!-- 非接触cpu卡 -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/cpu_card"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_alignParentTop="true"

        android:layout_marginTop="30dp"

        android:orientation="vertical" >

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginTop="10dp"

            android:orientation="horizontal" >

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:text="@string/send_data" />

            <EditText

                android:id="@+id/ucpu_send_data"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:singleLine="true" />

        </LinearLayout>

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginTop="10dp"

            android:orientation="horizontal" >

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:text="@string/receive_data" />

            <EditText

                android:id="@+id/ucpu_receive_data"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                 />

        </LinearLayout>

<LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginTop="20dp"

            android:orientation="horizontal" >

            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:text="定义读取数据后保存名称为:" />

            <EditText

                android:id="@+id/fileName"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:singleLine="true" />

        </LinearLayout>     

    </LinearLayout>

 
4000
  <TableLayout

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:layout_centerHorizontal="true" >

        <TableRow

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_weight="2" >

            <Button

                android:id="@+id/ucpu_active_card"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="@string/active_card" />

           <Button

                android:id="@+id/ucpu_selectLenEF1"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="选择EF1"           

                />  

                  <Button

                android:id="@+id/ucpu_selectLenEF2"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="选择EF2"               

                />  

           <Button

                android:id="@+id/ucpu_readLen"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="读长度"                 

                />                  

        </TableRow>

        <TableRow

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_weight="2" >                        

             <Button

                android:id="@+id/ucpu_read"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="读文件" />                           

        </TableRow>

         <TableRow

            android:layout_width="fill_parent"

            android:layout_height="wrap_content"

            android:layout_weight="2" >          

              <Button

                android:id="@+id/ucpu_send_cmd"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="发送指令" />

             <Button

                android:id="@+id/ucpu_close_card"

                android:layout_width="0dp"

                android:layout_height="wrap_content"

                android:layout_weight="1"

                android:text="@string/close_card"                 

                />                

        </TableRow>

    </TableLayout>
</RelativeLayout>

【读取类】

package com.example.psam_demo;

import java.io.File;

import java.io.FileOutputStream;

import java.text.DecimalFormat;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Semaphore;

import com.android.rfid.PSAM;

import com.android.rfid.Tools;

import com.example.service.DeviceService;

import android.app.Activity;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.os.Environment;

import android.os.Looper;

import android.util.Log;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

public class UcpuSplitReadActivity extends Activity implements OnClickListener {
private EditText receive_data,send_data,fileName;
private Button active_card,cpu_read,ucpu_readLen,close_card,send_cmd;
private Button ucpu_selectLenEF1,ucpu_selectLenEF2;
private MyBroadcast myReceiver;  //广播接收者
private PSAM mpsam;
private String TAG = "读取类";
private String activity = "com.example.psam_demo.UcpuSplitReadActivity";
public int cmd_flag = 0; 

    ExecutorService readexec = Executors.newCachedThreadPool(); // 只能1个线程同时访问

    final Semaphore readsemp = new Semaphore(1);

  
//接收数组  
long ff=0;
boolean isread=false;
List<byte[]>  byteList=new ArrayList<byte[]>() ;
long EF_len=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ucpu_split_read);
              //初始化
init();
}

private void init() {
fileName= (EditText) findViewById(R.id.fileName);
send_data = (EditText) findViewById(R.id.ucpu_send_data);
receive_data = (EditText) findViewById(R.id.ucpu_receive_data);
active_card = (Button) findViewById(R.id.ucpu_active_card);
close_card = (Button) findViewById(R.id.ucpu_close_card);
send_cmd = (Button) findViewById(R.id.ucpu_send_cmd);
ucpu_selectLenEF1=(Button) findViewById(R.id.ucpu_selectLenEF1);
ucpu_selectLenEF2=(Button) findViewById(R.id.ucpu_selectLenEF2);
ucpu_readLen= (Button) findViewById(R.id.ucpu_readLen);
cpu_read = (Button) findViewById(R.id.ucpu_read);

active_card.setOnClickListener(this);
ucpu_selectLenEF1.setOnClickListener(this);
ucpu_selectLenEF2.setOnClickListener(this);
ucpu_readLen.setOnClickListener(this);
cpu_read.setOnClickListener(this);
send_cmd.setOnClickListener(this);
close_card.setOnClickListener(this);
}
@Override
protected void onResume() {
myReceiver = new MyBroadcast();
mpsam = new PSAM();//实例化mpsam,用于调用协议封装命令
IntentFilter filter = new IntentFilter();
filter.addAction(activity);
registerReceiver(myReceiver, filter);
//注册广播接收者
super.onResume();

}

@Override
protected void onPause() {
unregisterReceiver(myReceiver);  //卸载广播接收者
cmd_flag = 0;
super.onPause();
}
private class ReadThread extends Thread {

long ff=0;//一次读取200字节,要读多少个200的长度数据,算出要 读的次数
long yu=0;
public ReadThread(long ff, long yu) {
this.ff=ff;
this.yu=yu;
}
@Override
public void run() {
super.run();
Looper.prepare();
 
 
 byte[] mycmd=null;
 
 synchronized (this) {
 for(int a=1;a<=(ff+1);a++){//首次读取200字节,位置从3开始, ff+1读不足200的余数据
 

 try {
readsemp.acquire();
Thread.sleep((long) (Math.random() * 3000));
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 Intent myservice = new Intent(UcpuSplitReadActivity.this,DeviceService.class);  //用于发送指令
    int offset=(200*(a-1)+3);//+3=前三字节为数据长度,后面的才是数据
String offsetHexString=Integer.toHexString(offset);//读取偏移量
String cmdHead="";//根据偏移量改变P1P2命令头
if(offsetHexString.length()==1){
cmdHead="00B0000"+offsetHexString+"C8";
}else if(offsetHexString.length()==2){
cmdHead="00B000"+offsetHexString+"C8";
}else if(offsetHexString.length()==3){
cmdHead="00B00"+offsetHexString+"C8";
}else{
cmdHead="00B0"+offsetHexString+"C8";
}
//Log.e("读取==偏移量", offsetHexString+"=="+"");
if(a!=(ff+1)){
 mycmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes(cmdHead));

//读取
cmd_flag = 25;
// byte[] mycmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes(cmdHead));
 myservice.putExtra("cmd", mycmd); 
 UcpuSplitReadActivity.this.startService(myservice); 
           Log.e("my发送read: " +a +"==", cmdHead+"=="+"");
           try {
Thread.sleep( 3000);
} catch (InterruptedException e) {
e.printStackTrace();
}//

}else{//ff+1读余数据 yu==0不发送
if(yu!=0){
String lastDataLength=Integer.toHexString((int)yu);//最后一次要读的数据长度

// cmdHead.replace("C8", lastDataLength);
String yuHead="";
if(offsetHexString.length()==1){
yuHead="00B0000"+offsetHexString;
}else if(offsetHexString.length()==2){
yuHead="00B000"+offsetHexString;
}else if(offsetHexString.length()==3){
yuHead="00B00"+offsetHexString;
}else{
yuHead="00B0"+offsetHexString;
}
if(lastDataLength.length()==1){
cmdHead=yuHead+"0"+lastDataLength;
}else if(lastDataLength.length()==2){
cmdHead=yuHead+lastDataLength;
}
 
 
// Log.e("my替换: "+cmdHead,"");
mycmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes(cmdHead));

//读取
cmd_flag = 25;
// byte[] mycmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes(cmdHead));
 myservice.putExtra("cmd", mycmd); 
 UcpuSplitReadActivity.this.startService(myservice); 
           Log.e("后my发送read: " +a +"==", cmdHead+"=="+"");
         
           readexec.shutdownNow();//

}

}
 
 

 
 
}//for
 }//syn
 
 
Looper.loop();
}
}

@Override
public void onClick(View v) {
// 给服务发送广播,内容为com.example.psam_demo.M1CardActivity
Intent ac = new Intent();
ac.setAction("com.example.service.DeviceService");
ac.putExtra("activity", activity);
sendBroadcast(ac);
Log.e(TAG, "send broadcast");

receive_data.setText(""); //清空数据
byte[] cmd = null; // 用于存放指令
Intent sendToservice = new Intent(UcpuSplitReadActivity.this,DeviceService.class);  //用于发送指令

switch (v.getId()) {
case R.id.ucpu_active_card:  //激活卡片
cmd_flag = 1;
cmd = mpsam.ucpu_open();
if(cmd != null){
Log.e(TAG, Tools.Bytes2HexString(cmd, cmd.length));
}else{

}
break;
case R.id.ucpu_selectLenEF1://选择文件 获取读取数据长度
cmd_flag = 2;
cmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes("00A4000002200100"));
if(cmd != null){                                 
Log.e(TAG, Tools.Bytes2HexString(cmd, cmd.length));
}else{

}
break;

case R.id.ucpu_selectLenEF2://选择文件 获取读取数据长度
cmd_flag = 2;
cmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes("00A4000002200200"));
if(cmd != null){                                 
Log.e(TAG, Tools.Bytes2HexString(cmd, cmd.length));
}else{

}
break;

case R.id.ucpu_readLen://读取cpu卡某文件的前3字节6位长度数据,以获得该文件长度。3字节6位数据中,长度是数字,不足6位补C.
cmd_flag = 3;
cmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes("00B0000003"));
if(cmd != null){                                 
Log.e(TAG, Tools.Bytes2HexString(cmd, cmd.length));
}else{

}
break;
case R.id.ucpu_read://
if(EF_len>200){//数据信息大于200,循环读取
double pi =EF_len/200;// 
String nn=new DecimalFormat("0000").format(pi);
ff= Long.parseLong(nn);//一次写200字节,写图片的长度数据,算出要 写的次数
long yu=EF_len%200;
Log.e(nn+"获取图片模板"+EF_len+"==", ff+"==ff==yu"+yu);
if(!isread){
synchronized(this){
if(byteList.size()>0&&byteList!=null){
       byteList.clear();
       }
  ReadThread
mReadThread = new ReadThread(ff,yu);
  mReadThread.start();
}
}else{
Toast.makeText(getApplicationContext(), "请等待读取完毕!", Toast.LENGTH_SHORT).show();
}
}else{//数据信息小于200,直接读取偏移量03
String readLen=Integer.toHexString((int)EF_len);//读取长度转16进制
String cmdHead="";//根据偏移量改变P1P2命令头
if(readLen.length()==1){
cmdHead="00B000030"+readLen;
}else if(readLen.length()==2){
cmdHead="00B00003"+readLen;
}

 cmd_flag = 25;
 cmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes(cmdHead));

 Log.e("直接读取不足200的文件"+EF_len+"==", "");

}
break;
case R.id.ucpu_send_cmd://
发送命令
cmd_flag = 5;
String data = send_data.getText().toString();
cmd = mpsam.ucpu_send_cmd(Tools.HexString2Bytes(data));
if(cmd != null){
Log.e(TAG, Tools.Bytes2HexString(cmd, cmd.length));
}else{

}
break;
case R.id.ucpu_close_card:   //关闭卡片
cmd_flag = 6;
cmd = mpsam.ucpu_close();
if(cmd != null){
Log.e(TAG, Tools.Bytes2HexString(cmd, cmd.length));
}else{

}

break;

default:
break;
}
sendToservice.putExtra("cmd", cmd);
UcpuSplitReadActivity.this.startService(sendToservice);  //发送指令给
}

/**
*  广播接收者,接收服务发送过来的数据,并更新UI
* @author Administrator
*
*/
private class MyBroadcast extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

String receivedata = intent.getStringExtra("result"); // 服务返回的数据
if (receivedata != null) {
switch (cmd_flag) {
case 1:
byte []active_buffer1 = Tools.HexString2Bytes(receivedata);
byte []active_data1 = mpsam.resolveDataFromDevice(active_buffer1);
if(active_data1 != null){
receive_data.setText(Tools.Bytes2HexString(active_data1, active_data1.length));
//Toast.makeText(getApplicationContext(), "激活卡片成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "激活卡片失败", Toast.LENGTH_SHORT).show();
}
break;
case 2://select EF1
byte []active_buffer2 = Tools.HexString2Bytes(receivedata);
byte []active_data2 = mpsam.resolveDataFromDevice(active_buffer2);
if(active_data2 != null){
receive_data.setText(Tools.Bytes2HexString(active_data2, active_data2.length));
}else{
}
break;
case 3://read EF1 length
byte []active_buffer3 = Tools.HexString2Bytes(receivedata);
byte []active_data3 = mpsam.resolveDataFromDevice(active_buffer3);
if(active_data3 != null){
String response=Tools.Bytes2HexString(active_data3, active_data3.length);
String len=response.substring(0, response.indexOf("C"));//要读的数据长度,3字节6位。如读取数据位:08CCCC 说明长度为08,CCCC是补足部分,对数据进行截取,以C首次出现的位置做接束,即可获得后续3字节之后的信息数据长度是多少。然后根据EF_len依次读取200,算出要的的次数。EF_len+1等于要读的不足200的部分既多读一次。
EF_len=Long.parseLong(len);
receive_data.setText(EF_len+"");
Log.e("rrrrrrr=="+len, "sssssssss"+EF_len);

}else{
}
break;
case 4://select EF2
byte []active_buffer4 = Tools.HexString2Bytes(receivedata);
byte []active_data4 = mpsam.resolveDataFromDevice(active_buffer4);
if(active_data4 != null){
receive_data.setText(Tools.Bytes2HexString(active_data4, active_data4.length));

}else{
}
break;
case 5://cmd
byte []uu = Tools.HexString2Bytes(receivedata);
byte []data = mpsam.resolveDataFromDevice(uu);
if(data != null){
receive_data.setText(Tools.Bytes2HexString(data, data.length));
}else{
}
break;
case 6://close
byte []close_buffer = Tools.HexString2Bytes(receivedata);
int close_data = mpsam.rf_check_data(close_buffer);
if(close_data != 0){
Toast.makeText(getApplicationContext(), "关闭卡片失败", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "关闭卡片成功", Toast.LENGTH_SHORT).show();
}
break;
case 25: //read EF2 data
synchronized(this){
String hh=receivedata.substring(12, receivedata.length()-8);
byte [] JJ = Tools.HexString2Bytes(hh);

// byte [] JJ = Tools.HexString2Bytes(receivedata);

Log.e("读25文件返回数据==", Tools.Bytes2HexString(JJ, JJ.length));

if(JJ != null){
byteList.add(JJ);

}
readsemp.release();

 
 
if(fileName.getText().toString()!=null&&!fileName.getText().toString().equals("")){
String name= fileName.getText().toString();
   try {  
    String pathMoban=MyApplication.filePath+"/"+name;
// String pathMoban=Environment.getExternalStorageDirectory()+"/KHDZ_Device/"+name;
File file = new File(pathMoban);  
file.createNewFile();
       FileOutputStream fos = new FileOutputStream(file,false);  
       Log.e("拆分写入=="+pathMoban,"==");
       for (int i = 0; i < byteList.size(); i++) { 
       
Log.e("aa22集合数据=="+i+"=="+ff, Tools.Bytes2HexString(byteList.get(i), byteList.get(i).length)+"");
       
fos.write(byteList.get(i));  

       if(i==ff){//接收次数==写入的次数   说明读取完毕。
       
receive_data.setText("read over !");
       
isread=false;
       
break;
       }else{
       
isread=true;
       
receive_data.setText("reading !");
       }
       
       } 
     
       fos.close();
       } catch (Exception e) {  
       
receive_data.setText("Exception !");
       
// Log.e("写入yi==","=="+e);
           e.printStackTrace();  
       } 
}else{
 Toast.makeText(getApplicationContext(), "请输入文件要保存的名称!", Toast.LENGTH_SHORT).show();
}
 
 
    break;

default:
break;

}
}
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐