I am composing a WiFi Direct android app following guide of Google Developer's guide. I am just beginning to learn. I am stuck in sending an image from Client to Server. The following is Client and Server coding taken from Demo:
This is a code to call Client Intent (MainActivity):
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode ==SELECT_IMAGE) {
Log.d(MainActivity.TAG, "onActivityResult Start");
Log.d(MainActivity.TAG, "requestCode "+requestCode);
Uri uri = data.getData();
Intent serviceIntent = new Intent(this, FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
Log.d(MainActivity.TAG, "file path " + uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_ADDRESS, IP_SERVER);
serviceIntent.putExtra(FileTransferService.EXTRAS_PORT, PORT);
this.startService(serviceIntent);
} else {
Log.d(MainActivity.TAG, "Service transfer failed");
}
}
This is code for Client (I used IntentService in a separate class):
public class FileTransferService extends IntentService {
public static final int SOCKET_TIMEOUT = 5000;
public static final String ACTION_SEND_FILE = "com.moon.android.wifidirectproject_moon.action.SEND_FILE";
public static final String EXTRAS_ADDRESS = "go_host";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_PORT = "go_port";
Socket socket = new Socket();
public FileTransferService() {
super("FileTransferService");
}
#Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_ADDRESS);
int port = intent.getExtras().getInt(EXTRAS_PORT);
try {
Log.d(MainActivity.TAG, "Opening client socket - ");
Log.d(MainActivity.TAG, "fileUri" + fileUri);
Log.d(MainActivity.TAG, "host" + host);
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.d(MainActivity.TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
ContentResolver cr = context.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(fileUri));
Log.d(MainActivity.TAG, "is - " + is);
} catch (FileNotFoundException e) {
Log.d(MainActivity.TAG, e.toString());
}
copyFile(is, stream);
Log.d(MainActivity.TAG, "Client: Data written");
} catch (IOException e) {
Log.e(MainActivity.TAG, e.getMessage());
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
Log.d(MainActivity.TAG, e.toString());
return false;
}
return true;
}
}
This is a call to Server Intent
#Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
if (info.groupFormed && info.isGroupOwner) {
InetAddress groupOwnerAddress = info.groupOwnerAddress;
ownerIP = groupOwnerAddress.getHostAddress();
Log.d(MainActivity.TAG, "Owner connected" + ownerIP);
Intent serverIntent = new Intent(mActivity, ServerService.class);
serverIntent.putExtra("port",MainActivity.PORT);
mActivity.startService(serverIntent);
.....
The following is Server Intent Service:
public class ServerService extends IntentService {
public static String mClientIP;
public ServerService() {
super("ServerService");
}
#Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
Integer port = intent.getExtras().getInt("port");
try {
ServerSocket serverSocket = new ServerSocket(port);
Socket client = serverSocket.accept();
Log.d(MainActivity.TAG, "Server: Socket opened");
Log.d(MainActivity.TAG, "clientIP" + client.getInetAddress().toString());
mClientIP = client.getInetAddress().toString();
Log.d(MainActivity.TAG, "Server: connection done");
/*
*************I am stuck here******************************
*/
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.d(MainActivity.TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
} catch (IOException e) {
Log.e(MainActivity.TAG, e.getMessage());
} finally {
stopSelf();
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
Log.d(MainActivity.TAG, e.toString());
return false;
}
return true;
}
}
Lastly, the following is my LogCat. I put asterisk marks where no further progress is made in Server.
1) Server device (Initial State)
: search start
: WiFi_enabled
: Owner connected192.168.49.1
2) Client Device(sending image):
...............................
Opening client socket -
: fileUricontent://media/external/images/media/16871
: host192.168.49.1
: Client socket - true
: WiFi_enabled
: is - android.os.ParcelFileDescriptor$AutoCloseInputStream#3c520d34
3) Again Server Device
: Server: Socket opened
: clientIP/192.168.49.133
: Server: connection done
: open failed: ENOENT (No such file or directory)
I must confess that I don't fully understand the server/client. I just have rough knowledge. However, if you give me any hint on what I am wrong with, I will try to learn more for myself. I've spent several days working on it but couldn't work it out. Thanks for reading this post.
Related
I've been working on a project where i would send a file from the android app i wrote to my esp8266; the esp8266 then will write the file onto the SD card. but when esp receives the file for example a .jpg, it's all garbled and noisy.
and if i receive a .txt file it will always add a (¬í ur [B¬óøTà xp ¬) at the beginning, regardless of what method i use.
Here's my android code:
(Server thread)
Socket mySocket = null;
ServerSocket serverSocket = null;
class ServerThread implements Runnable{
int serverPort;
public ServerThread(int serverPort){
this.serverPort = serverPort;
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(serverPort);
mySocket = serverSocket.accept();
output = new PrintWriter(mySocket.getOutputStream());
input = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
Log.i("connection", "server");
runOnUiThread(new Runnable() {
#Override
public void run() {
connection_state = true;
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
TextView thisText = new TextView(MainActivity.this);
thisText.setId(append);
thisText.setText("Server port: " + 8080 + " ... A client just made connection");
thisText.setTextSize(20);
thisText.setBackgroundColor(Color.rgb(25, 24, 24));
thisText.setTextColor(Color.rgb(0, 100, 0));
append++;
thisText.setGravity(20);
thisText.setLayoutParams(textParams);
myTexts.addView(thisText);
}
});
new Thread(new ReceiveStringThread()).start();
} catch (IOException e) {
e.printStackTrace();
Log.i("connection", "couldn't establish connection");
} finally {
try {
if (socket != null)
socket.close();
if (serverSocket != null)
serverSocket.close();
}catch (IOException e){
e.getStackTrace();
}
}
}
}
Send file thread:
class SendFileThread implements Runnable{
String filePath;
SendFileThread(String filePath) {
this.filePath = filePath;
}
#Override
public void run() {
if(connection_state) {
File findFile = new File(filePath);
byte[] sendIt = new byte[(int) findFile.length()];
try {
BufferedInputStream bufferFile = new BufferedInputStream(new FileInputStream(findFile));
bufferFile.read(sendIt, 0, sendIt.length);
ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
oos.writeObject(sendIt);
oos.flush();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "File was sent successfully. size: " +
(int) findFile.length() + " bytes", Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.getStackTrace();
}finally {
try {
mySocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
and here's my arduino code for esp8266:
#include <ESP8266WiFi.h>
#include <SD.h>
#ifndef STASSID
#define STASSID "ESP_CLIENT"
#define STAPSK "client-1234"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "192.168.1.103";
const uint16_t port = 8080;
boolean connectionStatus = false;
byte buffer_array[10] = {'0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00'};
int num_read;
WiFiClient client;
void setup() {
Serial.begin(57600);
//.................Initiate SD card................//
if(!SD.begin(SS)){
Serial.println("SD card initialization failed!");
return;
}else{
Serial.println("SD card initialized successfully");
}
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
char *printBytes(byte *bytes) {
char bytesStr[10];
sprintf(bytesStr, "%02X", *bytes);
Serial.print("byte: ");
Serial.println(bytesStr);
return bytesStr;
}
void loop() {
if(!connectionStatus){
Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);
if (!client.connect(host, port)) {
Serial.println("********************************************Connection failed************************************************");
connectionStatus = false;
delay(1000);
return;
}else{
Serial.println("********************************************Connection established with server***********************************************");
connectionStatus = true;
}
Serial.println("sending data to server");
if (client.connected()) {
client.println("hello from ESP8266");
}
}
if(client.available()){
Serial.println("Receiving...");
num_read = client.readBytesUntil('\n',buffer_array, 10);
Serial.println("bytes read: " + (String)num_read);
printBytes(buffer_array);
File appendSD = SD.open("/testESP32.txt", FILE_WRITE);
if(!appendSD){
Serial.println("not found");
return;
}else{
Serial.println("Writing byte to file...");
appendSD.write(buffer_array, num_read);
appendSD.close();
}
}
}
and regardless of which mode i put them into, whether it'll be esp as server and android device as client or reverse, it won't make a difference at all.
anyone knows how to fix this?
i modified the SendFileThread as below but it only worked for sending .txt files correctly. but sending image files like .jpg problem still stands.
class SendFileThread implements Runnable{
String filePath;
SendFileThread(String filePath) {
this.filePath = filePath;
}
#Override
public void run() {
if(connection_state) {
File findFile = new File(filePath);
byte[] sendIt = new byte[(int) findFile.length()];
try {
BufferedInputStream bufferFile = new BufferedInputStream(new FileInputStream(findFile));
bufferFile.read(sendIt, 0, sendIt.length);
OutputStream os= mySocket.getOutputStream();
os.write(sendIt);
os.flush();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "File was sent successfully. size: " +
(int) findFile.length() + " bytes", Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.getStackTrace();
}finally {
try {
mySocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
}
}
}
and i wanna be able to send all kinds of data like .pdf .doxs as well and ObjectOutputStream sends all this kinds of files just fine if although i'm sending them to another android phone not esp8266
SOLVED: i used
client.read(buffer_array, 10);
for image files instead of
client.readBytesUntil('\n', buffer_array, 10);
and in android changed
ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
oos.writeObject(sendIt);
to
OutputStream os= mySocket.getOutputStream();
os.write(sendIt);
and it finally worked for all types of files!
I am trying to write an android application that streams images taken from a first device, through the camera, to a second device with WiFi Direct.
I am trying to use this GitHub project, WiFiDIrectDemo, I managed to connect the devices and to send just one file.
When I try to send a second file I don't get any error and, from the logs, everything seems to work, but the second device doesn't get any file.
Is this a known issue? I have tried to look on the internet but I could not find anything that could help me.
I am attaching my File Transfer Service class:
public class FileTransferService extends IntentService {
Handler mHandler;
public static final int SOCKET_TIMEOUT = 50000; //ms
public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
public static int PORT = 8888;
public static final String inetaddress = "inetaddress";
public static final int ByteSize = 512;
public static final String Extension = "extension";
public static final String Filelength = "filelength";
public FileTransferService(String name) {
super(name);
}
public FileTransferService() {
super("FileTransferService");
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mHandler = new Handler();
}
#Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
InputStream is = null;
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
String extension = intent.getExtras().getString(Extension);
String filelength = intent.getExtras().getString(Filelength);
try {
if(!socket.isConnected())
{
Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
socket.bind(null);
socket.setReuseAddress(true);
socket.connect((new InetSocketAddress(host, port)),5000); // ..,socket_timeout)
Log.e("File Transfer Service"," socket connect");
}
Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
Log.e("file transfer" +
" service", "get output stream");
ContentResolver cr = context.getContentResolver();
Long FileLength = Long.parseLong(filelength);
WiFiTransferModal transObj = null;
ObjectOutputStream oos = new ObjectOutputStream(stream);
if(transObj == null) transObj = new WiFiTransferModal();
transObj = new WiFiTransferModal(extension,FileLength);
oos.writeObject(transObj);
try {
is = cr.openInputStream(Uri.parse(fileUri));
} catch (FileNotFoundException e) {
Log.d(WiFiDirectActivity.TAG, e.toString());
}
DeviceDetailFragment.copyFile(is, stream);
Log.d(WiFiDirectActivity.TAG, "Client: Data written");
oos.flush();
oos.close(); //close the ObjectOutputStream after sending data.
} catch (IOException e) {
Log.e("file transfer service","unable to connect: " + e.toString() );
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (Exception e) {
// Give up
e.printStackTrace();
Log.e("File transfer service","exception socket.close: " + e.toString());
}
}
}
else Log.e("file transfer service","socket is already null");
}
}
}
}
EDIT
Receiving code:
public class FileServerAsyncTask extends AsyncTask<String, String, String> {
// private TextView statusText;
private Context mFilecontext;
private String Extension, Key;
private File EncryptedFile;
private long ReceivedFileLength;
private int PORT;
public FileServerAsyncTask(Context context, int port) {
this.mFilecontext = context;
handler = new Handler();
this.PORT = port;
}
#Override
protected String doInBackground(String... params) {
try {
Log.e("device detail fragment", "File Async task port-> " + PORT);
ServerSocket serverSocket = new ServerSocket();
Log.e("device detail fragment"," new server");
serverSocket.setReuseAddress(true);
Log.e("device detail fragment","set reuse address");
serverSocket.bind(new InetSocketAddress(PORT));
Log.e("device detail fragment","socket bind");
Socket client = serverSocket.accept();
Log.e("device detail fragment "," socket client accept");
Log.e("Device detail fragment ", "client inet address" + client.getInetAddress());
WiFiClientIp = client.getInetAddress().getHostAddress();
Log.e("device detail fragment"," get client ip: " + WiFiClientIp);
ObjectInputStream ois = new ObjectInputStream(
client.getInputStream());
Log.e("device detail fragment","object input stream + " + ois.toString());
WiFiTransferModal obj = null;
String InetAddress;
try {
obj = (WiFiTransferModal) ois.readObject();
Log.e("device detail fragment"," read object");
if (obj != null) {
Log.e("device detail fragment"," obj != null ");
InetAddress = obj.getInetAddress();
Log.e("device detail fragment"," get inet address: " +
InetAddress);
if (InetAddress != null
&& InetAddress
.equalsIgnoreCase(FileTransferService.inetaddress)) {
SharedPreferencesHandler.setStringValues(mFilecontext,
mFilecontext.getString(R.string.pref_WiFiClientIp), WiFiClientIp);
//set boolean true which identify that this device will act as server.
SharedPreferencesHandler.setStringValues(mFilecontext,
mFilecontext.getString(R.string.pref_ServerBoolean), "true");
ois.close(); // close the ObjectOutputStream object
Log.e("device detail fragment"," output stream close");
// after saving
serverSocket.close();
Log.e("device detail fragment","close");
return "Demo";
}
Log.e("device detail fragment","FileName got from socket on other side->>> "+
obj.getFileName());
}
final File f = new File(
Environment.getExternalStorageDirectory() + "/"
+ FolderName + "/"
+ obj.getFileName());
Log.e("background"," new file f from inputstream");
File dirs = new File(f.getParent());
Log.e("device detail fragment"," f get parent()");
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.e("device detail fragment","create new file");
/**
* Receive file length and copy after it
*/
this.ReceivedFileLength = obj.getFileLength();
InputStream inputstream = client.getInputStream();
Log.e("device detail fragment","input stream client get input");
Message msg = Message.obtain();
msg.what = 1;
try
{
// send the images to the image view through handler
Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
Log.e("device detail fragment", "decode stream");
Bundle b = new Bundle();
b.putParcelable("bitmap", bitmap);
msg.setData(b);
Log.e("device detail fragment","message: " + msg.toString());
messageHandler.sendMessage(msg);
}
catch (Exception e)
{
Log.e("device detail fragment","stream not decoded into bitmap with" +
"exception: " + e.toString());
}
copyRecievedFile(inputstream, new FileOutputStream(f),
ReceivedFileLength);
Log.e("device detail fragment","copy input stream into file");
ois.close(); // close the ObjectOutputStream object after saving
// file to storage.
Log.e("device detail fragment","ois close");
/**
* Set file related data and decrypt file in postExecute.
* */
this.Extension = obj.getFileName();
this.EncryptedFile = f;
final Uri uri = Uri.fromFile(f);
return f.getAbsolutePath();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
Log.e("device detail fragment", e.getMessage());
}
return "";
} catch (IOException e) {
Log.e("device detail fragment", e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
if (!result.equalsIgnoreCase("Demo")) {
Log.e("On Post Execute","result +" + result);
} else if (!TextUtils.isEmpty(result)) {
/**
* To initiate socket again we are initiating async task
* in this condition.
*/
FileServerAsyncTask FileServerobj = new
FileServerAsyncTask(mFilecontext, FileTransferService.PORT);
if (FileServerobj != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
FileServerobj.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{null});
Log.e("Post Execute", "FileServerobj.execute on executor");
} else
{
FileServerobj.execute();
Log.e("Post Execute", "FileServerobj.execute");
}
}
}
}
}
#Override
protected void onPreExecute() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(mFilecontext);
}
if(imageView == null){
imageView = new ImageView(mFilecontext);
}
}
}
The server will receive a file and then opens it by letting the user choose an app to display the file. The server asynctask then has finished. So no new file can be received. So i do not believe you if you say that the logs tell that all is normal. Your client socket can not connect to begin with. All is intented behaviour.
* To initiate socket again we are initiating async task * in this condition..
Your code is not coming there.
You have to start an asynctask again to receive the next file.
Here is a source of StreamProxy I used for my project
public class StreamProxy implements Runnable {
private static final String LOG_TAG = "Stream proxy: %s";
private int port = 0;
private boolean isRunning = true;
private ServerSocket socket;
private Thread thread;
public StreamProxy() {
init();
start();
}
public int getPort() {
return port;
}
public String getProxyUrl(String uri, String tag) {
return String.format("http://127.0.0.1:%d/%s", getPort(), uri);
}
private void init() {
try {
socket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
socket.setSoTimeout(5000);
port = socket.getLocalPort();
Timber.d(LOG_TAG, "port " + port + " obtained");
} catch (IOException e) {
Timber.e(e, "Error initializing server");
}
}
private void start() {
if (socket == null) {
throw new IllegalStateException("Cannot start proxy; it has not been initialized.");
}
thread = new Thread(this);
thread.start();
}
public void stop() {
isRunning = false;
if (thread == null) {
throw new IllegalStateException("Cannot stop proxy; it has not been started.");
}
thread.interrupt();
try {
thread.join(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
Timber.d(LOG_TAG, "running");
while (isRunning) {
try {
Socket client = socket.accept();
if (client == null) {
continue;
}
Timber.d(LOG_TAG, "client connected");
client.setKeepAlive(false);
readRequest(client);
} catch (SocketTimeoutException e) {
} catch (IOException e) {
Timber.e(e, "Error connecting to client");
}
}
Timber.d(LOG_TAG, "Proxy interrupted. Shutting down.");
}
#Nullable
private void readRequest(Socket client) throws IOException {
InputStream is;
String firstLine;
try {
is = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
firstLine = reader.readLine();
} catch (IOException e) {
Timber.e(LOG_TAG, "Error parsing request", e);
return;
}
if (firstLine == null) {
Timber.i(LOG_TAG, "Proxy client closed connection without a request.");
return;
}
StringTokenizer st = new StringTokenizer(firstLine);
st.nextToken();
String uri = st.nextToken().substring(1);
Timber.d(LOG_TAG, uri);
processRequest(client, uri, "");
}
#Nullable
private HttpURLConnection download(String path) throws IOException {
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage());
}
return connection;
}
private void processRequest(Socket client, String url, String tag)
throws IllegalStateException, IOException {
Timber.d(LOG_TAG, "processing");
HttpURLConnection realResponse = download(url);
if (realResponse == null) {
return;
}
InputStream data = realResponse.getInputStream();
socketWriter.setClient(client);
try {
int readBytes;
Timber.d(LOG_TAG, "writing data to client");
// Start streaming content.
byte[] buff = new byte[1024 * 8];
while (isRunning && (readBytes = data.read(buff)) != -1) {
client.getOutputStream().write(buff, 0, readBytes)
}
Timber.d(LOG_TAG, "end writing data");
} catch (IOException e) {
Timber.e(e, "Error data transfer to client");
} finally {
Timber.d(LOG_TAG, "finally block");
if (data != null) {
data.close();
}
}
}
}
It works perfectly on Android <5.0 but on Android 5.0.+ I have following error with using MediaExtractor(http://developer.android.com/reference/android/media/MediaExtractor.html)
NuCachedSource2﹕ source returned error -1, 10 retries left
NuCachedSource2﹕ source returned error -1, 9 retries left
...
And no error messages when using Mediaplayer just few quiet retries.
Maybe for Android 5 there is another way for audio streaming with caching?
Stream proxy working well actually. All errors I get from MediaExtractor was about m4a container. For most files packed in m4a format, there is no way to play it via stream by using components from Android SDK. Except some roms on Samsung, LG and some other manufactures that has this feature.
I want to make my android app open socket to my windows console app and they communicate with each other. The socket is opened and data is sent and received in windows app, but my android app does not receive the answer which sent by windows. I watch the packets in my android and I saw the packets are coming but I do not know why my app do not receive it!
windows app server class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
Console.WriteLine("\nStarting server...");
this.tcpListener = new TcpListener(IPAddress.Any, 1234);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
Console.WriteLine("\nWaiting for clients to connect...");
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Console.WriteLine("\nIncoming from client...");
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
try
{
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("\nReceived: \n\n" + encoder.GetString(message, 0, bytesRead));
//By FMR
string response = "random responsive: " + new Random().Next(1000).ToString() + "\n";//"\r\n";
//writeData(clientStream, response);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
clientStream.Write(msg, 0, msg.Length);
clientStream.Flush();
Console.WriteLine("\nResponed ..." + response);
}
}
catch (Exception ex)
{
Console.WriteLine("\nException while: " + ex.Message);
}
tcpClient.Close();
}
}
my android thread:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
ServerSocket serverSocket = null;
Boolean bRun = true;
try {
socket = new Socket(ip, port);
if(outputStream == null) {
outputStream = new DataOutputStream(socket.getOutputStream());
}
// become server
serverSocket = new ServerSocket(port);
Log.i(G.TAG, "before serverSocket.accept");
socket = serverSocket.accept();
Log.i(G.TAG, "response recieve: ");
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e) {
try {
serverSocket.close();
} catch (IOException e1) {
Log.e(G.TAG, "serverSocket.close() e: " + e1.getMessage());
}
try {
socket.close();
} catch (IOException e1) {
Log.e(G.TAG, "socket.close() e: " + e1.getMessage());
}
}
Log.i(G.TAG, "after start recieve: ");
while (bRun) {
try {
Log.i(G.TAG, "while start: ");
String message = inputStream.readLine();
Log.i(G.TAG, "response message: " + message);
if (message != null) {
setListMessage(false, message);
}
}
catch (IOException e) {
bRun = false;
Log.e(G.TAG, "while bRun e: " + e.getMessage());
}
}
}
});
thread.start();
// in another function, my message is sent successfully from android and receive in windows
I found the problem, this line
socket = serverSocket.accept();
made the problem when I comment the line, the android app received the response!
Does anybody know why?
i want to make an application for transfer files using wifi direct, but my send and receiver progress bar won't update
my sender
public void Server () {
new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
//receive ip
serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
ClientIP = line;
}
in.close();
socket.close();
serverSocket.close();
socket = null;
serverSocket = null;
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//send file
socket = new Socket();
socket.bind(null);
socketAddress = new InetSocketAddress(ClientIP, portal);
socket.connect(socketAddress, SOCKET_TIMEOUT);
FragmentManager fm = getFragmentManager();
md = new MyDialog("Send to " + ClientIP );
md.setRetainInstance(true);
md.setCancelable(true);
md.show(fm, "Sender");
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
byte buf[] = new byte[1024];
File myFile = new File (path);
filelength = file.length();
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
while ((len = bis.read(buf)) != -1) {
fileSize+=len;
os.write(buf, 0, len);
os.flush();
//count for progress bar
double d = (double) (fileSize * 100) / filelength;
progressBarStatus = (int) Math.round(d);
progressBarHandler.post(new Runnable() {
public void run() {
md.updateProgress(progressBarStatus);
}
});
}
os.close();
fis.close();
bis.close();
socket.close();
// ok, file is downloaded,
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isSent = true;
runOnUiThread(new Runnable() {
public void run() {
if(isSent) {
Toast.makeText(getApplicationContext(), "File Sent", Toast.LENGTH_SHORT).show();
}
}
});
md.dismiss();
}
} catch (IOException e) {
Log.e(TAG, "I/O Exception", e);
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}).start();
}
my receiver
public void Client (final String hostAddress) {
socketAddress = new InetSocketAddress(hostAddress, port);
socket = new Socket();
new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
//sent ip
socket.bind(null);
socket.connect(socketAddress, SOCKET_TIMEOUT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(messsage);
out.flush();
out.close();
socket.close();
socket = null;
//receive file
socket = new Socket();
serverSocket = new ServerSocket(portal);
socket = serverSocket.accept();
final String name;
final String ext;
String[] tokens = filename.split("\\.(?=[^\\.]+$)");
name = tokens[0];
ext = tokens[1];
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getPackageName() + "/" + name + System.currentTimeMillis()
+ "." + ext);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
FragmentManager fm = getFragmentManager();
md = new MyDialog("Receive from " + HostIP);
md.setRetainInstance(true);
md.setCancelable(true);
md.show(fm, "Receiver");
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
filelength = f.length();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
while ((len = is.read(buf)) != -1) {
bos.write(buf, 0, len);
bos.flush();
fileSize+=len;
double d = (double) (fileSize * 100) / filelength;
progressBarStatus = (int) Math.round(d);
progressBarHandler.post(new Runnable() {
public void run() {
md.updateProgress(progressBarStatus);
}
});
}
is.close();
fos.close();
bos.close();
socket.close();
serverSocket.close();
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isSent = true;
// close the progress bar dialog
//progressBar.dismiss();
runOnUiThread(new Runnable() {
public void run() {
// some code #3 (that needs to be ran in UI thread)
if(isSent) {
Toast.makeText(getApplicationContext(), "File Received", Toast.LENGTH_SHORT).show();
btn.setEnabled(true);
}
}
});
md.dismiss();
}
} catch (IOException e) {
Log.e(TAG, "IO Exception.", e);
}
}
}).start();
}
and i use dialog fragment because i use API 14+
my dialog class
public class MyDialog extends DialogFragment {
ProgressBar mProgressBar;
String title;
public MyDialog (String title) {
this.title = title;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.popup, container);
mProgressBar = (ProgressBar)view.findViewById(R.id.pb);
getDialog().setTitle(title);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
#Override
public void onDestroyView()
{
if (getDialog() != null && getRetainInstance())
getDialog().setDismissMessage(null);
super.onDestroyView();
}
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
super.onCancel(dialog);
Toast.makeText(getActivity().getApplicationContext(), "Connection lost. Retry", Toast.LENGTH_SHORT).show();
getActivity().finish();
}
public void updateProgress(int percent)
{
mProgressBar.setProgress(percent);
}
}
i don't know why my code isn't working, my progress bar won't update and file not send.
Anyone can help me? thx before
You've got a lot of code, but as long as I know, the receiver should use an AsyncTask, that's how I do it and it works for me. Instead of a thread use an Asynctask and the OnProgressUpdate method of the AsyncTask to update the ProgressDialog in the main thread.
For example:
public class getFile extends AsyncTask<Void, String, Void>
{
ProgressDialog pB;
String hostAddress=null;
InetSocketAddress socketAddress;
Socket socket=null;
ServerSocket serverSocket=null;
int port=3001;
int SOCKET_TIMEOUT = 3000;
public getFile(String _hostAddress, Context context)
{
this.pB = new ProgressDialog(context);
this.pB.setTitle(context.getText(R.string.sYourMessageText);
this.pB.setMessage(null);
this.pB.setProgressNumberFormat(null);
this.pB.setProgressPercentFormat(null);
this.pB.setCancelable(false);
Drawable d = getResources().getDrawable(R.drawable.x_greenprogress);
pB.setProgressDrawable(d);
pB.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
hostAddress=_hostAddress;
}
#Override
protected void onPreExecute()
{
this.pB.show();
}
#Override
protected Void doInBackground(Void... params)
{
try {
//sent ip
socketAddress = new InetSocketAddress(this.hostAddress, port);
socket = new Socket();
socket.bind(null);
socket.connect(socketAddress, SOCKET_TIMEOUT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(messsage);
out.flush();
out.close();
socket.close();
socket = null;
//receive file
socket = new Socket();
serverSocket = new ServerSocket(portal);
socket = serverSocket.accept();
final String name;
final String ext;
String[] tokens = filename.split("\\.(?=[^\\.]+$)");
name = tokens[0];
ext = tokens[1];
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getPackageName() + "/" + name + System.currentTimeMillis()
+ "." + ext);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
while ((len = is.read(buf)) != -1)
{
bos.write(buf, 0, len);
bos.flush();
fileSize+=len;
// to update the progress bar just call:
this.publishProgress("" + (int) ((fileSize * 100) / filelength));
}
is.close();
fos.close();
bos.close();
socket.close();
serverSocket.close();
}
#Override
protected void onProgressUpdate(String... progress)
{
this.pB.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(Void result)
{
if (this.pB.isShowing())
this.pB.dismiss();
}
}
EDIT:
By the way, why do you connect to the server, send an IP close the connection and wait for the server to connect? Why don't use the first socket to do the file transfer? The connection has already been established.