How to set a virtual scene image programmatically on android emulator - android

I have writing some driven tests to a flutter project and there are a barcode scanner functionality which I can test successfully using the virtual scene tool provided by android emulator.
However there are many cases to test regarding to different barcodes. I want to set a specific barcode image on virtual scene to each case. Is it possible?
I found that the value of this image is putted on ~/.android/avd/[emulatorName]/AVD.conf file at virtualscene\posters variable.
virtualscene\posters=#Variant(\0\0\0\b\0\0\0\x2\0\0\0\b\0w\0\x61\0l\0l\0\0\0\n\xff\xff\xff\xff\0\0\0\n\0t\0\x61\0\x62\0l\0\x65\0\0\0\n\xff\xff\xff\xff)
virtualscene\posters=#Variant(\0\0\0\b\0\0\0\x2\0\0\0\b\0w\0\x61\0l\0l\0\0\0\n\ 0\0\0\\\0/\0U\0s\0\x65\0r\0s\0/\0l\0\x65\0o\0n\0\x61\0r\0\x64\0o\0.\0\x61\0r\0m\0\x65\0r\0o\0/\0\x44\0\x65\0s\0k\0t\0o\0p\0/\0J\0\x61\0m\0\x65\0s\0W\0i\0l\0s\0o\0n\0.\0p\0n\0g\0\0\0\n\0t\0\x61\0\x62\0l\0\x65\0\0\0\n\xff\xff\xff\xff)

You can replace the default (global) image located at $ANDROID_SDK_HOME/emulator/resources/poster.png with your poster.png image,
nor change the default pointer by editing the file $ANDROID_SDK_HOME/emulator/resources/Toren1BD.posters.

