I'm trying to share an image in an app I have made that downloads an Image and writes it to a file. But any time I try to share it, it says can't upload file or just does nothing. It's not coming up in the logcat so I'm kinda stuck for ideas on how to fix it.
The image that is downloaded is displayed in an image view like this
iView.setImageBitmap(im);
String path = ContentFromURL.Storage + "/temp.jpg";
File temp = new File(path);
uri = Uri.fromFile(temp);
iView.setImageURI(uri);
Asynch task to download file
HttpURLConnection connection;
try {
String url = params[0];
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Accept-Charset","UTF-8");
connection.connect();
InputStream input = connection.getInputStream();
image = BitmapFactory.decodeStream(input);
File temp = new File(Storage,"temp.jpg");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
FileOutputStream fo = new FileOutputStream(temp);
fo.write(bytes.toByteArray());
fo.close();
String path = temp.getAbsolutePath();
Log.d("Asynch", "image shuould exist");
SharePage.act.runOnUiThread(new Runnable()
{
public void run()
{
SharePage.setImage(image);
}
}
);
creating intent
twitterIntent = new Intent(Intent.ACTION_SEND);
twitterIntent.setClassName("com.twitter.android",packageName);
twitterIntent.setType("image/jpeg");
twitterIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(twitterIntent);
I know that I should use the built in android share thing but its not working either when I try to share the image
The problem was where I was trying to store the Image, I wanted to have it so that the user never saw the image and it was deleted when it wasn't needed anymore but the other apps didn't have access to the directory. So I have since moved it to the external storage directory.
Related
I tried following code to get the user's google profile pic, but this is giving only thumbnail size blur photo:
FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl();
This is giving me uri, which when converted to string shows following URL (URL is showing pic, but due to privacy modified few digits here):
https://lh3.googleusercontent.com/a-/AguE7mDKNdcXubEW0cMTTYzschAykXcWRQDYeMlHb8rf_g=s96-c
I am able to use this url to show picture in an ImageView using Picasso, but not sure how to download it & store in phone memory.
Picasso.get().load(FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl().toString()).fit().into(profileImage);
I tried following by converting getPhotoURL into bitmap:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(SplashActivity.this.getContentResolver(), userPhotoURLUri);
FileOutputStream fos = new FileOutputStream(pictureFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
But this is giving me exception at the very first line:
FileNotFoundException: No content provider: for google getphotouri
Following code worked for me.
As the google profile pic doesn't contains .jpg or .png in its url therefore all other methods are not working.
GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(YourActivity.this);
//Set the Image dimension here it will not reduce the image pixels
googleProfilePic = acct.getPhotoUrl().toString().replace("s96-c", "s492-c");
Glide.with(MainActivity.this).load(googleProfilePic).asBitmap().into(new BitmapImageViewTarget(imageView) {
#Override
protected void setResource(Bitmap resource) {
FileOutputStream outStream = null;
File dir = new File(myfolderPath);
String fileName = picName + ".jpg";
File outFile = new File(dir, fileName);
outStream = new FileOutputStream(outFile);
outStream.flush();
resource.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.close();
}
Try this:
Picasso.get().load(FirebaseAuth.getInstance().getCurrentUser().getPhotoUrl()).fit().into(profileImage);
BitmapDrawable draw = (BitmapDrawable) profileImage.getDrawable();
Bitmap bitmap = draw.getBitmap();
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/YourFolderName");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
try{
FileOutputStream outStream = new FileOutputStream(outFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
outStream.flush();
outStream.close();
}catch (Exception e) {
e.printStackTrace();
}
Permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You can use Android's Download Manager to have it handle the download:
// Create the Download Request
DownloadManager.Request downloadRequest = new DownloadManager.Request(myPhotoUri);
// Set the destination
// (You can include the "SubPath/FileName" as the second argument if you want the file in a sub directory)
downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, myFileName);
// Display a notification while the download is in progress and after it's completed
downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// Allow the media scanner to find the file
downloadRequest.allowScanningByMediaScanner();
// Enqueue the download
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long downloadId = downloadManager.enqueue(downloadRequest);
Additionally, if you want your app to perform an operation in response to the completed download, you would register a BroadcastReceiver filtering DownloadManager.ACTION_DOWNLOAD_COMPLETE Intents and check for the Download id returned by .enqueue().
Here's further information on DownloadManager and DownloadManager.Request you can use to customize your download options:
https://developer.android.com/reference/android/app/DownloadManager
https://developer.android.com/reference/android/app/DownloadManager.Request
I am developing an Android app. In my app, I am uploading multiple images to server using Retrofit network library. Before I uploading file I create a temporary file from bitmaps. Then delete them after uploaded.
photoFiles = new ArrayList<File>();
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
int index = 0;
for(Bitmap bitmap: previewBitmaps)
{
File file = null;
try{
String fileName = String.valueOf(System.currentTimeMillis())+".jpeg";
file = new File(Environment.getExternalStorageDirectory(), fileName); // create temporary file start from here
if(file.exists())
{
file.delete();
}
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
photoFiles.add(file);
requestBodyBuilder.addFormDataPart("files",file.getName(), RequestBody.create(MediaType.parse("image/png"),file));
}
catch (Exception e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
index++;
}
//Upload process goes here and delete files back after upload
Using above code, all working fine. But the problem is I have to create temporary files. I do not want to create temporary files. What I want to do is I create array list of Uri string when I pick up the file. Then on file upload, I will convert them to file back and do the upload process.
photoFiles = new ArrayList<File>();
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
int index = 0;
for(Bitmap bitmap: previewBitmaps)
{
File file = null;
try{
Uri uri = Uri.parse(photosUriStrings.get(index));
file = new File(getPathFromUri(uri));
Toast.makeText(getBaseContext(),getPathFromUri(uri),Toast.LENGTH_SHORT).show();
photoFiles.add(file);
requestBodyBuilder.addFormDataPart("files",file.getName(), RequestBody.create(MediaType.parse("image/png"),file));
}
catch (Exception e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
index++;
}
As you can see in the above, I am converting the URI string back to file and then upload it. But this time retrofit unable to upload the file. File is not null as well. So I am pretty sure the error is with converting uri string back to image file back because my old code above working fine. Why can I not do that? How can I successfully convert from URI to image file back please?
I found this
Convert file: Uri to File in Android
and
Create File from Uri type android
both not working.
I am not clear about your question but I think this may help you. This single line code will help you to convert URI to file and show in your view.
Picasso.with(getContext()).load("URI path").into(holder.imgID);
I'm downloading a PDF from my server.
The server send me a HttpResponse with the InputStream of file's body.
I'm able to write it into a file but, when I try to read it with a PDF reader, it tells me that the file might be corrupted.
I've also noticed that the size of the PDF downloaded directly from web service is twice the size of the PDF downloaded via my application.
The code I use to download and write the PDF file is this:
String fileName = //FILENAME + ".pdf";
fileName = fileName.replaceAll("/", "_");
String extPath = Environment.getExternalStorageDirectory().toString();
String folderName = //FOLDERNAME;
try {
File folder = new File(extPath, folderName);
folder.mkdir();
File pdfFile = new File(folder, fileName);
pdfFile.createNewFile();
URL url = new URL(downloadURL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(pdfFile);
byte[] buffer = new byte[MEGABYTE];
int bufferLength;
while((bufferLength = inputStream.read(buffer))>0 ){
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
Uri path = Uri.fromFile(pdfFile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
//otherStuff
Where I go wrong?
I've also noticed that inside the Headers of HttpResponse contains Content-type:text/html. It shoudld be something like text/pdf?
Your Downloading code seems correct. Based on that and on your comment:
I've also noticed that the size of the PDF downloaded directly from web service is twice the size of the PDF downloaded via my application."
I would suggest checking your URL. It appears that you might be downloading an html page instead of the pdf. To verify you are downloading correctly, change the download directory as follows:
//Default download directory
String extPath = Environment.DIRECTORY_DOWNLOADS;
And check the directory (via the file system, e.g. mount the phone to your computer or a file manager app) for the downloaded content to verify it is a pdf.
I'm newbie to Android, I'm trying to send some Images from Android to a RESTFul WCF.
By now I'm being able to select the Images from the Gallery and sending them to the Server.
the WCF is expecting the image as Stream
But I'm having problems with the Synced Images that get stored in the Tablet Like the Facebook or G+ photos. (I don't know if they are cached or something)
I'm using this function to get the path of the Image
public static String getRealPathFromURI(Context context, Uri contentUri) {
String path = null;
if (contentUri.getScheme().toString().compareTo("content")==0)
{
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
path = cursor.getString(column_index);
}
else
{
path = contentUri.getPath();
}
Log.i(TAG, path);
return path;
}
With that kind of images I get an internet path like:
https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-ash4/s2048x2048/432098_10151223392360790_398885469_n.jpg
Just for clarity and to remark. I get a "content" scheme.. so I get the path from the "if " something like:
content://com.sec.android.gallery3d.provider/picasa/item/5703464571893262194
To send it to the Server im using MultipartEntity, because I saw in others post here in SO to do so, like this:
((MultipartEntity) oInputEntity).addPart(
"fileContents",
new FileBody(new File(Utilities.getRealPathFromURI(context,
imageUri)),
"image/jpeg"));
With that kind of images I was getting a FileNotFoundEception I think it's because the image path is an Internet path, so the MultiPartEntity don't know how to retrieve it,
So I changed my method to download the image and now is working with this code
public static File getFileFromURI(Context context, Uri contentUri) {
String path = IntUtilities.getRealPathFromURI(context, contentUri);
Log.i(TAG, path);
final File file;
if (path.startsWith("http") || path.startsWith("/http") )
{
//if its an image form internet lets download it and save it in our directory and return that file
// Determine Uri of camera image to save.
final String fname = "BIR" + UUID.randomUUID() + ".jpg";
final File root = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "BIR");
root.mkdirs();
file = new File(root, fname);
try {
final URL url = new URL(path);
final HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.connect();
final FileOutputStream fileOutput = new FileOutputStream(file);
final InputStream inputStream = urlConnection.getInputStream();
#SuppressWarnings("unused")
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
}
// close the output stream when done
fileOutput.close();
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
file = new File(path);
}
return file;
}
((MultipartEntity) oInputEntity).addPart(
"fileContents",
new FileBody(Utilities.getFileFromURI(context,
imageUri),
"image/jpeg"));
But I'm not comfortable with this solution, seems like double effort, I turned off my Wifi and 3g in the tablet, also turned off and on the tablet iself and I still see those images, so I'm guessing they got copied locally or cached on the tablet when they were synced for the first time. I looked for them when attached to my computer (in Windows Explorer) to see if they were there, but I dont see them, maybe I'm doing something wrong or dont know the storage folder.
The main reason that I dont like this solution is that if you don't have Internet on the moment, obviously the image will not be downloaded, and the app I'm making is supposed to work offline, and well.. the Image is there, there shouldn't be a request to internet to guess a local image.
Being said this, is there a way to find the real/physical path of this Photos that were synced, that have an http or https scheme to send this images using the MultiPartEntity?
Or another proper way to send this Images to the Server?
I really appreciate your help
from the chooser dialog , you can always get a bitmap
chooser-->$Result->getData() = imageUri
from the imageUri, get a Bitmap by running the following code:
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
Once you get the bitmap..,
you can put it to a fileSink
you can use a Hashmap to cache it in Memory
mBitMap = BitmapFactory.decodeStream(
mCR.openInputStream(imageUri), null, options);
OutputStream os = new FileOutputStream(f);
mBitMap.compress(Bitmap.CompressFormat.JPG, minVal, os);
mload.memoryCache.putbig(file.toURI().toURL().toString(), mBitMap);
and you can http POST the Bitmap directly by loading its ByteArray to the Entity...
case POST:
HttpPost httpPost = new HttpPost(url);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
float tmp = (float) 1024 * 1024 / bmp.getByteCount();
int minVal = (Math.round(tmp * 100) < 101) ? Math.round(tmp * 100): 100;
if (bmp.compress(Bitmap.CompressFormat.JPEG, minVal, stream)){
httpPost.setEntity(new ByteArrayEntity(stream.toByteArray()));
}else{ //TODO need to format actual message
handler.sendMessage(Message.obtain(handler,
HttpConnection.DID_ERROR, new Exception("ERR bitmap NG")));
}
background on the POST method is here
lazyloader project is a good template to use.
So why use mimeMultipartEntity with a file when you can operate directly on the bytes in the bitMap? As soon as you have a Uri, get a Bitmap and use the bitmap/ Uri pair for the basis of your interface to memCache, interface to HTTP POST, interface to fileSink used to retrieve local file when you have CacheMiss. This will help minimize doing everything on the basis of a file.
Think about using a Map [hashON(Uri.toString() :: bitMap] to store the images that you process locally. Then when you want to POST an image , you can just retrieve it from the map and POST its bytes directly in a "ByteArrayEntity".
What i want to do: delete an image file from the private internal storage in my app. I save images in internal storage so they are deleted on app uninstall.
I have successfully created and saved:
String imageName = System.currentTimeMillis() + ".jpeg";
FileOutputStream fos = openFileOutput(imageName, Context.MODE_PRIVATE);
bitmap.compress(Bitmap.CompressFormat.JPEG, 35, fos);
an image that i receive through
bitmap = BitmapFactory.decodeStream(inputStream);
I am able to retrieve the image later for display:
FileInputStream fis = openFileInput(imageName);
ByteArrayOutputStream bufStream = new ByteArrayOutputStream();
DataOutputStream outWriter = new DataOutputStream(bufStream);
int ch;
while((ch = fis.read()) != -1)
outWriter.write(ch);
outWriter.close();
byte[] data = bufStream.toByteArray();
bufStream.close();
fis.close();
imageBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
I now want to delete this file permanently. I have tried creating a new file and deleting it, but the file is not found:
File file = new File(imageName);
file.delete();
I have read on the android developer website that i must open private internal files using the openFileInput(...) method which returns an InputStream allowing me to read the contents, which i don't really care about - i just want to delete it.
can anyone point me in the right direction for deleting a file which is stored in internal storage?
Erg, I found the answer myself. Simple answer too :(
All you have to do is call the deleteFile(imageName) method.
if(activity.deleteFile(imageName))
Log.i(TAG, "Image deleted.");
Done!