I have 2 problems with Android app. First of all I created Python Server and Android Java Client. The main purpose is to send some commands from Python to Java. So, my problems are here:-
1- When I call directory.list() not all files appears like images, I mean that images cannot appear to me but other files appears normally on Emulator and Real device.
2- When I run my code on Emulator, every thing is fine like send and receive data from and to Python and Java, and Java ask me about permission and wait until I accept or dinay, but when I run the same code on real device, all works fine instead of this line :-
else if(command.split(" ")[0].trim().equals("download"))
the program crashes and say "droidApp stopped". I don't know if the error with in request permission from user or not because the request screen don't appear to me on real device which is appeared on Emulator, and I can't connect my real device with laptop because of problem with my hardware usb. I'm sorry for my bad way of deliver my problem, but that is how can I describe it.
This is my full Java code:-
package droid.client;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Toast;
import java.net.InetAddress;
import java.net.Socket;
import java.io.*;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Base64;
public class MainActivity extends Activity {
private int STORAGE_PERMISSION_CODE = 1;
private Socket socket;
boolean sendData = true; // Flag to indicate whether data should be sent
//String Str = "HelloServer";
private static final int SERVERPORT = 2307;
private static final String SERVER_IP = "192.168.1.8";
private static boolean GET_FILE_PERMISSION = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
//String path = "/sdcard";
String path = Environment.getExternalStorageDirectory().toString() + "/Download";
File directory = new File(path);
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
DataInputStream Input = new DataInputStream(socket.getInputStream());
//DataOutputStream Output = new DataOutputStream(socket.getOutputStream());
FileInputStream getFileStream = null;
int bufLength = 4096;
byte[] buffer = new byte[4096];
byte[] data;
String ack;
while (socket.isConnected()){
String command = Input.readLine();
String Str = "";
if(command.equals("ls"))
{
directory = new File(path);
String[] files = directory.list();
for (int i = 0; i < files.length; i++)
{
Str += (files[i] + "\n");
}
}
else if(command.split(" ")[0].equals("cd"))
{
String subPath = command.split(" ")[1];
if(subPath.equals(".."))
{
String[] filePath = path.split("/");
if(filePath.length > 1)
{
for(int i = 0; i < filePath.length - 1; i++)
{
if(i == filePath.length - 2)
Str += filePath[i];
else
Str += filePath[i] + '/';
}
path = Str;
Str = "[+] Successful, new path is : " + path;
}
else
{
Str = "[-] Error, no back available.";
}
}
else
{
directory = new File(path);
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
if (files[i].equals(subPath)) {
path += '/' + subPath;
Str = "[+] Successful, new path is : " + path;
break;
}
if(i + 1 == files.length)
{
Str = "[-] Error, no such file or directory.";
break;
}
}
}
}
else if(command.split(" ")[0].trim().equals("download"))
{
String fileName = command.split(" ")[1].trim();
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "You have already granted this permission!",
Toast.LENGTH_SHORT).show();
} else {
requestStoragePermission();
}
getFileStream = new FileInputStream(path + "/" + fileName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int readLength;
while ((readLength = getFileStream.read(buffer, 0, bufLength)) != -1) {
out.write(buffer, 0, readLength);
}
data = out.toByteArray();
String imageString = Base64.getEncoder().encodeToString(data);
int firstIndex = 0;
int lastIndex = 4096;
int lengthOfFile = imageString.length();
while(lengthOfFile > 0)
{
if(lengthOfFile >= 4096)
{
sendMessage(imageString.substring(firstIndex,lastIndex));
firstIndex += 4096;
lastIndex += 4096;
lengthOfFile -= 4096;
}
else
{
lastIndex = (lastIndex - 4096) + lengthOfFile;
lengthOfFile = 0;
sendMessage(imageString.substring(firstIndex,lastIndex));
}
ack = Input.readLine();
}
Str = "DONE";
//out.close();
getFileStream.close();
}
sendMessage(Str);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
private void sendMessage(String Str){
try {
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(Str);
out.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void requestStoragePermission() {
while(GET_FILE_PERMISSION) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE))
{
new AlertDialog.Builder(this).setTitle("Permission needed").setMessage("This permission is needed because of this and that").setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create().show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
//GET_FILE_PERMISSION = false;
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == STORAGE_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission GRANTED", Toast.LENGTH_SHORT).show();
GET_FILE_PERMISSION = false;
} else if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
Toast.makeText(this, "Permission DENIED", Toast.LENGTH_SHORT).show();
}
}
}
}