You can set the virtual scene image to a specified path. And manipulate the target image while testing.
As the Instrumented tests are running on your (virtual) device, it cannot manipulate the host machine files directly. What can be done, (which is an ugly hack) is to start a server on the host, which can be reached from the virtual device with the hosts loop-back "10.0.2.2" address.
This server can manipulate the target files.
If anybody has better solution, please share it!
An example server and client is here.
Server:
import java.io.*;
import java.net.*;
import java.nio.channels.FileChannel;
public class FileManipulatorServer {
public static void main(String args[]) {
int port = 6789;
FileManipulatorServer server = new FileManipulatorServer( port );
server.startServer();
}
// declare a server socket and a client socket for the server
private ServerSocket fileManipulatorServer = null;
private Socket clientSocket = null;
private int port;
public FileManipulatorServer(int port ) {
this.port = port;
}
public void stopServer() {
System.out.println( "Server cleaning up." );
System.exit(0);
}
public void startServer() {
// Try to open a server socket on the given port
// Note that we can't choose a port less than 1024 if we are not
// privileged users (root)
try {
fileManipulatorServer = new ServerSocket(port);
}
catch (IOException e) {
System.out.println(e);
}
System.out.println( "Waiting for connections. Only one connection is allowed." );
// Create a socket object from the ServerSocket to listen and accept connections.
// Use FileManipulatorTask to process the connection.
while ( true ) {
try {
clientSocket = fileManipulatorServer.accept();
FileManipulatorTask task = new FileManipulatorTask(clientSocket, this);
task.run();
}
catch (IOException e) {
System.out.println(e);
}
}
}
}
class FileManipulatorTask {
private BufferedReader is;
private PrintStream os;
private Socket clientSocket;
private FileManipulatorServer server;
public FileManipulatorTask(Socket clientSocket, FileManipulatorServer server) {
this.clientSocket = clientSocket;
this.server = server;
System.out.println( "Connection established with: " + clientSocket );
try {
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public void run() {
String line;
try {
boolean serverStop = false;
line = is.readLine();
System.out.println( "Received " + line );
saveImageToPoster(line.trim());
os.println("OK");
os.flush();
System.out.println( "Connection closed." );
is.close();
os.close();
clientSocket.close();
if ( serverStop ) server.stopServer();
} catch (IOException e) {
System.out.println(e);
}
}
private void saveImageToPoster(String filename) {
try {
FileChannel src = new FileInputStream("C:\\fullpathtopostercandidates\\"+filename).getChannel();
FileChannel dest = new FileOutputStream("C:\\fullpathtoconfiguredposter\\poster.jpg").getChannel();
dest.transferFrom(src, 0, src.size());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client:
import java.io.*;
import java.net.*;
public class FileNameSenderClient {
private String hostname = "10.0.2.2";
private int port = 6789;
public void sendFileName(String filename) {
Socket clientSocket = null;
DataOutputStream os = null;
BufferedReader is = null;
try {
clientSocket = new Socket(hostname, port);
os = new DataOutputStream(clientSocket.getOutputStream());
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + hostname);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + hostname);
}
if (clientSocket == null || os == null || is == null) {
System.err.println( "Something is wrong. One variable is null." );
return;
}
try {
System.out.println("Write to output stream");
os.writeBytes( filename +"\n");
os.flush();
String responseLine = is.readLine();
System.out.println("Server returns: " + responseLine);
os.close();
is.close();
clientSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
Use the FileNameSenderClient from your instrumented test like this.
#Test
public void testQRcodeReadingOK()
{
FileNameSenderClient c = new FileNameSenderClient();
c.sendFileName("QRCode.jpg");
//your code that wants to use the image, like the this:
onView(withId(R.id.load_qr_code)).perform(click());
}

Related

Socket Connection Always Null When Connecting To Remote Server

Good day.Im trying to connect to server with socket.Here is my code on how i do it.
private class SocketConnection extends AsyncTask<String, String, String> {
PrintWriter out;
BufferedReader in;
#Override
protected String doInBackground(String... params) {
connect();
try {
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException ex) {
System.out.append("error").append("socketcoonection").println();
}
String msg = null;
try {
msg = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (run) {
System.out.append(msg).append("socketcoonection").println();
out.println();
out.flush();
/*try {
msg = in.readLine();
} catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}*/
}
return null;
}
}
and here is the connect() method
public void connect() {
try {
clientSocket = new Socket("vaenterprises.org/test.php", 8080);
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
if (clientSocket != null) {
run = true;
}
}
and this is the server side php code of test.php
echo json_encode("socket working");
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
and the address link is vaenterprises.org/test/php so im trying to connect to it and read the input or output stream or the echo.Whatever i do,i get nullPointerException at System.out.append(msg).append("socketcoonection").println(); and during debug i figured out that its socket which is null...Please tell me what am i doing wrong?

Transfer data between 2 android devices

I'd like write an app to transfer data between 2 android devices on the same wifi network, like as there is a share folder.
How can i do this?
Thanks
EDIT (My solution):
My Server wait for request
private boolean startServer() {
try {
server = new ServerSocket(port);
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
return true;
}
public void runServer() {
while (this.go) {
try {
Log.d("BurgerClub", "Server in attesa di richieste");
Socket s1 = server.accept();
OutputStream s1out = s1.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s1out));
BufferedReader br = new BufferedReader(new FileReader(this.path));
String counter = br.readLine();
counter = counter != null ? counter : "000";
br.close();
bw.write(counter);
bw.close();
s1.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
My Client (Runnable object)
public void run() {
try {
this.openConnection();
// Se il socket รจ connesso
if( !this.s1.isClosed() ) {
InputStream is = this.s1.getInputStream();
BufferedReader dis = new BufferedReader(new InputStreamReader(is));
line = dis.readLine();
if( !this.previousCounter.equals(line.trim()) ) {
((BurgerClub_MonitorActivity) counterContext).runOnUiThread(new Runnable() {
#Override
public void run() {
TextView edit = (TextView)(((BurgerClub_MonitorActivity) counterContext).findViewById(R.id.textActionCounter));
edit.setText(line);
}
});
this.previousCounter = line.trim();
}
dis.close();
}
} catch (ConnectException connExc) {
connExc.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (Throwable ex) {
ex.printStackTrace();
}
One device needs to serve as a server and the other one will be the client.
The basic flow needs to be something of this sort:
Server device opens a socket and listens on it.
Server device broadcasts the local IP and port it's listening on.
Client device receives broadcast and initiates a connection.
Perform data transfer.
Read about NFC (Near field communication)
http://developer.android.com/guide/topics/connectivity/nfc/index.html

how to send message to all connected client from server

i've created an android application in which, android application act as the client, and server resides in the desktop application.
suppose there are 10 android application runs the same at a time on 10 different android tablets, when one updation received from one tablet, the desktop application sends the updation to all other remaining tablets. how could the server knows how many clients are connected and how to send the message to all the clients
what i plan is to run a server in all android so that when one updation received from one tablet, the desktop application sends the updation to all other remaining tablets.
can anyone please tell me some suggestion regarding this.
Client side
private int SERVER_PORT = 9999;
class Client implements Runnable {
private Socket client;
private PrintWriter out;
private Scanner in;
#Override
public void run() {
try {
client = new Socket("localhost", SERVER_PORT);
Log.d("Client", "Connected to server at port " + SERVER_PORT);
out = new PrintWriter(client.getOutputStream());
in = new Scanner(client.getInputStream());
String line;
while ((line = in.nextLine()) != null) {
Log.d("Client", "Server says: " + line);
if (line.equals("Hello client")) {
out.println("Reply");
out.flush();
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Server class
class ServerThread implements Runnable {
private ServerSocket server;
#Override
public void run() {
try {
server = new ServerSocket(SERVER_PORT);
Log.d("Server", "Start the server at port " + SERVER_PORT
+ " and waiting for clients...");
while (true) {
Socket socket = server.accept();
Log.d("Server",
"Accept socket connection: "
+ socket.getLocalAddress());
new Thread(new ClientHandler(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ClientHandler implements Runnable {
private Socket clientSocket;
private PrintWriter out;
private Scanner in;
public ClientHandler(Socket clietSocket) {
this.clientSocket = clietSocket;
}
#Override
public void run() {
try {
out = new PrintWriter(clientSocket.getOutputStream());
in = new Scanner(clientSocket.getInputStream());
String line;
Log.d("ClientHandlerThread", "Start communication with : "
+ clientSocket.getLocalAddress());
out.println("Hello client");
out.flush();
while ((line = in.nextLine()) != null) {
Log.d("ClientHandlerThread", "Client says: " + line);
if (line.equals("Reply")){
out.print("Server replies");
out.flush();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You could save the Sockets in a List and send a message through all the OutputStreams in that List:
Socket socket = Server.accept();
sockets.add(socket); //sockets is an ArrayList<Socket>
public void sendMessageToEveryone(String msg) {
for(Socket s : sockets) {
s.getOutputStream().write(msg.getBytes());
s.getOutputStream().flush();
}
You could use the Google Cloud Messaging service.
Take a look at this page:
https://developer.android.com/google/gcm/index.html

Android proxy using sockets

I'm trying to create a proxy in Android and I have to use sockets . I've read many tutorials and came up with following code. Unfortunately browser doesn't seem to get any data and after some time it displays standard web page saying that web page is not available. What might be the cause? Thanks for your help.
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(9902, 0, InetAddress.getByName("localhost"));
} catch (Exception e) {
e.printStackTrace();
}
if (serverSocket != null) {
while (!Thread.currentThread().isInterrupted()) {
try {
Socket socket = serverSocket.accept();
new Thread(new RunnableToReadSocketData(socket)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class RunnableToReadSocketData implements Runnable {
private final Socket clientSocket;
public RunnableToReadSocketData(Socket socket) {
this.clientSocket = socket;
}
#Override
public void run() {
Socket serverSocket = null;
try {
InputStream streamFromClient = clientSocket.getInputStream();
PrintWriter streamToClient = new PrintWriter(clientSocket.getOutputStream());
StringWriter writer = new StringWriter();
IOUtils.copy(streamFromClient, writer);
String requestString = writer.toString();
int firstSpace = requestString.indexOf(" ");
int secondSpace = requestString.indexOf(" ", ++firstSpace);
String url = requestString.substring(firstSpace, secondSpace);
Uri uri = Uri.parse(url);
String urlWithoutProtocol = uri.getHost();
System.out.println("==============Reading Socket==============\n" + clientSocket.toString() + "\n" + requestString);
serverSocket = new Socket(urlWithoutProtocol, 80);
PrintWriter streamToServer = new PrintWriter(serverSocket.getOutputStream(), true);
streamToServer.write(requestString);
streamToServer.flush();
InputStream streamFromServer = serverSocket.getInputStream();
StringWriter writerResponse = new StringWriter();
IOUtils.copy(streamFromServer, writerResponse);
String responseString = writerResponse.toString();
System.out.println("==============RECEIVED==============\n" + serverSocket.toString() + "\n" + responseString);
streamToClient.write(responseString);
streamToClient.flush();
streamToClient.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
if (clientSocket != null) {
clientSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You're doing this wrong. After you process the CONNECT command you need to start two threads to copy bytes over the connection, one in each direction. Don't attempt to read the entire request before you send anything; ditto the response. Just copy bytes as you receive them.
When you read EOS on one socket, shutdown the other socket for output and exit that thread. If you've already shutdown the socket you read the EOS from, close both and exit the thread. You need this in case either end does a shutdown, to propagate it properly.
I agree with previous.
The general principle is:
Client connects
Start reading thread
Receive request
Parse destination
Open socket to destination
Forward request
For every Read on the destination socket, do a write on the client socket
For every Read on client socket, do a write on destination socket
If either socket closes (errors), close the other
So, two InputStream's, two OutputStreams, and just ferry data across them.

ServerSocket Android

Hey community I have the following ServerSocket which should listen to port 53000 and log any received data. However, I cannot seem to get past the server.accept() blocking call.
public void run() {
SocketServer server = new ServerSocket(53000);
//---buffer store for the stream---
byte[] buffer = new byte[1024];
//---bytes returned from read()---
int bytes;
//---keep listening to the InputStream until an
// exception occurs---
while (true) {
try {
socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = in.readLine();
Log.i("received response from server", str);
in.close();
socket.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e){
server.close();
Log.e(TAG, e.getMessage());
}
}
}
I have also given the application the INTERNET permission in the Manifest file.
()
To add to the mystery, I have also verified client responses get sent to that port.
Is there something in particular I need to do to make this work?
Thanks.
Your code is very messy and won't even compile. I made some adjustments so that i could test your code, and it's working fine. Here is the test application I used:
package com.test.stackoverflow
import java.io.BufferedReader;
public class ServerSocketTestActivity extends Activity {
/** Called when the activity is first created. */
private static String TAG = "ServerSocketTest";
private ServerSocket server;
Runnable conn = new Runnable() {
public void run() {
try {
server = new ServerSocket(53000);
while (true) {
Socket socket = server.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String str = in.readLine();
Log.i("received response from server", str);
in.close();
socket.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(conn).start();
}
#Override
protected void onPause() {
super.onPause();
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Using this code and netcat running via adb shell I was able to connect and communicate with the application.
When working with The Client Declare these methods
To access Streams
// gets the input stream // ObjectInputStream input;
// gets the output stream // ObjectOutputStream output;
// ServerSocket server;
// Socket connection;
maybe you have a another class to access the socket;
server = new ServerSocket(5001, 100);
// step 1 create socket connection
server = new ServerSocket(5001, 100);
while(the condition is true)
// step 2 wait for connection
// step 3 get streams
// step 4 : process the connection
// step 5 : close connection

Categories

Resources