工程项目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;
}
}
}
}
}
* 设备服务,用于在后台运行,发送命令和接收数据
* 在服务初始化时,执行串口打开,设备电源开启,
* 获取串口输入输出流
* 启动读数据线程
*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;
}
}
}
}
}
相关文章推荐
- 江西省建设工程安全质量监督管理局全省工程安全质量信息数据维护升级存储及异地备份项目中标公告
- python项目:获取微信好友信息(二)csv数据读取与处理
- 工程项目CPU白卡写入数据信息。
- 项目____SSH框架下Ajax数据通信过程中数据读取不到的问题
- 雅安市人民医院信息系统容灾工程采购项目&CDP连续数据保护需求
- c# winform项目treeview控件绑定本地电脑磁盘信息,读取文件夹信息,显示文件夹内文件内容
- HTML/Ajax/XML数据交互:HTML通过Ajax读取XML的存储信息
- Java 数据保存与读取,保存数据信息并加密
- 第二周 项目二:读取数据到结构体数组
- 关于取消“计算机信息系统集成企业资质认定”、“计算机信息系统集成项目经理人员资质评定”和“信息系统工程监理单位资质认证和监理工程师资格认定”
- 小项目-数据可视化:应用dash将工作信息呈现在地图上
- 小项目-数据处理篇:租房信息整理,plotly实现数据可视化
- 项目管理工作执行数据和信息流向的一致性
- Matlab批量读取元胞数组中数据保存到txt文件中(WIDER FACE数据集中,读取人脸标注矩形框信息)
- php读取excel文件的数据信息
- 实习笔记——如何把实验室科研数据分析项目变成能部署到生产环境中的工程
- kettle读取文件目录下的数据结构一致的所有数据文件信息和内容
- 项目管理过程 工作绩效数据,信息和报告
- 第十四周 项目2.3 带姓名的成绩单(从文件中读取数据然后经过成绩排序姓名排序处理)
- 第14周 项目2-3 读取数据后进行排序