Android saving file to memory card - java

In the below program i get the exception as shown below.Basically what i am trying to do is i am copying a file from a remote system to the device.but when saving to the memory card both on the emulator and device i am hitting an exception.The below exception is from the emulator where i can say that the memory card is not attached to the emulator and so the exception.but will the code work for a physical device.
How to make the code work on emulator and the device
Exception:
09-13 15:47:16.789: I/System.out(400): java.io.FileNotFoundException: /mnt/sdcard/Download/new.txt (Not a directory)
Code:
package com.scp2;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.jcraft.jsch.*;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Toast;
public class Scp2Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("guest", "17.30.5.2", 22);
session.connect();
Toast.makeText(this, "in try2" , Toast.LENGTH_SHORT).show();
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
File ofile = new File(Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_DOWNLOADS),"new.txt");
Toast.makeText(this, ofile.toString() , Toast.LENGTH_SHORT).show();
try {
FileOutputStream f = new FileOutputStream(ofile);
sftpChannel.get("/root/a.txt","/mnt/sdcard/download/dd.txt");
/*OR What shoud the abobe statement be **/
//sftpChannel.get("/root/a.txt",ofile); or this statement is correct
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println(e.toString());
}
sftpChannel.exit();
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}
}
}

Do this for file creation ; a better and safer way than yours
File dir = new File(Environment.getExternalStorageDirectory(),"/Downloads/");
dir.mkdirs();
String strFileName = "dd.html";
File file = new File(dir,strFileName);

Related

Android Studio, FileWriter not creating

