I am making an app that copies a file from memory (works) then reads it and displays information from the file. The file is in csv format and when I try to show textfrom the files all the the non english characters are shown like �. So itried opening it with Notepad ++ and i saw that when I try the UTF-8 encoding Notepad Shows the Characters that should be there suggesting it should be readable by the android app.
this is the code I used to copy the file:
//called in the main activity
Intent myIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
myIntent.setType("text/*");
myIntent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(myIntent, 100);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
if(resultCode == Activity.RESULT_OK){
Uri result= data.getData();
Log.e("fag", result.getPath() + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
copyFile(result);
}
if (resultCode == Activity.RESULT_CANCELED) {
Log.e("", "canceled");
}
}
Intent a = new Intent(getApplicationContext(), MainActivity.class);
startActivity(a);
}
private void copyFile(Uri uri) {
FileOutputStream out = null;
try {
InputStream in = getContentResolver().openInputStream(uri);
out = openFileOutput(NAME , MODE_PRIVATE);
byte[] buffer = new byte[1024];
while ( in.read(buffer) != -1) {
out.write(buffer);
}
in.close();
in = null;
out.close();
out = null;
} catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
fnfe1.printStackTrace();
}
catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
Then I display the file using a list view and read threw a buffer with this code:
BufferedReader br = null;
try {
File a = new File(getFilesDir().getPath() + "/CSV_RAW");
if(a.isFile())Log.e("TEST", "file exists");
br = new BufferedReader(new FileReader(a.getPath()));
int count = 0;
String ln;
while((ln =br.readLine()) != null)
{
if (ln.indexOf(',') != -1)
count++;
}
br = new BufferedReader(new FileReader(a.getPath()));
ln= br.readLine() ;
arr = new String[count];
count = 0;
while((ln = br.readLine()) != null)
{
if (ln.indexOf(',') != -1){
arr[count] = getName(ln);
count ++;
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
I would like to know how to fix it or if there a deeper problem.
A solution is to write and read utf8 is to use BufferedReader/BufferedWriter with an InputStreamReader/OutputStreamWriter like below
//reading utf8
BufferedReader br = new BufferedReader(new InputStreamReader(in /*your FileInoutStream*/ , "utf8"),1024 /* buffer size */);
//writing utf8
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out /*your FileOutputStream */, "utf8"),1024 /* buffer size */);
Related
I convert my image to BITMAP and then i convert it to String (from byte[] array).
I then send it as POST REQUEST to my .php page of the server and i expect it to upload it in my database as LONGBLOB type.
JAVA CODE
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == getActivity().RESULT_CANCELED){
return;
} //IF USER CANCELED, EXIT
if(requestCode == CAMERA_CODE){
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
this.profile_image.setImageBitmap(bitmap);
uploadImageToDB(bitmap);
}else if(requestCode == GALLERY_CODE){
if(data != null){
Uri contentUri = data.getData();
try{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), contentUri);
this.profile_image.setImageBitmap(bitmap);
uploadImageToDB(bitmap);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
private byte[] convertBitmapToLongblob(Bitmap bitmap){
if(bitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
return stream.toByteArray();
}
return null;
}
private String convertLongblobToString(byte[] longblob){
if(longblob != null){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
String encoded = android.util.Base64.encodeToString(longblob, Base64.DEFAULT);
return encoded;
}
return null;
}
private void uploadImageToDB(Bitmap imageBitmap){
final String uploadImageUrl = "http://192.168.1.8/myServer/uploadImage.php";
final String binaryImage = convertLongblobToString(convertBitmapToLongblob(imageBitmap));
final int userId = this.sp.getInt("id", -1); //sp -> SharedPreferences with user's info
if(userId != -1 && binaryImage != null){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(uploadImageUrl);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection)) {
throw new IOException("Not on HTTP Connection");
}
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setConnectTimeout(15000);
httpConn.setReadTimeout(10000);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("user_id", userId + "")
.appendQueryParameter("binary_image", binaryImage)
;
String queryPar = builder.build().getEncodedQuery();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(httpConn.getOutputStream(), StandardCharsets.UTF_8));
bw.write(queryPar);
bw.flush();
bw.close();
httpConn.connect();
int response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
InputStream in = httpConn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String data = "";
String temp;
while ((temp = br.readLine()) != null) {
data += temp + "\n";
}
br.close();
in.close();
JSONObject jsob = new JSONObject(data);
String res = jsob.getString("response");
switch (res) {
case "SUCCESS":
System.out.println("success");
break;
case "FAILED":
System.out.println("failed");
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
So, then i take my $_POST attribute of this string (byte[] array) converted image and i want it to be saved in my MYSQL database so i can retrieve it later. I have tried so many things but nothing works for me...
It keeps saving a [BOB 1B] which i guess is wrong, because it's size shouldn't be 1 byte.
PHP CODE
<?php
if($_SERVER['REQUEST_METHOD'] == "POST"){
require "./connection.php";
uploadImageToDB();
}
function uploadImageToDB(){
global $conn;
$userId = intval($_POST['user_id']);
$binImageStr = $_POST['binary_image'];
$binaryImage = unpack("C*",$binImageStr);
//AVOID SQL INJECTIONS BY MAKING A SECURE SQL COMMAND
$sql = sprintf("UPDATE extra_user_info SET profile_image = %0b WHERE user_id = %d;",
((binary)$binImageStr),
mysqli_real_escape_string($conn, $userId)
);
$result = mysqli_query($conn, $sql);
if($result){
echo json_encode(
[
"response"=>"SUCCESS"
]
); //CASE 1 (SUCCESS)
}else{
echo json_encode(
[
"response"=>"FAILED"
]
); //CASE 2 (FAILURE)
}
mysqli_close($conn);
}
?>
I am writing an App to save files (pictures) as a certain name given by a column from csv-file. The user have to choose the csv with the filebrowser first and then the file will be copyied to my Dir-Data directory.
Everything worsk fine but it seems like the Path i get form the File src Object doesn't work with the Operation.
I expect the error obviously here(2nd Code-Box)
And sry in advance if it is obvious/easy to avoid, it is my first Android-Project ever.
I already tryed to use different Copy Functions with different parameter types and also tryed other formats such as String given by uri.toString().
//CSV Opener
public void performFileSearch() {
// ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
// browser.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
// Filter to only show results that can be "opened"
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only .csv using the image MIME data type.
// For all it would be "*/*".
intent.setType("text/comma-separated-values");
startActivityForResult(intent, READ_REQUEST_CODE);
}
//create paths
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
if (resultData != null) {
Uri path = resultData.getData();
stringUri = path.getPath();
File src = new File(stringUri);
File destination = new File(getFilesDir().getPath());
try {
copyDirectoryOneLocationToAnotherLocation(src,destination);
}
catch(IOException e) {
e.printStackTrace();
System.out.print("error in upload");
}
Toast.makeText(MainActivity.this, "Path: "+stringUri , Toast.LENGTH_SHORT).show();
}
}
}
//copy-operation from StackOverflow
public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < sourceLocation.listFiles().length; i++) {
copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
I want the choosen file to be copied in my data/data/... directory to be used later in the App.
BUT: the path i get from the objets doesn`t work for me
Thx #Mike M. , the tip with using getContentResolver() brougth me the anwser after trying around.
Finally is used an other Copy funktion and reworked the onActivityResult();
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK)
{
if (resultData != null) {
try {
String destination = getFilesDir().getPath();
InputStream src = getContentResolver().openInputStream(resultData.getData()); // use the uri to create an inputStream
try {
convertInputStreamToFile(src, destination);
} catch (IOException e) {
e.printStackTrace();
System.out.print("error in upload");
}
} catch (FileNotFoundException ex) {
}
String destination = getFilesDir().getPath();
Toast.makeText(MainActivity.this, "Success!: CSV-File copyed to : " +destination , Toast.LENGTH_SHORT).show();
}
}
}
public static void convertInputStreamToFile(InputStream is, String destination) throws IOException
{
OutputStream outputStream = null;
try
{
File file = new File(destination + "/Student.csv");
outputStream = new FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
}
finally
{
if(outputStream != null)
{
outputStream.close();
}
}
}
I'm a newbie to android app development. I'm trying to read and display a text file chosen from a file chooser in a textview in my app. But with the following code my app keeps crashing. Initially when I put a toast after filePath = data.getData(); It was working and when I converted filePath (which has data type of Uri) to String and then put a toast just to make sure if Uri is being converted to String, it worked, I got the path of file in the toast but when I implemented the read_file() function my app crashed. I'm a newbie any help would be appreciated.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_SELECT_CODE && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
read_file(this,filePath);
}
}
public String read_file(Context context, Uri filePath) {
try {
String uriToString;
uriToString= filePath.toString();
Toast.makeText(this, uriToString, Toast.LENGTH_LONG).show();
FileInputStream fis = context.openFileInput(uriToString);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} catch (FileNotFoundException e) {
return "";
} catch (UnsupportedEncodingException e) {
return "";
} catch (IOException e) {
return "";
}
}
i am making android application ..in which i have encoded my image string to external file in external card..But when i read that file to show image....application crashed..
here is a code:
storedpic.setOnClickListener(new View.OnClickListener() {
ImageView storedimageView = (ImageView) findViewById(R.id.imageView3);
public void onClick(View v) {
File sdcard = Environment.getExternalStorageDirectory();
File readfile = new File(sdcard, "myfile.txt");
try {
BufferedReader br = new BufferedReader(new FileReader(readfile));
String test;
while (true) {
test = br.readLine();
// readLine() returns null if no more lines in the file
byte[] bytarray = Base64.decode(test, Base64.DEFAULT);
Bitmap bmimage = BitmapFactory
.decodeByteArray(bytarray, 0, bytarray.length);
storedimageView.setImageBitmap(bmimage);
if (test == null)
break;
}
}
catch (IOException e) {
Toast.makeText(getBaseContext(), "Can't read a file", Toast.LENGTH_LONG).show();
}
}
});
More than likely Base64#decode is throwing an NPE as the input String is null. Try replacing
while (true) {
test = br.readLine();
...
}
with
while ((test = br.readLine()) != null) {
...
}
Of course remove the break statement
following is my code,
From Activity class
Intent intent = new Intent(this, DownloadService.class);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(handler);
intent.putExtra("MESSENGER", messenger);
intent.setData(Uri.parse("http://www.abc.ezy.asia/E-MobApps/op.apk"));
intent.putExtra("urlpath", "http://www.abc.ezy.asia/E-MobApps/op.apk");
startService(intent);
I have overrided Service Class method onHandle Event
// DownloadService Class
#Override
protected void onHandleIntent(Intent intent) {
Uri data = intent.getData();
String urlPath = intent.getStringExtra("urlpath");
String fileName = data.getLastPathSegment();
File output = new File(Environment.getExternalStorageDirectory(),fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
fos = new FileOutputStream(output.getPath());
byte dataB[] = new byte[1024];
InputStreamReader reader = new InputStreamReader(stream);
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
fos.flush();
result = Activity.RESULT_OK;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Bundle extras = intent.getExtras();
if (extras != null) {
Messenger messenger = (Messenger) extras.get("MESSENGER");
Message msg = Message.obtain();
msg.arg1 = result;
msg.obj = output.getAbsolutePath();
try {
messenger.send(msg);
} catch (android.os.RemoteException e1) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
}
}
In above code I used File Streams & Input stream reader for downloading
when tried to download html file then complete file was downloaded to my sdcard.But when I tried for APK. The File downloaded of 2.2 mb instead of 2.4 mb Parsing problem is there. Kindly help me to resolve the issue.
try this piece of code :
URL url = new URL(fileUrl);
URLConnection connection = url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(output.getPath());
byte data[] = new byte[1024];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
input.close();
result = Activity.RESULT_OK;