I choose a text file from internal storage of Android e.g Sample.txt that convert the file to byte array using convertFileToByteArray( Uri documentUri)
Context applicationContext = MainActivity.getContextOfApplication();
private byte[] convertFileToByteArray(Context context, Uri documentUri) {
ByteArrayOutputStream buffer = null;
try {
InputStream inputStream = applicationContext.getContentResolver().openInputStream(documentUri);
int nRead;
byte[] data = new byte[16384];
buffer = new ByteArrayOutputStream();
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
} catch (Exception e) {
e.getLocalizedMessage();
}
return buffer.toByteArray();
}
In this line
InputStream inputStream = applicationContext.getContentResolver().openInputStream(documentUri);
no catch on exception error however, it catch Exception and return "No such directory" when I choose a file that cannot be identified their extension type, for example, Sample.lev1, Sample.abc, Sample.rty
This android app is for encryption and decryption, so my extension for encrypted file would be weird, such as, .lev1, .abc, .rty.
Encryption are fine because I choose a file that can be readable (.txt, .pdf) but decryption no because when trying to convert file(.lev1, .abc, .rty) to byte array, it throws "FileNotFoundException",
case R.id.btnGO://WILL CRYPT file
Uri doctUri = chosenFile;
keyType = MainActivity.keyType;
if (keyType == null || doctUri == null || radioGroup.getCheckedRadioButtonId() == -1) {
setMessage("Selection not Complete !");
} else {
mimeType = getMimeType(getContext(), doctUri);//check file whether it suitable or not.
// and to be used for save file
if (functionCode == ENCRYPT_FILE) {
try {
if (mimeType == null || isBCDMimeType(getFileName(doctUri))) {
if (isBCDMimeType(getFileName(doctUri))) {
//
} else {
}
} else {
byte[] b = convertFileToByteArray(doctUri);
launchRingDialogForEF(null, b, mimeType, keyType);
}
} catch (Exception e) {
e.getLocalizedMessage();
}
} else if (functionCode == DECRYPT_FILE) {
if (isVendorMimeType(getFileName(doctUri))) {
try {
byte[] b = convertFileToByteArray(doctUri);
size = b.length;
encryptDecryptHex ead = new encryptDecryptHex();
ead.decrypt(usbDeviceConnection, epOUT, epIN, b);
returnEData = ead.deData;
output = ead.decryptedData;
showMessageAfterTryToCrypt(returnEData, output, "Decrypt File", ead.m, ead.k);//m= mimeType k=keyType
goOk(usbDeviceConnection, epOUT, epIN);
} catch (Exception e) {
e.getLocalizedMessage();
}
} else {
}
}
}
You have get the permission at runtime before accessing any device storage if the os version is 6.0 and more. Check the following official documentation for more information
https://developer.android.com/training/permissions/requesting.html
the uri for Encrypted.ab(for example) was appended by "%00"
content://com.android.externalstorage.documents/document/primary%3AEncrypted.a%00b%00%00%00%00%00
Related
I am using following method to encrypt and decrypt the files. File is getting decrypted properly but I am unable to view Image or video in application. File is opening in gallery and I can view image and watch video clearly. The same I am unable to do in application using Imageview and Videoview
Below is my code :
public void run() {
boolean successful = true;
operationInProgress = true;
lastUpdateAtByteNumber = 0;
totalBytesRead = 0;
timeOperationStarted = System.currentTimeMillis();
if (operationType == OPERATION_TYPE_ENCRYPTION) {
completedMessageStringId = R.string.encryption_completed;
} else {
completedMessageStringId = R.string.decryption_completed;
}
InputStream inputStream = null;
OutputStream outputStream = null;
//get the input stream
try {
inputStream = new FileInputStream(inputFileName);
} catch (IOException ioe) {
successful = false;
ioe.printStackTrace();
}
//get the output stream
try {
outputStream = new FileOutputStream(outputFileName);
} catch (IOException ioe) {
successful = false;
ioe.printStackTrace();
}
if (inputStream != null && outputStream != null) {
//call AESCrypt
try {
fileSize = inputStream.available();
AESCrypt aesCrypt = new AESCrypt(password);
if (operationType == OPERATION_TYPE_ENCRYPTION) {
//Encrypt
aesCrypt.encrypt(version, inputStream, outputStream);
} else {
//Decrypt
aesCrypt.decrypt(fileSize, inputStream, outputStream);
}
} catch (GeneralSecurityException gse) {
successful = false;
gse.printStackTrace();
} catch (UnsupportedEncodingException uee) {
successful = false;
uee.printStackTrace();
} catch (IOException ioe) {
successful = false;
} catch (NullPointerException npe) {
successful = false;
}
}
//close the streams
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ioe) {
successful = false;
ioe.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException ioe) {
successful = false;
}
}
operationInProgress = false;
}
The reference code is https://www.aescrypt.com/download/
AndroidCrypt (AES Crypt compatible) for Android phones (source code)
File getting encrypted and decrypted properly. When I am trying to open the load the file using Imageview for image and videoview for video.
I am using below code to view image
File url1 = new File(path to my file);
Bitmap bmp = BitmapFactory.decodeFile(url1.getAbsolutePath());
objImageView.setImageBitmap(bmp);
It gives error **"libjpeg error 105 < Ss=0, Se=63, Ah=0, Al=0> from Incomplete image data"** . or **Failed to create image decoder with message 'unimplemented'**
For Video I am using below code
getPackageName is name of package
FileProvider I have declared in manifest and also in xml I have menioned fielpath
File url1 = new File(path to video file)
videoView.setVideoURI(FileProvider.getUriForFile(
this, getPackageName(),url1));
The same image and video is clearly visible in Gallery application.
Please help me.
Thanks
First of all I would like to say, that loading big images strategy is described here. I am aware of the obligation to resize the image to omit OutOfMemoryError. I would like to get bytes from the image to be able to send it through Internet.
public byte[] getAttachment(Context context, String fullFilePath) {
byte[] fileBytes = mFileUtil.readFileAsBytes(fullFilePath);
if (fileBytes == null) {
Logger.i("Unable to get bytes, trying through content resolver");
try {
fileBytes = mFileUtil.readFileFromContentResolver(context, fullFilePath);
} catch (OutOfMemoryError e) {
Uri imageUri = Uri.parse(fullFilePath);
if (checkIfFileIsImage(context, imageUri)) {
try {
InputStream stream = context.getContentResolver().openInputStream(imageUri);
if (stream == null) {
return null;
}
BitmapFactory.Options options = getOptions(stream, 2000, 2000);
stream.close();
stream = context.getContentResolver().openInputStream(imageUri);
if (stream == null) {
return null;
}
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
bitmap = rotateBitmap(context, imageUri, bitmap);
stream.close();
fileBytes = convertBitmapToArray(bitmap);
} catch (Exception e1) {
Logger.e("Unable to get bytes using fallback method, attachment " +
"will not be added");
} catch (OutOfMemoryError e2) {
Logger.e("Unable to get bytes using fallback method, because " +
"attachment is too big. Attachment will not be added");
}
}
System.gc();
}
}
return fileBytes;
}
FileUtil.class
public byte[] readFileAsBytes(String fileName) {
File originalFile = new File(fileName);
byte[] bytes = null;
try {
FileInputStream fileInputStreamReader = new FileInputStream(originalFile);
bytes = new byte[(int) originalFile.length()];
fileInputStreamReader.read(bytes);
} catch (IOException e) {
}
return bytes;
}
public byte[] readFileFromContentResolver(Context context, String fileName) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream is = null;
InputStream inputStream = null;
try {
inputStream = context.getContentResolver().openInputStream(Uri.parse(fileName));
is = new BufferedInputStream(inputStream);
byte[] data = new byte[is.available()];
is.read(data);
bos.write(data);
} catch (Exception e) {
} finally {
try {
if (is != null) {
is.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e1) {
}
}
return bos.toByteArray();
}
As you can see the aim of this code is to get byte[] from Bitmap unlike here. It works without problems in almost any case. However it is especially error prone on low-end devices with older Android systems (but also very rarely).
I don't like the idea of setting largeHeap inside AndroidManifest.xml as this is just masking the problem rather than cope with it. I also would not like to send even smaller images.
Could this piece of code be improved in any other way in order to get rid of OutOfMemoryError?
This is my method for reading a txt file in the raw folder:
public static String readTextFile(Activity activity,int rawId){
InputStream inputStream = activity.getResources().openRawResource(rawId);
System.out.println(inputStream);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i;
try {
i = inputStream.read();
while (i != -1)
{
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return byteArrayOutputStream.toString();
}
My code for equal :
String read_text= partsViewModel.getImageAddress().trim();// read_text is dc18b7f823e94dcb85a5f38845300324
if (read_text.equals("dc18b7f823e94dcb85a5f38845300324")) {
// equal
} else {
// not equal
}
Why is read_text not equal with dc18b7f823e94dcb85a5f38845300324 ?
if your file in raw folder is a different encoding, you may not get a true from equals().
you need to watch out byteArrayOutputStream.toString(), try
byteArrayOutputStream.toString("ISO-8859-1")
or
byteArrayOutputStream.toString("utf-8")
Also, your code is
partsViewModel.getImageAddress().trim()
you should also make sure if it is actually come from your readTextFile code.
I have implemented a database backup on dropbox, i would like to restore the DB from dropbox to the internal memory (data\data\\database),
i think is forbidden to write directly, is possible to read by stream the file on dropbox, and open the local file, clear the data inside , and flush the stream into the file?
If yes, anyone have a code for example?
I hope to be clear.
this is my code...
private boolean downloadDropboxFile(String dbPath, File localFile) throws IOException{
BufferedInputStream br = null;
BufferedOutputStream bw = null;
try {
if (!localFile.exists()) {
localFile.createNewFile(); //otherwise dropbox client will fail silently
}
byte[] buffer = new byte[4096];
DropboxInputStream fd = mApi.getFileStream (dbPath, null);
br = new BufferedInputStream(fd, buffer.length);
bw = new BufferedOutputStream(new FileOutputStream(localFile));
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//in finally block:
if (bw != null) {
bw.close();
}
if (br != null) {
br.close();
}
}
return true;
}
I am working on Dropbox. I see the documentation. This is my code to display list:
Entry entryCheck = mApi.metadata("/", 100, null, true, null);
Log.i("Item Name", entryCheck.fileName());
Log.i("Is Folder", String.valueOf(entryCheck.isDir));
I got all list from dropbox but my question is that
Here entryCheck.isDir always give me true value if it is file or directory so how i can know which is file or which one is directory?
How i downloaded that files.
I tried with this but it is not working:
private boolean downloadDropboxFile(String dbPath, File localFile,
DropboxAPI<?> api) throws IOException {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
try {
if (!localFile.exists()) {
localFile.createNewFile(); // otherwise dropbox client will fail
// silently
}
DropboxInputStream fin = mApi.getFileStream("dropbox", dbPath);
br = new BufferedInputStream(fin);
bw = new BufferedOutputStream(new FileOutputStream(localFile));
byte[] buffer = new byte[4096];
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// in finally block:
if (bw != null) {
bw.close();
}
if (br != null) {
br.close();
}
}
return true;
}
This will work
String inPath ="mnt/sdcard/"+filename;
File file=new File(inPath);
try {
mFos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
mErrorMsg = "Couldn't create a local file to store the image";
return false;
}
mApi.getFile("/"+filename, null, mFos, null);
This downloads the file and store it in the sdcard location inPath.
You have to do it in a new thread,not in main thread.Use AsyncTask.
http://www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html
this link explains why..