I have enabled the user to select a specific file from his device the extension of the file is .txt , and I'm using MaterialFilePicker library for it , now how to convert this file to string base64 so I can send the file to the server.
if there's another library or another way to do it please recommend me to use it.
this the code I tried but it didn't work out , thanks.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSIONS_REQUEST_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openFilePicker();
} else {
showError();
}
}
}
}
// FILE PICKER
private void checkPermissionsAndOpenFilePicker() {
String permission = Manifest.permission.READ_EXTERNAL_STORAGE;
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
showError();
} else {
ActivityCompat.requestPermissions(this, new String[]{permission}, PERMISSIONS_REQUEST_CODE);
}
} else {
openFilePicker();
}
}
private void showError() {
Toast.makeText(this, "Allow external storage reading", Toast.LENGTH_SHORT).show();
}
private void openFilePicker() {
new MaterialFilePicker()
.withActivity(this)
.withRequestCode(FILE_PICKER_REQUEST_CODE)
.withHiddenFiles(true)
.withTitle("Sample title")
.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_PICKER_REQUEST_CODE && resultCode == RESULT_OK) {
String path = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH);
if (path != null) {
Log.d("Path: ", path);
file = new File(path);
fileStr = String.valueOf(file);
Toast.makeText(this, "Picked file: " + file, Toast.LENGTH_LONG).show();
}
}
}
//convert the file path to base64
public static String encodeImage(String path) {
File imagefile = new File(path);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 80, baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
if (fis != null) {
try {
fis.close();
if (baos != null)
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//Base64.de
return encImage;
}
First read the file to a byte array, and then use
Base64.encodeToString(byte[], int)
to convert it to a Base64 string.
Try this:
File file = new File("myfile.txt");
//convert file to byte[]
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(file);
bos.close();
oos.close();
byte[] bytearray = bos.toByteArray();
//convert byte[] to file
ByteArrayInputStream bis = new ByteArrayInputStream(bytearray);
ObjectInputStream ois = new ObjectInputStream(bis);
File fileFromBytes = null;
fileFromBytes = (File) ois.readObject();
bis.close();
ois.close();
System.out.println(fileFromBytes);
Note: Don't forget to handle the exception(try/catch)
Related
I am trying to upload PDF file to my server. I am able to upload images decoding using bitmap. I am reusing the same code but I need to upload PDF from a user on my Android app.
private void chooseFile(int type2) {
//System.out.println(type2);
Intent intent = new Intent();
//intent.setType("application/pdf");
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),type2 );
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// System.out.println(data);
if ((requestCode == 1 || requestCode == 2 || requestCode == 3 || requestCode == 4 || requestCode == 5 || requestCode == 6 || requestCode == 7 || requestCode == 8) && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri filePath = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
// profile_image.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
if (requestCode == 1) {
String userString = getStringImage(bitmap , 1);
RequestQueue requestQueue = Volley.newRequestQueue(CashFlowActivity.this);
String url = C.url+"cashflow_upload.php";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//System.out.println(response);
// Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
p1 = "user_file/u_image/"+userID+"/extract.pdf";
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Error while uploading image", Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("userId", userID);
params.put("extractImage",userString);
return params;
}
};
requestQueue.add(stringRequest);
I am not getting a direct method to upload PDF through Android app associated with PHP, MySQL. I did some changes here and there I am able to get a PDF file on my server but the PDF itself is empty or contains the string of location of the file.
public String getStringImage(Bitmap bitmap, int type) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] imageByteArray = byteArrayOutputStream.toByteArray();
String encodeImage = Base64.encodeToString(imageByteArray, Base64.DEFAULT);
imageByteArray = Base64.decode(encodeImage, Base64.DEFAULT);
Bitmap decodeImage = BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
if (type == 1) {
extractPhoto.setImageBitmap(decodeImage);
} else if (type == 2) {
bankPhoto.setImageBitmap(decodeImage);
} else if (type == 3) {
itrPhoto.setImageBitmap(decodeImage);
} else if (type == 4) {
bankPhoto1.setImageBitmap(decodeImage);
} else if (type == 5) {
itrPhoto1.setImageBitmap(decodeImage);
} else if (type == 6) {
bankPhoto2.setImageBitmap(decodeImage);
} else if (type == 7) {
itrPhoto2.setImageBitmap(decodeImage);
} else if (type == 8) {
bankPhoto3.setImageBitmap(decodeImage);
}
return encodeImage;
}
You can use this Function:
public String getStringPdf (Uri filepath){
InputStream inputStream = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
inputStream = getContentResolver().openInputStream(filepath);
byte[] buffer = new byte[1024];
byteArrayOutputStream = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
byte[] pdfByteArray = byteArrayOutputStream.toByteArray();
return Base64.encodeToString(pdfByteArray, Base64.DEFAULT);
}
Thanks to blackapps for guiding correct method.
i am trying to pick an audio file and save it , but i am getting ENOENT , yet i use the same code with image and it works fine !!!!! \n
i am using file provider to create/save files and it works more than probably .
how can the same code work with images yet not with audio : \n
here is some code examples \n
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0 && resultCode == RESULT_OK) {
Uri resultUri = data.getData();
saveFile(resultUri);
}
}
and to save the file i use :
File dirPath = new File(Environment.getExternalStorageDirectory(),"Moch/WAR/");
File file = new File(dirPath, "notification.mp3");
String sourceFilename = resultUri.getPath();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
if(!file.exists())
if (!file.createNewFile())
Toast.makeText(notificationsSettings.this,"Unable to make sound File",Toast.LENGTH_LONG).show();
if(file.exists()) {
bis = new BufferedInputStream(new FileInputStream(sourceFilename));
bos = new BufferedOutputStream(new FileOutputStream(file, false));
byte[] buf = new byte[1024];
bis.read(buf);
do {
bos.write(buf);
} while (bis.read(buf) != -1);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bis != null) bis.close();
if (bos != null) bos.close();
mProgressDialog.dismiss();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and this is the doomed error line : \n
/document/audio:266: open failed: ENOENT (No such file or directory)
I'm trying to copy an image file with this code:
InputStream fileInputStream = null;
OutputStream fileOutputStream = null;
String inPath = "/storage/emulated/0/Pictures/MyImage.jpg";
String outPath = "/storage/extSdCard/MyFolder/MyImage.jpg";
try {
verifyStoragePermissions(this);
fileInputStream = new FileInputStream(new File(inPath));
File outputFile = new File(outPath);
if (!outputFile.exists()) {
try {
outPutFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[1024];
int read;
while ((read = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, read);
}
fileInputStream.close();
fileInputStream = null;
fileOutputStream.flush();
fileOutputStream.close();
fileOutputStream = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
And this is the method for verifying storage permissions on sdk>=23
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* #param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
And result is this error which occurs before reaching the buffer line.
Unable to decode stream: java.io.FileNotFoundException: /storage/extSdCard/MyFolder/MyImage.jpg: open failed: ENOENT (No such file or directory)
I have MyFolder on sd card and gallery apps on my device copy images to this directory without any problem.
NOTE: permissions are granted in the manifest (in the correct place before application tag) and inside activity(for skd >=23) .
EDITS:
Implemented suggestion of creating file before fileOutputStream (didn't help).
Lowered the targetSdkVersion to overpass any possible problems related to permissions and still no success.
targetSdkVersion 22
Creating File in this way:
File outFile = new File("/storage/extSdCard", "MyFolder/MyImage.jpg");
also made no result.
I'm testing it on android version 22.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
You need to create the file first, FileOutputStream will throw that exception if the file does not exist FileNotFoundException
File outputFile = new File(outPath);
file.createNewFile();
fileOutputStream = new FileOutputStream(outputFile);
if you are using targetSdkVersion 23 (or higher) in your app gradle file, you need to explicitly request the permission (could be into the onCreate method of the Activity or a button listener method), like this...
private static final int CODE_WRITE_EXTERNAL = 10;
if (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Log.d(TAG, "onCreate: " + "Show explanation");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_WRITE_EXTERNAL );
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CODE_WRITE_EXTERNAL );
}
} else {
Log.d(TAG, "onCreate: " + "Permission already granted!");
//Call your method to save the file
}
Then you need to implement the next callback method
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case CODE_WRITE_EXTERNAL : {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "onRequestPermissionsResult: Good to go!");
//Call your mehotd here
} else {
Log.d(TAG, "onRequestPermissionsResult: Bad user");
}
}
}
}
This is the way I used SAF to get the job done.
private void newcopyFile(File fileInput, String outputParentPath,
String mimeType, String newFileName) {
DocumentFile documentFileGoal = DocumentFile.fromTreeUri(this, treeUri);
String[] parts = outputParentPath.split("\\/");
for (int i = 3; i < parts.length; i++) { //ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "MyFolder"}
if (documentFileGoal != null) {
documentFileGoal = documentFileGoal.findFile(parts[i]);
}
}
if (documentFileGoal == null) {
Toast.makeText(MainActivity.this, "Directory not found", Toast.LENGTH_SHORT).show();
return;
}
DocumentFile documentFileNewFile = documentFileGoal.createFile(mimeType, newFileName);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
outputStream = getContentResolver().openOutputStream(documentFileNewFile.getUri());
inputStream = new FileInputStream(fileInput);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (outputStream != null) {
byte[] buffer = new byte[1024];
int read;
if (inputStream != null) {
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
if (inputStream != null) {
inputStream.close();
}
inputStream = null;
outputStream.flush();
outputStream.close();
outputStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
i am trying to copy whole directory to usb storage :
File Sdfile = new File(Environment.getExternalStorageDirectory(), "myfolder");
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.setType("*/*");
intent.setType(DocumentsContract.Document.MIME_TYPE_DIR);//For API 19+
intent.putExtra(Intent.EXTRA_TITLE, Sdfile.getName());
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(intent, 47);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 47) {
if (resultCode != RESULT_OK) return;
File file = new File(Environment.getExternalStorageDirectory(), "myfolder");
copyFile(file, data.getData());
}
Below code is for copy the whole folder to usb storage.
private void copyFile(File src, Uri destUri) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(src));
bos = new BufferedOutputStream(getContentResolver().openOutputStream(destUri));
byte[] buf = new byte[5024];
bis.read(buf);
do {
bos.write(buf);
} while (bis.read(buf) != -1);
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bis != null) bis.close();
if (bos != null) bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
when i am trying to copy the whole folder then it gives error.
Even i direct copy the whole folder to usb storage .
How can i copy whole directory ?
I'm guessing your app does not have the correct permissions. For Android versions below KitKat, you need to declare the permission WRITE_EXTERNAL_STORAGE in your AndroidManifest.xml
<user-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Reference: http://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE
I opened the music player to select an audio file using this code
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent_upload = new Intent();
intent_upload.setType("audio/*");
intent_upload.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent_upload,1);
}
});
I called the uploadAudioToParse method inside OnActivityResult()
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 1){
if(resultCode == RESULT_OK){
//the selected audio.
Uri uri = data.getData();
File abc=new File(uri.toString());
ParseObject ob=new ParseObject("songs");
uploadAudioToParse(abc,ob,"song");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
And this is my uploadAudioToParse method.
private ParseObject uploadAudioToParse(File audioFile, ParseObject po, String columnName){
if(audioFile != null){
Log.d("EB", "audioFile is not NULL: " + audioFile.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(audioFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read;
byte[] buff = new byte[1024];
try {
assert in != null;
while ((read = in.read(buff)) > 0)
{
out.write(buff, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
byte[] audioBytes = out.toByteArray();
// Create the ParseFile
ParseFile file = new ParseFile(audioFile.getName() , audioBytes);
po.put(columnName, file);
// Upload the file into Parse Cloud
file.saveInBackground();
po.saveInBackground();
}
return po;
}
is the file conversion method correct?