iText / Cloud Print not working on Android - java

I'm trying to generate a simple PDF and have it passed over to Google Cloud Print, but nothing happens when I try printing the PDF to my google drive. (Login works)
How would I even authenticate that my PDF is whole and valid, for starters? I feel like I'm taking iText's word for it.
Also, I get some error telling me that
public class PDFViewer extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
this.getWindow().setSoftInputMode
(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
super.onCreate(savedInstanceState);
InputStream object = this.getResources().openRawResource(R.raw.itextkey);
LicenseKey.loadLicenseFile(object);
File root = Environment.getExternalStorageDirectory();
File f = new File(android.os.Environment.getExternalStorageDirectory()
.getAbsolutePath() + java.io.File.separator + "HelloWorld.pdf");
boolean externalStorageAvailable = false;
boolean externalStorageWriteable = false;
String state = Environment.getExternalStorageState();
// if we can read and write to storage
if (Environment.MEDIA_MOUNTED.equals(state)) {
externalStorageAvailable = true;
externalStorageWriteable = true;
}
// else if we can read but cannot write
else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
externalStorageAvailable = true;
externalStorageWriteable = false;
}
if (externalStorageWriteable) {
System.out.println("enough storage!");
// creation of a document-object
Document document = new Document();
try {
// we create a writer that listens to the document
// and directs a PDF-stream to a file
if (f.exists())
f.delete();
try {
f.createNewFile();
} catch (IOException e) {System.out.println(e);}
PdfWriter.getInstance(document, new FileOutputStream
(android.os.Environment.getExternalStorageDirectory()
.getAbsolutePath() + java.io.File.separator + "HelloWorld.pdf"));
// open + format the document
document.open();
document.add(new Paragraph("Hello World"));
} catch (DocumentException de) {
System.err.println(de.getMessage());
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
document.close();
}
Intent printIntent = new Intent(this, PrintDialogActivity.class);
Uri hello = Uri.fromFile(f);
printIntent.setDataAndType(hello, "application / pdf");
printIntent.putExtra("title", "stuff");
startActivity(printIntent);
I get this error which I have 0 idea what to do about:
04-29 03:41:18.502: E/chromium(749): external/chromium/net/disk_cache
/backend_impl.cc:1107: [0429/034118:ERROR:backend_impl.cc(1107)]
Critical error found -8
I'd like to know what I can try to play with to get this working. The PrintDialogActivity is stock from Google's website , by the way. I turned off Exchange in App settings, I've allowed external storage to be written to in the manifest, and internet has also been enabled.
Thanks

I had this same problem until I found the solution on the Android developer website: http://developer.android.com/guide/webapps/webview.html.
The targetSdkVersion in your app's AndroidManifest.xml is probably set to 17 or higher. In that case, you need to make a small change to the PrintDialogActivity that you got from the Google Developer website. You need to add the annotation, #JavascriptInterface to the public methods in the PrintDialogJavaScriptInterface class.
final class PrintDialogJavaScriptInterface
{
#JavascriptInterface
public String getType()
{
return cloudPrintIntent.getType();
}
#JavascriptInterface
public String getTitle()
{
return cloudPrintIntent.getExtras().getString("title");
}
#JavascriptInterface
public String getContent()
{
try
{
ContentResolver contentResolver = getContentResolver();
InputStream is = contentResolver.openInputStream(cloudPrintIntent.getData());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = is.read(buffer);
while (n >= 0)
{
baos.write(buffer, 0, n);
n = is.read(buffer);
}
is.close();
baos.flush();
return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return "";
}
#JavascriptInterface
public String getEncoding()
{
return CONTENT_TRANSFER_ENCODING;
}
#JavascriptInterface
public void onPostMessage(String message)
{
if (message.startsWith(CLOSE_POST_MESSAGE_NAME))
{
finish();
}
}
}

Related

Image not overwriting on same name

I'm developing image editor app.. so each time the user have to save the image.
So first i inserted
String savedImageURL = MediaStore.Images.Media.insertImage(
getContentResolver(),
bitmap,
"Bird",
"Image of bird"
);
this code, but it creating new file instead of overwriting.
So i use another method
public String saveImage(String folderName, String imageName) {
String selectedOutputPath = "";
if (isSDCARDMounted()) {
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderName);
// Create a storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("PhotoEditorSDK", "Failed to create directory");
}
}
// Create a media file name
selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
Log.d("PhotoEditorSDK", "selected camera path " + selectedOutputPath);
File file = new File(selectedOutputPath);
try {
FileOutputStream out = new FileOutputStream(file,true);
if (parentView != null) {
parentView.setDrawingCacheEnabled(true);
parentView.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 80, out);
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return selectedOutputPath;
}
But it also didn't work.
Does anyone know about overwrite a bitmap in the same name?
Pass false as 2nd argument, to set append to false, so that you will overwrite the existing file:
FileOutputStream out = new FileOutputStream(file,false);
Check out the constructor documentation:
here is your code:
public String saveImage(String folderName, String imageName) {
String selectedOutputPath = "";
if (isSDCARDMounted()) {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), folderName);
// Create a storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("PhotoEditorSDK", "Failed to create directory");
}
}
// Create a media file name
selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
Log.d("PhotoEditorSDK", "selected camera path " + selectedOutputPath);
File file = new File(selectedOutputPath);
if (file.exists())
{
try {
file.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
file.createNewFile();
FileOutputStream out = new FileOutputStream(file,false);
if (parentView != null) {
parentView.setDrawingCacheEnabled(true);
parentView.getDrawingCache().compress(Bitmap.CompressFormat.JPEG, 80, out);
}
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return selectedOutputPath;
}
I also had this situation, but it turns out that this is not a problem with saving, but with displaying in ImageViev. I used Glide, and it turns out to be stored in the cache when outputting. And I did not change the name and path of the file. That is, I rewrote them. But Glide did not know this. He thought they were the same file. To fix this problem, I added the following
Glide.with(context)
.load(file)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(view)
If you also have this situation and these solutions helped you, I'm glad to this.

Sharing from snapchat to my app

I am unable to figure out how to share a video from SnapChat to my app while WhatsApp can do it without problems so it is possible.
Since SnapChat works with a contentprovider I figured I should just query the uri using the android contentresolver method. Using the databaseUtils I dumped the cursor to logcat but all it gives me back is the displayname and the filesize. I see no way how to get the actual file.
Help me out guys. What am I missing?
A bit late but i managed to solve it. Here is the solution. I added comments in the code to explain what i am doing.
void handleSendVideo(Intent intent)
{
// get title
String title = intent.getExtras().getString(Intent.EXTRA_SUBJECT);
// get the uri for the video
mVideoUri = (Uri) intent.getExtras().get(Intent.EXTRA_STREAM);
// check if it originates from snapchat
if (mVideoUri.getAuthority().equals(UriHelper.SNAPCHAT_FILE_PROVIDER))
{
Intent mRequestFileIntent;
ParcelFileDescriptor mInputPFD;
mRequestFileIntent = new Intent(Intent.ACTION_PICK);
mRequestFileIntent.setType("video/*");
// Query the content resolver to get the name of the file. Beware that you will not find
// the actual file here. You must read it from the fileDescriptor.
Cursor fileDataCursor = getContentResolver().query(mVideoUri, null, null, null, null);
String fileName = "";
if (fileDataCursor != null)
{
fileDataCursor.moveToFirst();
fileName = fileDataCursor.getString(0);
fileDataCursor.close();
}
// something is wrong... return
if (fileName.isEmpty())
{
return;
}
try {
// open the file descriptor that belongs to the file given to us by snapchat.
mInputPFD = getContentResolver().openFileDescriptor(mVideoUri, "r");
// fetch the descriptor
FileDescriptor fd = mInputPFD.getFileDescriptor();
// create in input stream from descriptor
InputStream inputStream = new FileInputStream(fd);
// This is the file that will be created
File targetFile = new File(Environment.getExternalStorageDirectory(), fileName);
// Open a outputstream connected to the file
FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
// Create a buffer with a size equal to what is available from the inputstream.
// Note: we dont have to loop here because the file is available on the storage.
byte[] buffer = new byte[inputStream.available()];
// Read all data into the buffer
inputStream.read(buffer);
// Write the buffer to the outputstream
fileOutputStream.write(buffer);
// close all streams, our file is ready.
inputStream.close();
fileOutputStream.close();
mInputPFD.close();
// check if the new file exists.
if (targetFile.exists())
{
// add the file to the android MediaProvider
mVideoUri = addVideo(targetFile);
}
else
{
DialogMaker.showAlertMessage(this, "Could not read video", "unable to read video from SnapChat.", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
return;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
logger.i("videoUri: " + mVideoUri.toString());
logger.i("videoPath: " + mVideoUri.getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
public Uri addVideo(File videoFile) {
ContentValues values = new ContentValues(3);
values.put(MediaStore.Video.Media.TITLE, "My video title");
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, videoFile.getAbsolutePath());
return getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
}

File naming error in Android

Hello all I am having a problem when exporting a named file to the device internal storage for my apps Sqlite database name.
I am getting the error
java.io.FileNotFoundException: /storage/emulated/0/Download/:/09/12/2017-JDO.db: open failed: ENOENT (No such file or directory)
when trying to name the file /09/12/2017-JDO.
I am using File.pathSeparator() with the passed in file name but still am not having any luck. I think it has to do with the / in the file name which is the reason why I tried the File.pathSeparator() to begin with since I want that option for naming the file if the user wants to include the date in that format or in combination with the /.
Here are some code snippets of the methods I am using to try and accomplish this and to show what I am trying to do.
/*
This method saves and exports the current database to the device's internal Downloads folder
This is the default named database
*/
public void backUpDatabase() {
/* Open your local db as the input stream */
DBHelper anotherDbHelper = null;
try {
try {
anotherDbHelper = new DBHelper(ExistingTallyActivity.this);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String path = null;
if (anotherDbHelper != null) {
path = String.valueOf(getApplicationContext().getDatabasePath(anotherDbHelper.getDatabaseName()));
}
File dbFile = null;
if (path != null) {
dbFile = new File(path);
}
FileInputStream fis = null;
try {
if (dbFile != null) {
fis = new FileInputStream(dbFile);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String outFileName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/Pipe_Tally");
/* Open the empty db as the output stream */
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(outFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/* Transfer bytes from the input-file to the output-file */
byte[] buffer = new byte[1024];
int length;
try {
if (fis != null) {
while ((length = fis.read(buffer)) > 0) {
try {
if (outputStream != null) {
outputStream.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
/* Close the streams */
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (anotherDbHelper != null) {
anotherDbHelper.close();
}
}
/*
This method renames the database to what the user inputs they want. Note: The original db is
still present and stored in the Downloads folder as well.
*/
public void renameDbFile(String desiredDbName) {
/* Open your local db as the input stream */
DBHelper dbHelperToRename = null;
try {
try {
dbHelperToRename = new DBHelper(ExistingTallyActivity.this);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String pathRenamed = null;
if (dbHelperToRename != null) {
pathRenamed = String.valueOf(getApplicationContext().getDatabasePath(dbHelperToRename.getDatabaseName()));
}
File dbFileRenamed = null;
if (pathRenamed != null) {
dbFileRenamed = new File(pathRenamed);
}
FileInputStream fisRenamed = null;
try {
if (dbFileRenamed != null) {
fisRenamed = new FileInputStream(dbFileRenamed);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/* Here is where the db is renamed by the user by inserting the passed in string to the method */
String outFileNameRenamed =
(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath() + "/"+desiredDbName+".db");
// Open the empty db as the output stream
OutputStream outputStreamRenamed = null;
try {
outputStreamRenamed = new FileOutputStream(outFileNameRenamed);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/* Transfer bytes from the input-file to the output-file */
byte[] bufferRenamed = new byte[1024];
int length;
try {
if (fisRenamed != null) {
while ((length = fisRenamed.read(bufferRenamed)) > 0) {
try {
if (outputStreamRenamed != null) {
outputStreamRenamed.write(bufferRenamed, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
/* Close the streams */
try {
if (outputStreamRenamed != null) {
outputStreamRenamed.flush();
outputStreamRenamed.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fisRenamed != null) {
fisRenamed.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (dbHelperToRename != null) {
dbHelperToRename.close();
}
}
/*
This method exports the database into CSV format as well by naming it the passed in string value
for the desired name.
*/
#TargetApi(Build.VERSION_CODES.KITKAT)
public void saveDbAsCsv(String desiredCsvName) {
/* Getting a instance of the DbHelper class right here. */
DBHelper dbhelperCsv = null;
try {
dbhelperCsv = new DBHelper(ExistingTallyActivity.this);
} catch (ClassNotFoundException | NoSuchFieldException e) {
e.printStackTrace();
}
/* Original name of the file dir where the db will be stored in csv format. (Just like SQLite) */
String pathRenamedCsv = null;
if (dbhelperCsv != null) {
pathRenamedCsv = String.valueOf(getApplicationContext().getDatabasePath(dbhelperCsv.getDatabaseName()));
}
/* Creating a File type here with the passed in name from above from the string */
File dbFile = getDatabasePath(pathRenamedCsv);
/*
Appending the desired name to the Downloads Directory here, which is where the new file
will be written
*/
String renamedCsvName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/"+desiredCsvName);
File exportDir = new File(String.valueOf(renamedCsvName));
if (!exportDir.exists())
{
exportDir.mkdirs();
}
/*
Critical .csv extension here. Took me a while originally to figure out where to pass this
in at. Was at first passing it into the renamedCsvName up above and it was just returning
a folder with the .csv extension and not the file contained withn.
*/
File file = new File(exportDir, desiredCsvName+".csv");
try
{
/* Passing in the string value of the file to an instance of the CsvWriter class */
CsvWriter csvWriter = new CsvWriter(String.valueOf(file));
SQLiteDatabase db = null;
if (dbhelperCsv != null) {
db = dbhelperCsv.getReadableDatabase();
}
/* Getting a cursor from the database table Tally_File */
Cursor curCSV = null;
if (db != null) {
curCSV = db.rawQuery("SELECT * FROM Tally_File",null);
}
if (curCSV != null) {
csvWriter.writeRecord(curCSV.getColumnNames());
}
if (curCSV != null) {
while(curCSV.moveToNext())
{
/* Exporting all the columns here to write out to the csv file */
String arrStr[] ={curCSV.getString(0),curCSV.getString(1), curCSV.getString(2),
curCSV.getString(3), curCSV.getString(4), curCSV.getString(5),
curCSV.getString(6), curCSV.getString(7), curCSV.getString(8),
curCSV.getString(9), curCSV.getString(10), curCSV.getString(11),
curCSV.getString(12), curCSV.getString(13), curCSV.getString(14), curCSV.getString(15),
curCSV.getString(16)};
/*
Critical here as I was not at first calling the writeRecord that accepted the
String[] array and was calling the toString() method on it and only getting a large
array.
*/
csvWriter.writeRecord(arrStr);
}
}
csvWriter.close();
if (curCSV != null) {
curCSV.close();
}
}
catch(Exception sqlEx)
{
Toast.makeText(this, "Error naming file", Toast.LENGTH_LONG).show();
}
}
Here is where I am calling the methods and passing in the desiredName for naming the file/Db, which is switch case dependent on a menu selection, all within the same activity.
case R.id.menu_save_and_export:
Thread threadMenuSaveAndExport = new Thread();
/*
This method verifies user permissions then calls the backUpDatabase() method to
backup the original db file before the user renames it, if desired.
*/
verifyStoragePermissions(new Runnable() {
#Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
/* Calling this method here to backup the current database*/
backUpDatabase();
}
});
/* Loading the view of activity_database_name with this LayoutInflater*/
View view = LayoutInflater.from(ExistingTallyActivity.this)
.inflate(R.layout.activity_database_name,null);
/*This editText handles the input from the user for their chosen db name*/
mEtCustomDbName = (EditText) view.findViewById(R.id.etCustomDbName);
AlertDialog.Builder alert = new AlertDialog.Builder(ExistingTallyActivity.this);
/* Taken from the strings.xml file. Says Name Database Prior To Export */
alert.setMessage(getResources().getString(R.string.name_your_db));
alert.setView(view);
/* Using the global "Ok" string from strings.xml */
alert.setPositiveButton(getResources().getString(R.string.global_ok_text), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
/* Passing in the results of the editText to a string here*/
String userDefinedDbName = mEtCustomDbName.getText().toString().trim();
/*
Calling this method to rename the existing db to what the user input
Note: The original db remains in the same folder, as it was previously
backed up from the backUpDatabase() method above. Using the if statement
below to check for a empty string and if it is, the file is not renamed.
Both situations display custom toast message dependent on which executes.
Also implementing the File.separator method to help with File naming
issues on the Android "Unix-like" filesystem
*/
if (userDefinedDbName.length() > 0) {
/* Naming to a .db extension with this method. Works with SQLite */
renameDbFile(File.pathSeparator+userDefinedDbName);
/* Naming to a .csv extension with this method for working with Excel */
saveDbAsCsv(File.pathSeparator+userDefinedDbName);
Toast.makeText(ExistingTallyActivity.this,
/* Using the "Database Saved" string from strings.xml */
getResources().getString(R.string.database_saved),
Toast.LENGTH_LONG).show();
}else {
Toast.makeText(ExistingTallyActivity.this,
/* Using the "Database Not Saved" string from strings.xml */
getResources().getString(R.string.database_not_saved),
Toast.LENGTH_LONG).show();
}
}
});
/* Using the global "Cancel" string from strings.xml */
alert.setNegativeButton(getResources().getString(R.string.global_cancel_text), null);
alert.setCancelable(false);
AlertDialog showAlert = alert.create();
showAlert.show();
threadMenuSaveAndExport.start();
break;
Any advice or help would be greatly appreciated with this as I do want to be able to use the naming with / if desired as an option. Thanks

Image URL to ParseFile?

I have a Parse Android app for which I am implementing Facebook sign up. Currently I am stuck on grabbing images to set as profile pictures of new ParseUser's. I have successfully used the Facebook Graph API to retrieve the correct URL (I have checked this by plugging it into a browser, where I am shown the right profile picture), but I now need a way to turn that URL into a byte array (byte[]) so that I can save the ParseFile field of our ParseUser's profile picture. I have already looked at all these SO questions:
• java.net.URL read stream to byte[]
• Efficiently read file from URL into byte[] in Java
• Get image with given url and convert it to byte array
None of these have worked. I am currently trying to use the Apache IOutils, like in the solution from the second link. Here is my current code for the AsyncTask:
private class SetProfPicWithURL extends AsyncTask<URL, Integer, byte[]> {
#Override
protected byte[] doInBackground(URL... imageURL) {
Log.i("SetProfPicWithURL", "invocation, URL: " + imageURL[0]);
InputStream is = null;
byte[] bytes = null;
try {
is = imageURL[0].openStream();
bytes = IOUtils.toByteArray(is);
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (is != null) try {
is.close();
if(bytes == null){Log.e("LoginActivity", "bytes is null int SetProfPicWithURL");}
final ParseFile imageFile = new ParseFile("image.jpg", bytes);
imageFile.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("LoginActivity", "getCurrentUser.put");
ParseUser.getCurrentUser().put(ParseUtils.PARSE_PROFILE_IMAGE, imageFile);
ParseUser.getCurrentUser().saveInBackground();
} else {
e.printStackTrace();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
return bytes;
}
}
Now when this code executes, I get no error logs, and a ParseFile is created. However, no profile pictures load within the app, and when I click to examine the file in the dashboard, I get this error message:
The file “tfss-0280f98d-7180-4528-9d24-3ec47d3b25d4-image.jpg” could
not be opened because it is empty.
Honestly, I'm at a loss. I've spent significantly more time on this one photo issue than any other part of implementing the Facebook login. And the way our database is set up, it is really not ideal to create another field to save the URL and load with Picasso. Any help with this issue is truly appreciated!
Directly save your imagefile as profile picture like this :
final ParseFile imageFile = new ParseFile("image.jpg", bytes);
ParseUser.getCurrentUser().put(ParseUtils.PARSE_PROFILE_IMAGE, imageFile);
ParseUser.getCurrentUser().saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.i("LoginActivity", "Profile saved succesfully");
} else {
e.printStackTrace();
}
}
});
EDIT :
Use this to get image byte array from url.
try {
java.net.URL img_value = new java.net.URL(imageURL);
Bitmap mIcon = BitmapFactory
.decodeStream(img_value.openConnection()
.getInputStream());
if (mIcon != null)
imgByteArray = encodeToByteArray(mIcon);
} catch (Exception e) {
e.printStackTrace();
}
public byte[] encodeToByteArray(Bitmap image) {
Log.d(TAG, "encodeToByteArray");
Bitmap b= image;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imgByteArray = baos.toByteArray();
return imgByteArray ;
}

Download and save a file using Java

Let's say I have an URL, like something.domain/myfile.txt then I want to save this file, with that "Save File" dialog.
I tried my best to do it, but everytime I save the file using the dialog the file is not there.
An example or somewhere I can find information on this would help a lot!
URL website = null;
try {
website = new URL(<insert url here>);
} catch (MalformedURLException e) {
e.printStackTrace();
}
ReadableByteChannel rbc = null;
try {
rbc = Channels.newChannel(website.openStream());
} catch (IOException e2) {
e2.printStackTrace();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("minecraft.jar"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
} catch (IOException e) {
e.printStackTrace();
}
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(fileChooser) == JFileChooser.APPROVE_OPTION) {
File dir = fileChooser.getCurrentDirectory();
dir.mkdir();
//After this point is where I need help.
I trust that this is what you're looking for:
if (fileChooser.showSaveDialog(fileChooser) == JFileChooser.APPROVE_OPTION)
{
File file = fileChooser.getSelectedFile();
// whatever you want to do with the file
System.out.println("The file is "+file.getAbsolutePath());
// fos = new FileOutputStream(file) ...
}
Did you notice that in your code you are trying to save/download the file before giving the user the option to chose the destination?
I would split the code into three different operations:
A method in charge of transferring the bytes from the InputStream (the web) to the OutputStream (the file).
a method to show the user a dialog so he can chose where to store the file.
the method that completes the whole task: choose a file and transfer the bytes from the web to it.
1) Would be something like this (you don't need to use the NIO API to implement it):
public void transfer(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[2048];
int bytesRead;
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
}
2) would be something very similar to what Dukeling has already stated:
public File chooseFile() {
File result = null;
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(fileChooser) == JFileChooser.APPROVE_OPTION) {
result = fileChooser.getSelectedFile();
}
return result;
}
3) then, combining these two operations together is really simple:
public void saveFileFromWeb(URL url) {
File file = chooseFile(); // 1. Choose the destination file
if (file != null) {
// 2. Create parent folder structure
File folder = file.getParentFile();
if (!folder.exist()) {
folder.mkdirs();
}
InputStream in = null;
OutputStream out = null;
try {
// 3. Initialise streams
in = url.openStream();
out = new FileOuputStream(file);
// 4. Transfer data
transfer(in, out);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 5. close streams
if (in != null) {
try {
in.close();
} catch (IOException e) { /* ignore */ }
}
if (out != null) {
try {
out.close();
} catch (IOException e) { /* ignore */ }
}
}
}
NOTE: 1) and 2) could be private methods. Of course you could do this is just one single operation but splitting it would give you an overview of the different steps to perform.
NOTE 2: I simplified the exception handling part

Categories