I am trying to use FileWrite to write sensor data of the phone. But I could the get the basic generating new FileWriter working. It seems to return null. Here is the code, basically it tries to create a writer when a button is clicked then just write a few lines of 'hi'. But the program catches the exception at writer = new FileWriter(destPath, true); and Writer unsuccess. is toasted. Any idea why this error happens?
package com.example.jiajunyang.bowdetection;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SensorEventListener
{
private static final String destPath = "mySensorData.txt";
FileWriter writer;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
File sdCardFile = new File(Environment.getExternalStorageDirectory() + " \filename.txt");
Log.d("TAG", sdCardFile.getPath());
}
public void onStartClick(View view) {
try {
writer = new FileWriter(destPath, true);
Toast.makeText(getApplicationContext(), "Start writer. ",
Toast.LENGTH_SHORT).show();
writer.write("hi \n");
writer.write("hi \n");
writer.write("hi \n");
writer.flush();
writer.close();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Writer unsuccess. ",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
I develop Mobile Applications with Java.
Some Java APIs just don't work with Android. Are you sure FileWriter does?
Also, the way you define your destination path seems a little bit odd to me.
Here is an Android code example:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
You can find more details here.

Android Socket Connection Test [duplicate]

This question already has answers here:
NetworkOnMainThreadException [duplicate]
(5 answers)
Closed 6 years ago.
I'm trying to test if my Android App is connecting to a Rpi hot spot. I'm following this guide for the client code.
I want to have a toast message pop up depending on the state of socket.isConnected() when I hit a button. However, I think each time I try and implement it, I run into Network on the main thread problems. How could I change the following code to add a simple "if(true), send toast message" using the isConnected method in the onClick?
Thank you for any help!
package mrxhaleenterprise.sockettest;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 39169;
private static final String SERVER_IP = "172.24.1.1";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
onClick is called on main Thread.So you are writing to socket(Network Operation) on main thread which is causing problem. Your below code should run on background thread.
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
I want to have a toast message pop up depending on the state of socket.isConnected() when I hit a button.
No you don't. Once you've constructed that Socket, it is connected, and that method won't magically start returning false if the connection goes down. You need to maintain your own state of the connection, depending on whether you've encountered an IOException or end of stream on it. More probably you don't want the button at all, you want to pop up an error dialogue when the disconnect happens.

java exit app causes infinite loop

i have made a simple java app to print a text file then should terminate.
I tried to use the return statemend but didn't work at all. So i used the system.exit(0) but instead of exit the app, it goes in an infinite loop...
this is my code: can someone tell me what is wrong ?
package com.example.testprinterdemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import com.pda3505.Service.CaptureService;
import com.pda3505.printer.PrinterClassSerialPort;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class MainActivity extends Activity {
public static PrinterClassSerialPort printerClass = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
printerClass.write(new byte[] { 0x1d, 0x21,0x00,0x00});
printerClass.write(new byte[] { 0x1b, 0x26, 0x00 });
BufferedReader reader = null;
try {reader = new BufferedReader(new FileReader("/mnt/sdcard/temp.txt"));}
catch (FileNotFoundException e) {e.printStackTrace();}
String line = null;
try {line = reader.readLine();}
catch (IOException e) {e.printStackTrace();}
while(line!=null) {
printerClass.printText(line);
printerClass.printText("\n");
try {line = reader.readLine();}
catch (IOException e) {e.printStackTrace();}
}
system.exit(0);
}
private void init() {
printerClass = new PrinterClassSerialPort(new Handler());
printerClass.open(this);
Intent newIntent = new Intent(MainActivity.this, CaptureService.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(newIntent);
}
}
try{
//never hard code the file path in Android.
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"temp.txt";
BufferedReader reader = new BufferedReader(new FileReader(filePath));
while (true){
String line = reader.readLine();
if(line.length() > 0){
printerClass.printText(line);
printerClass.printText("\n");
}else{
break;
//you can use return too
}
}
}catch (IOException e){
e.printStackTrace();
}
In your approach, line is never null, it is either "" or it is " " or "\n" etc, but never null. so listen for length and break the loop
Please avoid multiple try catch blocks when you can have your code under single try block. And please scope the variables properly, do not declare variables outside the scope where it is not used, as it causes problems for JAVA Garbage collector/

Transferring Multiple Files over Socket [duplicate]

This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 7 years ago.
I'm developing an application and I want to transfer files from a computer to a phone using sockets. I'm able to transfer one file but when I want to transfer multiple files, they pile up. Here's how the program works:
I get a screenshot from computer using Robot.
I save it as Send.jpg.
I send the image. Let's say for example its size is 1 MB.
I receive the image on phone.
I display it in an ImageView.
And loop through these steps again until the user closes the activity on phone.
But the result is this :
I get the first screenshot (Send.jpg: 1 MB) send it and receive it on phone. Get the second one (Send.jpg: 2 MB) send it and receive it on phone. and the third one and etc...
It never gets displayed on phone. And when I check the phone storage using explorer, I see one image - its size is the size of the first image + the second + the third ...
I guess my problem is i have to stop the InputStream, please help.
Code :
Server :
package application;
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import javax.imageio.ImageIO;
public class ScreenCapture {
Socket socket;
OutputStream os;
Robot robot;
PrintStream ps;
public ScreenCapture() throws IOException, AWTException {
// TODO Auto-generated constructor stub
socket = SocketWrapper.getSocket();
os = socket.getOutputStream();
robot = new Robot();
ps = new PrintStream(socket.getOutputStream());
new Record().start();
}
private class Record extends Thread{
#Override
public void run() {
while(true){
int count;
Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage img = robot.createScreenCapture(rect);
try {
ImageIO.write(img, "jpg", new File("/Users/Tomahawk/Documents/MovieMaker/send.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileInputStream fis;
try {
File f = new File("/Users/Tomahawk/Documents/MovieMaker/send.jpg");
fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] byteArray = new byte[(int) f.length()];
long filesize = f.length();
while((count = bis.read(byteArray)) > 0){
os.write(byteArray,0,count);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Sent File");
}
}
}
}
Client (Phone) :
package com.pcontrol.tomahawk.pcontrol;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ScreenCapture extends Activity {
Socket socket;
InputStream is;
OutputStream os;
Scanner scanner;
ImageView screenCap;
long filesize = 0;
int i=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_capture);
socket = SocketWrapper.getSocket();
try {
is = socket.getInputStream();
scanner = new Scanner(is);
} catch (IOException e) {
e.printStackTrace();
}
screenCap = (ImageView) findViewById(R.id.screenCap);
new ReceiveFiles().execute();
}
private class ReceiveFiles extends AsyncTask<Void,Void,Void> {
#Override
protected Void doInBackground(Void... params) {
try {
os = new FileOutputStream("/sdcard/"+i+".jpg");
copy(is, os);
publishProgress();
} catch (IOException e) {
e.printStackTrace();
}
i++;
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
Bitmap bmp = BitmapFactory.decodeFile("/sdcard/"+i+".jpg");
screenCap.setImageBitmap(bmp);
}
}
static void copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[60000];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_screen_capture, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
You're not telling the receiver where one file ends and the next one starts.
You could add a basic framing protocol, for example one where you first send the size of the file and then the data. That way the receiver can count the bytes it reads and knows when to close the current file and open another.
Alternatively you could use separate sockets to send each file, but it looks like that would require major changes to your architecture.

Problem with MulticastSocket on Java-Android

I'm starting to code with MulticastSocket, trying to make a simple app with a client and a server to send messages.
The code I have for the server:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
public class Servidor {
private static MulticastSocket ms;
public static void main(String[] args) throws IOException{
InetAddress sessAddr = InetAddress.getByName("224.2.76.24");
try{
sessAddr = InetAddress.getByName("224.2.76.24");
ms = new MulticastSocket(5500);
ms.joinGroup(sessAddr);
while (true)
{
byte[] mensaje = new byte[1024];
mensaje = "aa".getBytes();
DatagramPacket dp = new DatagramPacket(mensaje, mensaje.length,sessAddr,5500);
ms.send(dp);
}
}
catch (SocketException se) {
System.err.println(se);
}
ms.leaveGroup(sessAddr);
}
}
And this on the client:
package com.example;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
public class ClienteMultiCast extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView Mensaje;
Mensaje =(TextView)findViewById(R.id.Mensaje);
InetAddress ia = null;
byte[] buffer = new byte[65535];
MulticastSocket ms = null;
int port = 5500;
try {
ia = InetAddress.getByName("224.2.76.24");
DatagramPacket dp = new DatagramPacket(buffer, buffer.length,ia,port);
ms = new MulticastSocket(port);
ms.joinGroup(ia);
while (true) {
ms.receive(dp);
String s = new String(dp.getData(),0,dp.getLength());
Mensaje.setText(s);
}
} catch (UnknownHostException e) {Mensaje.setText(e.getMessage());} catch (IOException e) {Mensaje.setText(e.getMessage()); }
try {
ms.leaveGroup(ia);
} catch (IOException e) {
Mensaje.setText(e.getMessage());
}
}
}
The problem is that when I start both, nothing happens. The client doesn't get any message.
Any idea what's wrong?
Diego,
By default, the Android WiFi stack filters out multicast packets. Take a look at http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html.
You need something along the lines of:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Turn off multicast filter */
MulticastLock mcastLock = new MulticastLock();
mcastLock.acquire();
/* Process Multicast Packets */
}
It appears that Multicast support in Android is not as solid as some of use might hope. See http://codeisland.org/2012/udp-multicast-on-android/
Ie whether it actually works out or may be device dependent. It is not working on my Nexus5.
https://code.google.com/p/android/issues/detail?id=51195

Categories

Resources