I am writing a an Android app which is essentially an network based tic tac toe, There is a server on the computer an two Android phones as clients playing against each other. To accomplish this task I created a multithreaded server that can deal with both clients, and I created the two clients and I made them receive what the server sends them in a separate thread and using a handler I change the UI once the server sends the other player's move.
The problem is that the serverThread never recognizes what any of the clients send. The protocol I am using between the client and the server is a number based protocol, once the client clicks on a tile, a number is sent to the server, the server adds this number to an array, and sends it to all the threads(Both clients) so that they can change this tile from tile to "X" or "O" depending on the number
Here is the code for the listener of two buttons, all other buttons are similar
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (value == 1) {
numberSent = 0;
Global.os.println(Integer.toString(0));
Global.os.flush();
Log.i("Sent", "The Zero");
}
else if (value == 2) {
numberSent = 9;
Global.os.println(Integer.toString(Activity2.numberSent));
Global.os.flush();
}
}
});
b2.setImageResource(R.drawable.tile);
b2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(value == 1) {
numberSent = 1;
Global.os.println(Integer.toString(Activity2.numberSent));
Global.os.flush();
}
else if(value == 2) {
numberSent = 10;
Global.os.println(Integer.toString(Activity2.numberSent));
Global.os.flush();
}
}
});
Here is the code for the ClientThread (The one that handles messages recieved from the server and has the handler that changes the UI)
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.util.Log;
public class ClientThread implements Runnable {
int s;
public void run() {
try {
try {
Global.s = new Socket("10.0.2.2", 5555);
Global.is = new DataInputStream(Global.s.getInputStream());
Global.os = new PrintStream(Global.s.getOutputStream());
Global.os.println(Integer.toString(100));
Log.i("Socket", "Created");
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
Log.i("In the", "While");
try {
String S = null;
while ((S = Global.is.readLine()) != null) {
Log.d("ServerActivity", "line");
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Global.os.print(Integer.toString(Activity2.numberSent));
try {
String S = Global.is.readLine();
s = Integer.parseInt(S);
if (s == 0) {
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b1.setImageResource(R.drawable.x);
}
});
}
else if(s == 1){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b2.setImageResource(R.drawable.x);
}
});
}
else if(s == 2){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b3.setImageResource(R.drawable.x);
}
});
}
else if(s == 3){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b4.setImageResource(R.drawable.x);
}
});
}
else if(s == 4){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b5.setImageResource(R.drawable.x);
}
});
}
else if(s == 5){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b6.setImageResource(R.drawable.x);
}
});
}
else if(s == 6){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b7.setImageResource(R.drawable.x);
}
});
}
else if(s == 7){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b8.setImageResource(R.drawable.x);
}
});
}
else if(s == 8){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b9.setImageResource(R.drawable.x);
}
});
}
else if(s == 9){
Activity2.handler.post(new Runnable() {
public void run() {
Activity2.b1.setImageResource(R.drawable.o);
}
});
}
else if(s == 10){
Activity2.handler.post(new Runnable() {
public void run() {
Activity2.b2.setImageResource(R.drawable.o);
}
});
}
else if(s == 11){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b3.setImageResource(R.drawable.o);
}
});
}
else if(s == 12){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b4.setImageResource(R.drawable.o);
}
});
}
else if(s == 13){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b5.setImageResource(R.drawable.o);
}
});
}
else if(s == 14){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b6.setImageResource(R.drawable.o);
}
});
}
else if(s == 15){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b7.setImageResource(R.drawable.o);
}
});
}
else if(s == 16){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b8.setImageResource(R.drawable.o);
}
});
}
else if(s == 17){
Activity2.handler.post(new Runnable() {
#Override
public void run() {
Activity2.b9.setImageResource(R.drawable.o);
}
});
}
else {
}
} catch (IOException e) {
e.printStackTrace();
}
});
}
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
}
}
}
Here is the code of my server thread
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
class ServerThread extends Thread {
DataInputStream is = null;
PrintStream os = null;
Socket clientSocket = null;
ServerThread t[];
public String received;
public ServerThread(Socket clientSocket, ServerThread[] t){
this.clientSocket=clientSocket;
this.t=t;
}
public void run() {
try {
is = new DataInputStream(clientSocket.getInputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
os = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
try{
// Once the socket is open all the work will be here!!!!!!
while(true) {
System.out.print("In the while");
received = is.readLine();
int s = Integer.parseInt(received);
if(s == 100) {
System.out.print("I recieved the 100");
}
if(s == 0) {
System.out.println("I recieved the 0");
XOServer.boardArray[0] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 0;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 1) {
XOServer.boardArray[1] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 1;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 2) {
XOServer.boardArray[2] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 2;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 3) {
XOServer.boardArray[3] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 3;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 4) {
XOServer.boardArray[4] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 4;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 5) {
XOServer.boardArray[5] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 5;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 6) {
XOServer.boardArray[6] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 6;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 7) {
XOServer.boardArray[7] = 1;
XOServer.turn = true;
System.out.print("I recieved the 7");
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 7;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 8) {
XOServer.boardArray[8] = 1;
XOServer.turn = true;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 8;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 9) {
XOServer.boardArray[0] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 9;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 10) {
XOServer.boardArray[1] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 10;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 11) {
XOServer.boardArray[2] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 11;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 12) {
XOServer.boardArray[3] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 12;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 13) {
XOServer.boardArray[4] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 13;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 14)
XOServer.boardArray[5] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 14;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 15) {
XOServer.boardArray[6] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 15;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 16) {
XOServer.boardArray[7] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 16;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else if(s == 17) {
XOServer.boardArray[8] = 2;
XOServer.turn = false;
for(int i = 0; i<=t.length; i++) {
if (t[i]!=null) {
XOServer.sentValue = 17;
t[i].os.println(Integer.toString(XOServer.sentValue));
t[i].os.flush();
}
}
}
else {
}
}
}
catch (Exception e){
System.out.print(e);
}
}
Here is the code for my server
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class XOServer{
// Declaration section:
// declare a server socket and a client socket for the server
// declare an input and an output stream
static Socket clientSocket = null;
static ServerSocket serverSocket = null;
static PrintStream os = null;
static DataInputStream is = null;
static int sentValue;
// This chat server can accept up to 10 clients' connections
static ServerThread t[] = new ServerThread[10];
public static int [] boardArray = new int[9];
public static boolean turn = false;
public static void main(String args[]) {
// The default port
int port_number=5555;
if (args.length < 1) {
System.out.println("Usage: java MultiThreadChatServer \n"+
"Now using port number="+port_number);
} else {
port_number=Integer.valueOf(args[0]).intValue();
}
for(int i = 0; i <=8; i++ ) {
boardArray[i] = 0;
}
// Initialization section:
// Try to open a server socket on port port_number (default 2222)
// Note that we can't choose a port less than 1023 if we are not
// privileged users (root)
try {
serverSocket = new ServerSocket(port_number);
}
catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams for this socket will be created in
// client's thread since every client is served by the server in
// an individual thread
while (true) {
try {
clientSocket = serverSocket.accept();
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
for(int i=0; i<=9; i++){
if(t[i]==null) {
(t[i] = new ServerThread(clientSocket,t)).start();
break;
}
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
}
I think your problem (or at least one problem) is on the server. When the client connects you are setting:
os = new PrintStream(clientSocket.getOutputStream());
os is a static variable inside of the server. This is wrong.
static PrintStream os
Each client thread must have it's own separate PrintStream. You will need to get the input/output streams and pass them into your handler.
clientSocket = serverSocket.accept();
DataInputStream is = new DataInputStream(clientSocket.getInputStream());
PrintStream os = new PrintStream(clientSocket.getOutputStream());
... new ServerThread(is, os, clientSocket, t)).start();
Also, I don't understand why you fork 10 threads for each client connection. That seems wrong. Typically you could accept a client connection and then fork 1 thread to handle that specific connection with that input and output streams.
Related
to be able using a remote service through localhost IP (to hide real address from users in other intents) I am using this service to port-forwarding :
public class PortForward extends Service implements Runnable {
private static final String TAG = "Port Forward";
private int localPort;
private int remotePort;
private String remoteHost;
private boolean running = false;
private int lastUp = -1;
private int lastDown = -1;
private int bUp = 0;
private int bDown = 0;
LocalBroadcastManager bm;
private Thread t;
ServerSocketChannel serverSocketChannel = null;
public Handler sendBroadcastHandler = new Handler() {
public void handleMessage(Message msg) {
Intent i = new Intent().setAction(MainActivity.USAGE_UPDATE);
i.putExtra("bUp", bUp);
i.putExtra("bDown", bDown);
bm.sendBroadcast(i);
}
};
public Handler sendDeathHandler = new Handler() {
public void handleMessage(Message msg) {
Bundle b = msg.getData();
String causeOfDeath = b.getString("causeOfDeath", "unknown");
Notification note = new Notification.Builder(PortForward.this)
.setContentTitle("TCP forwarding thread dead")
.setContentText("Cause of death: " + causeOfDeath)
.setSmallIcon(R.drawable.ic_launcher).build();
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(1338, note);
}
};
private void updateCounts() {
updateCounts(false);
}
private void updateCounts(boolean force) {
if (!force && (bUp - lastUp < 10000 && bDown - lastDown < 10000)) {
return;
}
lastUp = bUp;
lastDown = bDown;
Message msg = sendBroadcastHandler.obtainMessage();
sendBroadcastHandler.sendMessage(msg);
}
#Override
public void onDestroy() {
Log.d(TAG, "Service onDestroy");
if (t != null) {
t.interrupt();
try {
t.join();
} catch (InterruptedException e) {
Log.d(TAG, "couldn't join forwarder-thread");
System.exit(1);
}
}
Log.d(TAG, "Killed it");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Service onStart");
if (running){
updateCounts(true);
return START_REDELIVER_INTENT;
}
running = true;
bm = LocalBroadcastManager.getInstance(this);
localPort = intent.getIntExtra("localPort", -1);
remotePort = intent.getIntExtra("remotePort", -1);
remoteHost = intent.getStringExtra("remoteHost");
t = new Thread(this);
t.start();
Log.d(TAG, "launching a thread");
Notification note = new Notification.Builder(this)
.setContentTitle("Forwarding TCP Port")
.setContentText(String.format(
"localhost:%s -> %s:%s", localPort, remoteHost, remotePort))
.setSmallIcon(R.drawable.ic_launcher)
.build();
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);
note.contentIntent = pi;
note.flags |= Notification.FLAG_NO_CLEAR;
startForeground(1337, note);
Log.d(TAG, "doing startForeground");
updateCounts(true);
return START_REDELIVER_INTENT;
}
private void reportException(Exception e){
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
Message msg = sendDeathHandler.obtainMessage();
Bundle b = msg.getData();
b.putString("causeOfDeath", sw.toString());
sendDeathHandler.sendMessage(msg);
}
private void finish(Selector s){
try {
serverSocketChannel.close();
} catch (IOException e){ }
Set<SelectionKey> selectedKeys = s.keys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
closeConnectionForKey(keyIterator.next());
}
}
private void closeChannel(SocketChannel c){
if (c != null){
try {
if (c != null){
c.close();
}
} catch (IOException e){ }
}
}
private void closeConnectionForKey(SelectionKey key){
PFGroup g = null;
try {
g = (PFGroup)key.attachment();
} catch (Exception e){
return;
}
if (g == null) {return;}
closeChannel(g.iChannel);
closeChannel(g.oChannel);
}
#Override
public void run() {
String causeOfDeath = null;
System.out.println("Server online");
Selector selector = null;
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(localPort));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
reportException(e);
return;
}
System.out.println("Server socket bound.");
while (true) {
System.out.println("Waiting for conn");
updateCounts();
int readyChannels = 0;
try {
readyChannels = selector.select();
} catch (IOException e) {
reportException(e);
continue;
}
if (Thread.currentThread().isInterrupted()) {
finish(selector);
return;
}
if (readyChannels == 0) {
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
//System.out.println("Ready on " + readyChannels);
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (!key.isValid()) {
continue;
} else if (key.isAcceptable()) {
System.out.println("Acceptable!");
PFGroup g = new PFGroup();
// 512KB buffers
g.iBuffer = ByteBuffer.allocate(512000);
g.oBuffer = ByteBuffer.allocate(512000);
boolean iConnected = false;
try {
g.iChannel = serverSocketChannel.accept();
iConnected = g.iChannel.finishConnect();
if (iConnected){
g.sidesOn++;
}
g.iChannel.configureBlocking(false);
g.iKey = g.iChannel.register(selector, 0, g);
g.oChannel = SocketChannel.open();
g.oChannel.configureBlocking(false);
g.oChannel.connect(new InetSocketAddress(remoteHost, remotePort));
g.oKey =g.oChannel.register(selector, SelectionKey.OP_CONNECT, g);
} catch (IOException e) {
continue;
}
} else if (key.isConnectable()) {
System.out.println("connectable!");
try {
SocketChannel c = (SocketChannel) key.channel();
PFGroup g = (PFGroup)key.attachment();
if (!c.finishConnect()) {
System.out.println("couldn't finish conencting");
continue;
}
g.sidesOn++;
System.out.println("Initilized the bidirectional forward");
key.interestOps(SelectionKey.OP_READ);
g.iKey = g.iChannel.register(selector, SelectionKey.OP_READ, g);
} catch (IOException e) {
continue;
}
} else if (key.isReadable()) {
try {
ByteBuffer b = null;
SocketChannel from = null;
SocketChannel to = null;
PFGroup g = (PFGroup)key.attachment();
String label = null;
if (key.channel() == g.iChannel){
from = g.iChannel;
to = g.oChannel;
b = g.iBuffer;
label = "incoming";
} else if (key.channel() == g.oChannel){
from = g.oChannel;
to = g.iChannel;
b = g.oBuffer;
label = "outgoing";
}
int i = from.read(b);
b.flip();
while (b.hasRemaining()) {
int bytes = to.write(b);
if(label.equals("incoming")){
bUp += bytes;
} else {
bDown += bytes;
}
}
b.clear();
if (i == -1) {
key.cancel();
g.sidesOn--;
if (g.sidesOn == 0){
System.out.println("Done, closing keys");
closeConnectionForKey(key);
}
}
} catch (IOException e){
Log.d(TAG, "closing connection for key.");
closeConnectionForKey(key);
}
}
}
}
}
public class PFGroup {
public ByteBuffer iBuffer;
public ByteBuffer oBuffer;
public SocketChannel iChannel;
public SocketChannel oChannel;
public int sidesOn = 0;
SelectionKey iKey;
SelectionKey oKey;
}
}
and in my main activity i used it like this:
Intent i=new Intent(this, PortForward.class)
.putExtra("localPort", 1195)
.putExtra("remotePort", port)
.putExtra("remoteHost", address);
startService(i);
but it does not work. when app is in background i can not use address:port through 127.0.0.1:1195 .
and also no related log appeasers in logcat.
I'm connecting my android device to arduino via USB and I receive data immediately from arduino by using bulkTransfer, but when I'm going to send acknowledge signal back to arduino using the same command, it receives that some seconds later.
My arduino model is DUE, and the arduino side code is:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(49, OUTPUT);
}
void loop() {
String a;
int sensorValue[64];
for (int i = 0; i <= 63; i++)
{
sensorValue[i] = analogRead(A0) / 4;
a = a + char(sensorValue[i]);
}
char b;
while (1) {
Serial.print(a);
Serial.flush();
delay(2);
b = Serial.read();
if (b == '1')
{
break;
}
}
digitalWrite(49, HIGH);
delay(2000);
digitalWrite(49, LOW);
}
My android side code is:
public void onClick(View v) {
synchronized (this) {
if (usbDeviceConnection != null) {
Thread myThread = new Thread(new Runnable() {
#Override
public void run() {
try {
int chunkCounter = 0;
String strTemp = null;
while (chunkCounter < 1) {
byte[] message = new byte[64];
final int result = usbDeviceConnection.bulkTransfer(endpointIN, message, 64, 10);
if (result == 64) {
for (int intTemp = 0; intTemp < 64; intTemp++) {
strTemp += String.valueOf((char) message[intTemp]);
}
byte[] ack = new byte[1];
ack[0] = 1; //1 means I've got this chunk
synchronized(this) {
int resultAck = 0;
while (resultAck <= 0) {
resultAck = usbDeviceConnection.bulkTransfer(endpointOUT, ack, 1, 10);
}
}
chunkCounter++;
if (chunkCounter == 1) {
final String strTempFinal = strTemp;
tempflag = true;
runOnUiThread(new Runnable() {
#Override
public void run() {
txtGetData.setText(strTempFinal);
}
});
}
}
}
} catch (final Exception e){
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
});
myThread.start();
}
Any help would be appreciated.
thanks in advance.
In android , i create a application based on RFID Card Reader on mobile. While i tapping Card on RFID Reader it generates same value at many times until the card untapped from the reader.
I want to show only one value per tapping card on RFID reader. Here i place my code and Sample snapshot of my application.
Guide me and tell solution for my problem.
public static MediaPlayer mp;
FT_Device ftDev = null;
int DevCount = -1;
int currentIndex = -1;
int openIndex = 0;
/*graphical objects*/
EditText readText;
Button readEnButton;
static int iEnableReadFlag = 1;
/*local variables*/
int baudRate; /*baud rate*/
byte stopBit; /*1:1stop bits, 2:2 stop bits*/
byte dataBit; /*8:8bit, 7: 7bit*/
byte parity; /* 0: none, 1: odd, 2: even, 3: mark, 4: space*/
byte flowControl; /*0:none, 1: flow control(CTS,RTS)*/
int portNumber; /*port number*/
long wait_sec=3000;
byte[] readData; //similar to data.
public static final int readLength = 1024; // changed length from 512
public int iavailable = 0;
char[] readDataToText;
//char readDataToTextSudha;
public boolean bReadThreadGoing = false;
public readThread read_thread;
public static D2xxManager ftD2xx = null;
boolean uart_configured = false;
// Empty Constructor
public MainActivity() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
readData = new byte[readLength];
readDataToText = new char[readLength];
//readDataToTextSudha = new char;
readText = (EditText) findViewById(R.id.ReadValues);
readText.setInputType(0);
readEnButton = (Button) findViewById(R.id.readEnButton);
baudRate = 9600;
/* default is stop bit 1 */
stopBit = 1;
/* default data bit is 8 bit */
dataBit = 8;
/* default is none */
parity = 0;
/* default flow control is is none */
flowControl = 0;
portNumber = 1;
try {
ftD2xx = D2xxManager.getInstance(this);
} catch (D2xxManager.D2xxException ex) {
ex.printStackTrace();
}
//Opening Coding
if (DevCount <= 0) {
createDeviceList();
} else {
connectFunction();
}
//Configuration coding
if (DevCount <= 0 || ftDev == null) {
Toast.makeText(getApplicationContext(), "Device not open yet...", Toast.LENGTH_SHORT).show();
} else {
SetConfig(baudRate, dataBit, stopBit, parity, flowControl);
}
readEnButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (DevCount <= 0 || ftDev == null) {
Toast.makeText(getApplicationContext(), "Device not open yet...", Toast.LENGTH_SHORT).show();
} else if (uart_configured == false) {
Toast.makeText(getApplicationContext(), "UART not configure yet...", Toast.LENGTH_SHORT).show();
return;
} else {
EnableRead();
}
}
});
}
public void EnableRead() {
iEnableReadFlag = (iEnableReadFlag + 1) % 2;
if (iEnableReadFlag == 1) {
ftDev.purge((byte) (D2xxManager.FT_PURGE_TX));
ftDev.restartInTask();
readEnButton.setText("Read Enabled");
Toast.makeText(getApplicationContext(),"Read Enabled",Toast.LENGTH_LONG).show();
} else {
ftDev.stopInTask();
readEnButton.setText("Read Disabled");
Toast.makeText(getApplicationContext(),"Read Disabled",Toast.LENGTH_LONG).show();
}
}
public void createDeviceList() {
int tempDevCount = ftD2xx.createDeviceInfoList(getApplicationContext());
if (tempDevCount > 0) {
if (DevCount != tempDevCount) {
DevCount = tempDevCount;
updatePortNumberSelector();
}
} else {
DevCount = -1;
currentIndex = -1;
}
};
public void disconnectFunction() {
DevCount = -1;
currentIndex = -1;
bReadThreadGoing = false;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (ftDev != null) {
synchronized (ftDev) {
if (true == ftDev.isOpen()) {
ftDev.close();
}
}
}
}
public void connectFunction() {
int tmpProtNumber = openIndex + 1;
if (currentIndex != openIndex) {
if (null == ftDev) {
ftDev = ftD2xx.openByIndex(getApplicationContext(), openIndex);
} else {
synchronized (ftDev) {
ftDev = ftD2xx.openByIndex(getApplicationContext(), openIndex);
}
}
uart_configured = false;
} else {
Toast.makeText(getApplicationContext(), "Device port " + tmpProtNumber + " is already opened", Toast.LENGTH_LONG).show();
return;
}
if (ftDev == null) {
Toast.makeText(getApplicationContext(), "open device port(" + tmpProtNumber + ") NG, ftDev == null", Toast.LENGTH_LONG).show();
return;
}
if (true == ftDev.isOpen()) {
currentIndex = openIndex;
Toast.makeText(getApplicationContext(), "open device port(" + tmpProtNumber + ") OK", Toast.LENGTH_SHORT).show();
if (false == bReadThreadGoing) {
read_thread = new readThread(handler);
read_thread.start();
bReadThreadGoing = true;
}
} else {
Toast.makeText(getApplicationContext(), "open device port(" + tmpProtNumber + ") NG", Toast.LENGTH_LONG).show();
}
}
public void updatePortNumberSelector() {
if (DevCount == 2) {
Toast.makeText(getApplicationContext(), "2 port device attached", Toast.LENGTH_SHORT).show();
} else if (DevCount == 4) {
Toast.makeText(getApplicationContext(), "4 port device attached", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "1 port device attached", Toast.LENGTH_SHORT).show();
}
}
public void SetConfig(int baud, byte dataBits, byte stopBits, byte parity, byte flowControl) {
if (ftDev.isOpen() == false) {
Log.e("j2xx", "SetConfig: device not open");
return;
}
ftDev.setBitMode((byte) 0, D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(baud);
ftDev.setDataCharacteristics(dataBits, stopBits, parity);
uart_configured = true;
Toast.makeText(getApplicationContext(), "Config done", Toast.LENGTH_SHORT).show();
}
final Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (iavailable > 0) {
mp = MediaPlayer.create(MainActivity.this, R.raw.beep);
mp.start();
readText.append(String.copyValueOf(readDataToText, 0, iavailable));
}
}
};
private class readThread extends Thread {
Handler mHandler;
readThread(Handler h) {
mHandler = h;
this.setPriority(Thread.MIN_PRIORITY);
}
#Override
public void run() {
int i;
while (true == bReadThreadGoing) {
try {
Thread.sleep(1000); //changed
} catch (InterruptedException e) {
}
synchronized (ftDev) {
iavailable = ftDev.getQueueStatus();
if (iavailable > 0) {
if (iavailable > readLength) {
iavailable = readLength;
}
ftDev.read(readData, iavailable,wait_sec);
for (i = 0; i < iavailable; i++) {
readDataToText[i] = (char) readData[i];
}
Message msg = mHandler.obtainMessage();
mHandler.sendMessage(msg);
}
}
}
}
}
#Override
public void onResume() {
super.onResume();
DevCount = 0;
createDeviceList();
if (DevCount > 0) {
connectFunction();
SetConfig(baudRate, dataBit, stopBit, parity, flowControl);
}
}
}
My problem would snapped here
Getting Value continuously from Reader
I want this type of value when i tap the card
If i tap some other cards, old card value replaces from the new one.
Guide me.
Thanks in Advance
I got the answer by using of Threads. When the card tapping it get some values after sleep of one or two seconds only the next value have to get from the reader.
public void run() {
int i;
while (true == bReadThreadGoing) { // Means Make sure , getting value from Reader
try {
Thread.sleep(1000); // Wait for a second to get another value.
clearText(); //clear the old value and get new value.
} catch (InterruptedException e) {
}
And clearing the edittext by using this command.
public void clearText() {
runOnUiThread(new Runnable() {
public void run() {
readText.setText("");
}
});
}
This is my code for questions, my problem is that i cannot create a code to randomly output a question from xml without any duplication,
Here's my code:
public class QuizFunActivity extends Activity{
Intent menu = null;
BufferedReader bReader = null;
static JSONArray quesList = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
Thread thread = new Thread() {
public void run() {
try {
Thread.sleep(3*1000);
finish();
loadQuestions();
Intent intent = new Intent(QuizFunActivity.this, QuestionActivity.class);
QuizFunActivity.this.startActivity(intent);
} catch (Exception e) {
}
}
};
thread.start();
}
private void loadQuestions() throws Exception {
try {
InputStream questions = this.getBaseContext().getResources()
.openRawResource(R.raw.questions);
bReader = new BufferedReader(new InputStreamReader(questions));
StringBuilder quesString = new StringBuilder();
String aJsonLine = null;
while ((aJsonLine = bReader.readLine()) != null) {
quesString.append(aJsonLine);
}
Log.d(this.getClass().toString(), quesString.toString());
JSONObject quesObj = new JSONObject(quesString.toString());
quesList = quesObj.getJSONArray("Questions");
Log.d(this.getClass().getName(),
"Num Questions " + quesList.length());
} catch (Exception e){
} finally {
try {
bReader.close();
} catch (Exception e) {
Log.e("", e.getMessage().toString(), e.getCause());
}
}
}
public static JSONArray getQuesList() {
return quesList;
}
}
can you give me a sample of which part on my code should i create a code for random output?
thanks for the help!
you may take a look with this activity,
public class QuestionActivity extends Activity {
/** Called when the activity is first created. */
EditText question = null;
RadioButton answer1 = null;
RadioButton answer2 = null;
RadioButton answer3 = null;
RadioButton answer4 = null;
RadioGroup answers = null;
Button finish = null;
int selectedAnswer = -1;
int quesIndex = 0;
int numEvents = 0;
int selected[] = null;
int correctAns[] = null;
boolean review =false;
Button prev, next = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.question);
TableLayout quizLayout = (TableLayout) findViewById(R.id.quizLayout);
quizLayout.setVisibility(android.view.View.INVISIBLE);
try {
question = (EditText) findViewById(R.id.question1);
answer1 = (RadioButton) findViewById(R.id.a0);
answer2 = (RadioButton) findViewById(R.id.a1);
answer3 = (RadioButton) findViewById(R.id.a2);
answer4 = (RadioButton) findViewById(R.id.a3);
answers = (RadioGroup) findViewById(R.id.answers);
RadioGroup questionLayout = (RadioGroup)findViewById(R.id.answers);
Button finish = (Button)findViewById(R.id.finish);
finish.setOnClickListener(finishListener);
prev = (Button)findViewById(R.id.Prev);
prev.setOnClickListener(prevListener);
next = (Button)findViewById(R.id.Next);
next.setOnClickListener(nextListener);
selected = new int[QuizFunActivity.getQuesList().length()];
java.util.Arrays.fill(selected, -1);
correctAns = new int[QuizFunActivity.getQuesList().length()];
java.util.Arrays.fill(correctAns, -1);
this.showQuestion(0,review);
quizLayout.setVisibility(android.view.View.VISIBLE);
} catch (Exception e) {
Log.e("", e.getMessage().toString(), e.getCause());
}
}
private void showQuestion(int qIndex,boolean review) {
try {
JSONObject aQues = QuizFunActivity.getQuesList().getJSONObject(qIndex);
String quesValue = aQues.getString("Question");
if (correctAns[qIndex] == -1) {
String correctAnsStr = aQues.getString("CorrectAnswer");
correctAns[qIndex] = Integer.parseInt(correctAnsStr);
}
question.setText(quesValue.toCharArray(), 0, quesValue.length());
answers.check(-1);
answer1.setTextColor(Color.WHITE);
answer2.setTextColor(Color.WHITE);
answer3.setTextColor(Color.WHITE);
answer4.setTextColor(Color.WHITE);
JSONArray ansList = aQues.getJSONArray("Answers");
String aAns = ansList.getJSONObject(0).getString("Answer");
answer1.setText(aAns.toCharArray(), 0, aAns.length());
aAns = ansList.getJSONObject(1).getString("Answer");
answer2.setText(aAns.toCharArray(), 0, aAns.length());
aAns = ansList.getJSONObject(2).getString("Answer");
answer3.setText(aAns.toCharArray(), 0, aAns.length());
aAns = ansList.getJSONObject(3).getString("Answer");
answer4.setText(aAns.toCharArray(), 0, aAns.length());
Log.d("",selected[qIndex]+"");
if (selected[qIndex] == 0)
answers.check(R.id.a0);
if (selected[qIndex] == 1)
answers.check(R.id.a1);
if (selected[qIndex] == 2)
answers.check(R.id.a2);
if (selected[qIndex] == 3)
answers.check(R.id.a3);
setScoreTitle();
if (quesIndex == (QuizFunActivity.getQuesList().length()-1))
next.setEnabled(false);
if (quesIndex == 0)
prev.setEnabled(false);
if (quesIndex > 0)
prev.setEnabled(true);
if (quesIndex < (QuizFunActivity.getQuesList().length()-1))
next.setEnabled(true);
if (review) {
Log.d("review",selected[qIndex]+""+correctAns[qIndex]);;
if (selected[qIndex] != correctAns[qIndex]) {
if (selected[qIndex] == 0)
answer1.setTextColor(Color.RED);
if (selected[qIndex] == 1)
answer2.setTextColor(Color.RED);
if (selected[qIndex] == 2)
answer3.setTextColor(Color.RED);
if (selected[qIndex] == 3)
answer4.setTextColor(Color.RED);
}
if (correctAns[qIndex] == 0)
answer1.setTextColor(Color.GREEN);
if (correctAns[qIndex] == 1)
answer2.setTextColor(Color.GREEN);
if (correctAns[qIndex] == 2)
answer3.setTextColor(Color.GREEN);
if (correctAns[qIndex] == 3)
answer4.setTextColor(Color.GREEN);
}
} catch (Exception e) {
Log.e(this.getClass().toString(), e.getMessage(), e.getCause());
}
}
private OnClickListener finishListener = new OnClickListener() {
public void onClick(View v) {
setAnswer();
//Calculate Score
int score = 0;
for(int i=0; i<correctAns.length; i++){
if ((correctAns[i] != -1) && (correctAns[i] == selected[i]))
score++;
}
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(QuestionActivity.this).create();
alertDialog.setTitle("Score");
alertDialog.setMessage((score) +" out of " + (QuizFunActivity.getQuesList().length()));
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Retake", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
review = false;
quesIndex=0;
QuestionActivity.this.showQuestion(0, review);
}
});
/* alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Review", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
review = true;
quesIndex=0;
QuestionActivity.this.showQuestion(0, review);
}
}); */
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE,"Quit", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
review = false;
Intent instructionsIntent = new Intent(QuestionActivity.this,MainBookActivity.class);
startActivity(instructionsIntent);
finish();
}
});
alertDialog.show();
}
};
private void setAnswer() {
if (answer1.isChecked())
selected[quesIndex] = 0;
if (answer2.isChecked())
selected[quesIndex] = 1;
if (answer3.isChecked())
selected[quesIndex] = 2;
if (answer4.isChecked())
selected[quesIndex] = 3;
Log.d("",Arrays.toString(selected));
Log.d("",Arrays.toString(correctAns));
}
private OnClickListener nextListener = new OnClickListener() {
public void onClick(View v) {
setAnswer();
quesIndex++;
if (quesIndex >= QuizFunActivity.getQuesList().length())
quesIndex = QuizFunActivity.getQuesList().length() - 1;
showQuestion(quesIndex,review);
}
};
private OnClickListener prevListener = new OnClickListener() {
public void onClick(View v) {
setAnswer();
quesIndex--;
if (quesIndex < 0)
quesIndex = 0;
showQuestion(quesIndex,review);
}
};
private void setScoreTitle() {
this.setTitle("SciQuiz3 " + (quesIndex+1)+ "/" + QuizFunActivity.getQuesList().length());
}
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
}
Thanks!
I'm creating a audio swipe card reader but I'm getting an error with windows. I can't trace what causing the error in my codes. Can anyone hel me to point what causing the error in my codes? any thought will be highly appreciated.
Here is my codes:
public class SReaderActivity extends Activity {
public final String TAG = "SReaderActivity";
Button swipe, get;// detect, stop
TextView result_text, mTitle;
private TimeCount time = null;
private AudioManager am = null;
int maxVol;
private ProgressDialog progressDialog;
private boolean mHeadsetPlugged = false;
private BroadcastReceiver mHeadsetReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
boolean hasHeadset = (intent.getIntExtra("state", 0) == 1);
boolean hasMicroPhone = (intent.getIntExtra("microphone", 0) == 1);
if (hasHeadset && hasMicroPhone) {
mHeadsetPlugged = true;
} else {
mHeadsetPlugged = false;
if (sreader != null)
sreader.Stop();
handler.post(disable_button);
}
handler.post(mHeadsetPluginHandler);
}
}
};
private Handler handler = new Handler();
SReaderApi sreader = null;
private String version = null;
private String ksn = null;
private String random = null;
private String workingkey = null;
private String encryption_data = null;
private String decryption_data = null;
private String T1PAN_data = null;
private String T1Name_Exd = null;
private String T2PAN_data = null;
private String T2Exd_data = null;
private Runnable mHeadsetPluginHandler = new Runnable() {
public void run() {
String plug_str = mHeadsetPlugged ? "plugin" : "unplugin";
Toast.makeText(SReaderActivity.this, "Headset " + plug_str, Toast.LENGTH_SHORT).show();
if (sreader != null && mHeadsetPlugged == false) { // Device unplug APP close
CloseSinWave();
finish();
} else {
onDetect();
}
}
};
private Runnable disable_button = new Runnable() {
public void run() {
swipe.setEnabled(false);
get.setEnabled(false);
}
};
private Runnable enable_button = new Runnable() {
public void run() {
get.setText(R.string.get);
swipe.setClickable(true);
swipe.setEnabled(true);
swipe.setText(R.string.swipe);
}
};
private Runnable enable_get = new Runnable() {
public void run() {
get.setEnabled(true);
get.setClickable(true);
}
};
private Runnable timeout_ack = new Runnable() {
public void run() {
Toast.makeText(SReaderActivity.this, "Timeout!!!", Toast.LENGTH_SHORT).show();
}
};
private Runnable unknown_err = new Runnable() {
public void run() {
result_text.setText(R.string.unknown_error);
}
};
private Runnable detcet = new Runnable() {
public void run() {
String txt = "Detect OK\n";
result_text.setText(txt);
}
};
private Runnable display_encryptiondata = new Runnable() {
public void run() {
String txt = "Encryption data\n";
txt += encryption_data + "\n\n\n";
result_text.setText(txt);
}
};
private Runnable display_decryptiondata = new Runnable() {
public void run() {
String txt = "Encryption data\n";
txt += encryption_data + "\n\n\nDecryption data\n";
txt += decryption_data + "\n";
result_text.setText(txt);
}
};
private Runnable display_get_data = new Runnable() {
public void run() {
String txt = "Decryption data\n";
txt += decryption_data + "\n\n\n\n";
txt += "T1PAN:" + T1PAN_data + "\n";
txt += "T1Name_Exd:" + T1Name_Exd + "\n";
txt += "T2PAN:" + T2PAN_data + "\n";
txt += "T2Exd:" + T2Exd_data + "\n";
result_text.setText(txt);
}
};
private Runnable clear_all = new Runnable() {
public void run() {
encryption_data = "";
decryption_data = "";
T1PAN_data = "";
T1Name_Exd = "";
T2PAN_data = "";
T2Exd_data = "";
result_text.setText("");
}
};
private Runnable clear_encryption = new Runnable() {
public void run() {
encryption_data = "";
decryption_data = "";
T1PAN_data = "";
T1Name_Exd = "";
T2PAN_data = "";
T2Exd_data = "";
result_text.setText("");
}
};
private Runnable clear_carddata = new Runnable() {
public void run() {
encryption_data = "";
T1PAN_data = "";
T1Name_Exd = "";
T2PAN_data = "";
T2Exd_data = "";
result_text.setText("");
}
};
private Runnable settext_swpie = new Runnable() {
public void run() {
swipe.setClickable(true);
swipe.setText(R.string.swipe);
}
};
private Runnable begin_get = new Runnable() {
public void run() {
myToast = new MyToast(SReaderActivity.this, "get T1&T2 Data...");
myToast.show();
}
};
private Runnable settext_get = new Runnable() {
public void run() {
get.setClickable(true);
get.setText(R.string.get);
}
};
public class MyToast {
private Context mContext = null;
private Toast mToast = null;
private Handler mHandler = null;
private Runnable mToastThread = new Runnable() {
public void run() {
mToast.show();
mHandler.postDelayed(mToastThread, 3000);
}
};
public MyToast(Context context, String txt) {
mContext = context;
mHandler = new Handler(mContext.getMainLooper());
mToast = Toast.makeText(mContext, txt, Toast.LENGTH_LONG);
}
public void setText(String text) {
mToast.setText(text);
}
public void show() {
mHandler.post(mToastThread);
}
public void cancel() {
mHandler.removeCallbacks(mToastThread);
mToast.cancel();
}
}
private MyToast myToast = null;
class TimeCount extends CountDownTimer {
int id;
public TimeCount(int id, long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);// ²ÎÊýÒÀ´ÎΪ×Üʱ³¤,ºÍ¼ÆʱµÄʱ¼ä¼ä¸ô
this.id = id;
}
#Override
public void onFinish() {// ¼ÆʱÍê±Ïʱ´¥·¢
if (id == R.id.swipe) {
swipe.setText(R.string.reswipe);
swipe.setClickable(true);
}
else if (id == R.id.get) {
get.setText(R.string.get);
get.setClickable(true);
}
}
#Override
public void onTick(long millisUntilFinished) {// ¼Æʱ¹ý³ÌÏÔʾ
CharSequence str = getString(R.string.second);
if (id == R.id.swipe) {
swipe.setClickable(false);
}
else if (id == R.id.get) {
get.setClickable(false);
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.swipe);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
mTitle = (TextView) findViewById(R.id.title_left_text);
mTitle.setText(R.string.version_name);
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
IntentFilter iFilter = new IntentFilter();
iFilter.addAction(Intent.ACTION_HEADSET_PLUG);
iFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(mHeadsetReceiver, iFilter);
swipe = (Button) this.findViewById(R.id.swipe);
swipe.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onSwipe();
}
});
get = (Button) this.findViewById(R.id.get);
get.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onGet();
}
});
result_text = (TextView) this.findViewById(R.id.result);
swipe.setEnabled(false);
get.setEnabled(false);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
maxVol = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
am.setStreamVolume(AudioManager.STREAM_MUSIC, maxVol, 0);
}
public void onDestroy() {
unregisterReceiver(mHeadsetReceiver);
super.onDestroy();
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU: {
openOptionsDialog();
return true;
}
case KeyEvent.KEYCODE_BACK: { // Log.WritetoFile();
if (sreader != null) {
sreader.Stop();
sreader = null;
if (myToast != null)
myToast.cancel();
finish();
System.exit(0);
return true;
}
}
}
return super.onKeyDown(keyCode, event);
}
public void onUserLeaveHint() { // this only executes when Home is selected.
// do stuff
super.onUserLeaveHint();
if (sreader != null) {
sreader.Stop();
sreader = null;
if (myToast != null)
myToast.cancel();
finish();
System.exit(0);
}
}
public void onAttachedToWindow() {
super.onAttachedToWindow();
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
}
private void openOptionsDialog() {
AlertDialog.Builder dialog = new AlertDialog.Builder(SReaderActivity.this);
dialog.setTitle("SS505 sReader");
dialog.setMessage("Magnetic Card Reader APP");
dialog.setNegativeButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
private void onSwipe() {
if (sreader == null)
return;
progressDialog = ProgressDialog.show(this, "Loadding Key", "Please wait swipe card ...", true, false);
time = new TimeCount(R.id.swipe, 15000, 1000);
time.start();// ¿ªÊ¼¼Æʱ
swipe.setEnabled(false);
get.setEnabled(false);
new Thread() {
public void run() {
String data = null;
decryption_data = null;
encryption_data = null;
handler.post(clear_encryption);
try {
random = sreader.GetRandom(10000);
if (random == null) {
progressDialog.dismiss();
String err = sreader.GetErrorString();
if (err.equalsIgnoreCase("cancel all"))
return;
}
workingkey = sreader.GenerateWorkingKey(random, ksn);
progressDialog.dismiss();
data = sreader.ReadCard(15000);
} catch (Exception ex) {
progressDialog.dismiss();
if (ex instanceof TimeoutException) {
time.cancel();
sreader.Cancel();
handler.post(enable_button);
handler.post(timeout_ack);
return;
} else
handler.post(unknown_err);
CloseSinWave();
}
time.cancel();
if (data == null) {
encryption_data = sreader.GetErrorString();
if (encryption_data.equalsIgnoreCase("cancel all"))
return;
handler.post(display_encryptiondata);
} else {
encryption_data = "\n" + data;
handler.post(display_encryptiondata);
String d_str = sreader.TriDesDecryption(workingkey, data);
if (d_str != null) {
if (false == d_str.startsWith("A1")) {
return;
}
int index2 = FindSplitCharIndex(d_str, "A2", 2);
int index3 = FindSplitCharIndex(d_str, "A3", index2 + 2);
if (index2 < 0 || index3 < 0) {
return;
}
String t1 = d_str.substring(2, index2);
String t2 = d_str.substring(index2 + 2, index3);
String t3 = d_str.substring(index3 + 2);
String ex_msg = "";
if (t1.equals(""))
decryption_data = "\nT1=" + "T1 Empty";
else
decryption_data = "\nT1=" + changeHexString2CharString(t1);
if (t2.equals(""))
decryption_data += "\nT2=" + "T2 Empty";
else {
String e2 = changeHexString2CharString(t2);
if (e2.length() < 24 || e2.length() > 40)
ex_msg = "\nTrack2 " + getResources().getText(R.string.de_len) + e2.length() + "byte";
decryption_data += "\nT2=" + e2;
}
if (t3.equals(""))
decryption_data += "\nT3=" + "T3 Empty";
else
decryption_data += "\nT3=" + changeHexString2CharString(t3) + ex_msg;
handler.post(display_decryptiondata);
}
}
handler.post(enable_button);
handler.post(settext_swpie);
handler.post(enable_get);
}
}.start();
}
private int FindSplitCharIndex(String str, String split, int start) {
int i = start;
while (i < str.length() && i + 1 < str.length()) {
String e = str.substring(i, i + 2);
if (e.equals(split)) {
return i;
}
i += 2;
}
return -1;
}
private String changeHexString2CharString(String e) {
String char_txt = "";
for (int i = 0; i < e.length(); i = i + 2) {
String c = e.substring(i, i + 2);
char j = (char) Integer.parseInt(c, 16);
char_txt += j;
}
return char_txt;
}
private boolean Detect_sReader() {
mHeadsetPlugged = HeadSetUtils.checkHeadset();
if (!mHeadsetPlugged) {
result_text.setText(R.string.nodevice);
}
return mHeadsetPlugged;
}
private boolean GenerateSinWave() {
sreader = SReaderApi.getSreaderInstance();
if (sreader.Init() == true) {
sreader.Start();
am.setMode(AudioManager.MODE_NORMAL);
return true;
}
return false;
}
private void CloseSinWave() {
if (sreader != null)
sreader.Stop();
}
private void Initialization() {
swipe.setEnabled(false);
progressDialog = ProgressDialog.show(this, "", "Card Reader Detecting...", true, false);
new Thread() {
public void run() {
int i = 0;
try {
int j = 1;
boolean s_init = false;
while (j < 5) {
try {
s_init = sreader.Initial(2500);
if (s_init)
break;
} catch (Exception ex) {
if (ex instanceof TimeoutException) {
if (j == 4) {
handler.post(timeout_ack);
} else
sleep(1000);
} else {
handler.post(unknown_err);
break;
}
}
j++;
}
if (!s_init) {
CloseSinWave();
progressDialog.dismiss();
return;
}
i++;
ksn = sreader.GetKSN(5000);
if (ksn == null) {
String err = sreader.GetErrorString();
if (err.equalsIgnoreCase("cancel all"))
return;
throw new Exception("ksn is null");
}
handler.post(enable_button);
handler.post(detcet);
progressDialog.dismiss();
} catch (Exception ex) {
progressDialog.dismiss();
if (ex instanceof TimeoutException) {
handler.post(timeout_ack);
} else
handler.post(unknown_err);
CloseSinWave();
}
}
}.start();
}
private void onGet() {
if (sreader == null)
return;
time = new TimeCount(R.id.get, 10000, 1000);
time.start();// ¿ªÊ¼¼Æʱ
get.setEnabled(false);
swipe.setEnabled(false);
handler.post(begin_get);
new Thread() {
public void run() {
String Empty = "Empty";
int i = 0;
handler.post(clear_carddata);
try {
T1PAN_data = sreader.GetT1PAN(5000);
if (T1PAN_data == null) {
T1PAN_data = Empty;
} else {
T1PAN_data = changeHexString2CharString(T1PAN_data);
}
i++;
T1Name_Exd = sreader.GetT1HolderName_Exd(5000);
if (T1Name_Exd == null) {
T1Name_Exd = Empty;
} else {
T1Name_Exd = changeHexString2CharString(T1Name_Exd);
}
i++;
T2PAN_data = sreader.GetT2PAN(5000);
if (T2PAN_data == null) {
T2PAN_data = Empty;
} else {
T2PAN_data = changeHexString2CharString(T2PAN_data);
}
i++;
T2Exd_data = sreader.GetT2Exd(5000);
if (T2Exd_data == null) {
T2Exd_data = Empty;
} else {
T2Exd_data = changeHexString2CharString(T2Exd_data);
}
handler.post(display_get_data);
} catch (Exception ex) {
if (ex instanceof TimeoutException) {
time.cancel();
myToast.cancel();
sreader.Cancel();
handler.post(enable_button);
handler.post(timeout_ack);
return;
} else
handler.post(unknown_err);
CloseSinWave();
}
myToast.cancel();
time.cancel();
handler.post(settext_get);
handler.post(enable_button);
}
}.start();
}
private void onDetect() {
am.setStreamVolume(AudioManager.STREAM_MUSIC, maxVol, 0);
if (Detect_sReader() == true) {
handler.post(clear_all);
if (GenerateSinWave() == true) {
Initialization();
}
}
}
}
Here is the Log cat:
05-20 16:26:30.638: E/AndroidRuntime(1497): FATAL EXCEPTION: main
05-20 16:26:30.638: E/AndroidRuntime(1497): java.lang.IllegalArgumentException: Window type can not be changed after the window is added.
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.os.Parcel.readException(Parcel.java:1429)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.os.Parcel.readException(Parcel.java:1379)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.IWindowSession$Stub$Proxy.relayout(IWindowSession.java:634)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.ViewRootImpl.relayoutWindow(ViewRootImpl.java:3835)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1384)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
05-20 16:26:30.638: E/AndroidRuntime(1497): at android.view.Choreographer.doFrame(Choreographer.java:525)
Problem seems to be in onAttachedToWindow(). Change the function as below and give it a try.
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
your targetSdk must be less than 14.
try setting it to 13
Check this Answer. And it works for me.