Resolving a path to an image file - java

I have an imageView i am trying to set an image to based on the file path of an image the user selects from their gallery. I put the path into a database and then i pass that path into another activity to set the imageView to display. The path comes back at all steps as
/external/images/media/23
I have used multiple toasts to check the path in the activity before i pass the path, after receiving the path by the called method so i know the path is being sent from activity to activity correctly. However when i use the following code to set the imageView nothing appears.
File imgFile;
//Bitmap moviePic;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_view);
Bundle income = getIntent().getExtras();
if(income != null)
{
mTitle = income.getString("title");
mYear = income.getString("year");
id = income.getLong("id");
mPath = income.getString("path");
}
Toast.makeText(this, "path: " + mPath, Toast.LENGTH_SHORT).show();
imV = (ImageView) findViewById(R.id.movieImage);
//moviePic = BitmapFactory.decodeFile(mPath);
imgFile = new File(mPath);
imV.setImageURI(Uri.fromFile(imgFile));
//imV.setImageResource(R.drawable.top);
mVT = (TextView) findViewById(R.id.movieViewTitle);
mVT.setText(mTitle);
mVY = (TextView) findViewById(R.id.movieViewYear);
mVY.setText(mYear);
delete = (Button) findViewById(R.id.deleteMovie);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent deleting = new Intent();
deleting.putExtra("Id", id);
setResult(RESULT_OK, deleting);
finish();
}
});
}
My guess is that im doing something wrong with the file path. Below is the code i use to resolve the path.
imgV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent addImage = new
Intent(android.content.Intent.ACTION_PICK);
addImage.setType("image/*");
startActivityForResult(addImage, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
super.onActivityResult(requestCode, resultCode, intent);
switch(requestCode)
{
case 1:
if(resultCode == RESULT_OK)
{
Uri image = intent.getData();
imgV.setImageURI(image);
moviePath = image.getPath();
Toast.makeText(this, moviePath, Toast.LENGTH_LONG).show();
}
}
}
}
To find the image files i used the android emulator, browsed to google images and downloaded one or two. When i look in the DDMS It placed them in the mnt\sdcar\download\ folder which is obviously different than the path they are resolving to using the image.getPath() method. Is there another way i should be resolving the path? Or is there something im missing with the way the emulator file path works.

Related

Android app in java crashes when trying to open a text file

I am trying to make a simple text editor for Android in Java. I run into a problem, when tring to open a file.
In this line of my code
File file = new File(getExternalFilesDir(filepath), filename);
I got a null pointer exception:
java.lang.NullPointerException: name == null
at java.io.File.<init>(File.java:150)
at java.io.File.<init>(File.java:124)
at my.app.texteditor.MainActivity$1.onClick(MainActivity.java:31)
and my app crashes, leaving the filepicker on my android device open.
For me (after some time of trying to debug my code) it seems that the
protected void onActivityResult(int requestCode, int resultCode, Intent data)
function is never called and thus the filepath and filename are never assigned, which generates the exception. Hovever I am not sure whether I detected the problem correctly and I dont know how to fix it.
Here is the (full) code of my main activity - the one where I am trying to open a file:
package my.app.texteditor;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
public class MainActivity extends AppCompatActivity {
String filepath, filename, folder;
private static final int PICKFILE_RESULT_CODE = 1;
private static int PICKER_RESULT = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button OpenButton = (Button) findViewById(R.id.OpenButton);
OpenButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent getContent = new Intent(Intent.ACTION_GET_CONTENT);
getContent.setType("text/*");
startActivityForResult(getContent, PICKFILE_RESULT_CODE);
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);
}
});
Button NewButton = (Button) findViewById(R.id.NewButton);
NewButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newIntent = new Intent(MainActivity.this, ShowFile.class);
startActivity(newIntent);
}
});
if (!StorageHandler.isExternalStorageAvailable() || StorageHandler.isExternalStorageReadOnly()) {
OpenButton.setEnabled(false);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
PICKER_RESULT = resultCode;
if (requestCode == PICKFILE_RESULT_CODE) {
if (resultCode == RESULT_OK) {
filepath = data.getData().getPath();
filename = data.getData().getLastPathSegment();
int lastPos = filepath.length() - filename.length();
folder = filepath.substring(0, lastPos);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
When I put this part of my code:
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);
in an if statement, so it will be executed only if the PICKER_RESULT variable is changed in onActivityResult function - like this:
if(PICKER_RESULT!=-1) {
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);
}
then my android device opens the filepicker, app DOES NOT crash, but I am not able to open a file - the PICKER_RESULT is still set to -1.
So my quesion is, why is the onActivityResult function never called?
You're trying to use the result of the activity in the onClick event handler. This won't work because the activity is started asynchronously. The event handler will keep running until the end, and only then the activity starts.
All of the code that depends on the activity result should be in
onActivityResult (or a method that's called from it)
startActivityForResult(getContent, PICKFILE_RESULT_CODE);
// MOVE THIS TO onActivityResult
File file = new File(getExternalFilesDir(filepath), filename);
Intent openIntent = new Intent(MainActivity.this, ShowFile.class);
openIntent.putExtra("my.app.file", file);
startActivity(openIntent);

How to check/set mime type in Android

Quick overview; I am building a Android application for file sharing, just began really but a little stuck on something. I want to enable the user to share multiple different file formats e.g. images, documents, videos etc. Now I got it all that working but only one at a time as show below. I have to change the string variable 'type' to certain mime type in order to open that file. I have the URI of the file that is selected if that helps.
I have Toasts in there just for testing purposes. Basically what I wish to achieve is that the application will check what file format is selected and open the apporiate third party app to preview that file when the preview button is clicked e.g. .JPG file will open pictures/gallery.
I believe code needs to be added to the 'previewBtn' in the onClick method but could be wrong.
Is there a way that the application can check what file is selected, and then set 'type' to be equal to that?
public class ShareFilesActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "ShareFilesActivity";
TextView mTextView = null;
String mimeType = null;
private static final int REQUEST_CODE = 6384; // onActivityResult request
// code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_files);
Button chooseFile;
chooseFile = (Button) findViewById(R.id.chooseFileBtn);
chooseFile.setOnClickListener(this);
Button previewBtn;
previewBtn = (Button) findViewById(R.id.previewBtn);
previewBtn.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.chooseFileBtn:
showChooser();
break;
case R.id.previewBtn:
String input = mTextView.getText().toString();
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = "image/*";
Toast.makeText(ShareFilesActivity.this, "Type3: " + type, Toast.LENGTH_LONG).show();
intent.setDataAndType(Uri.parse(input),type);
startActivity(intent);
Toast.makeText(ShareFilesActivity.this, input, Toast.LENGTH_LONG).show();
Toast.makeText(ShareFilesActivity.this, "Type1: " + mimeType, Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
private void showChooser() {
// Use the GET_CONTENT intent from the utility class
Intent target = FileUtils.createGetContentIntent();
// Create the chooser Intent
Intent intent = Intent.createChooser(
target, getString(R.string.chooser_title));
try {
startActivityForResult(intent, REQUEST_CODE);
} catch (ActivityNotFoundException e) {
// The reason for the existence of aFileChooser
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE:
// If the file selection was successful
if (resultCode == RESULT_OK) {
if (data != null) {
// Get the URI of the selected file
final Uri uri = data.getData();
mimeType = getContentResolver().getType(uri);
Toast.makeText(ShareFilesActivity.this, "Type2: " + mimeType, Toast.LENGTH_LONG).show();
Log.i(TAG, "Uri = " + uri.toString());
mTextView = (TextView) findViewById(R.id.fileNameTextView);
mTextView.setText(uri.toString());
mimeType = getContentResolver().getType(uri);
try {
// Get the file path from the URI
final String path = FileUtils.getPath(this, uri);
} catch (Exception e) {
Log.e("ShareFilesActivity", "File Select Error", e);
}
}
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
}
To check mime type you can use the below function and change the type of your own use
public boolean isVideoFile(String path) {
String mimeType = URLConnection.guessContentTypeFromName(path);
System.out.println(mimeType);
return mimeType != null && mimeType.indexOf("video") == 0;
}
Will return true if the type is video on my case
Hope this helps.

Upload Image with a Text (connected) to Firebase Storage

I upload an image to Firebase Storage with Android. I have an app which send image immediately after captured a photo.
But I would like to create an app which show a photo in ImageView before sending. I'd like to write some text under the photo and next, upload both of them.
Which tools should I use to do this?
I've Picasso to download from Storage. But I can't manage how to show an ImageView after capturing a photo, next write some text(like name or description) and send it to Firebase.
The second challenge is how to show particular text with this image?
IMAGE <-> TEXT.
In Firebase Storage I don't see some field to store image with a text.
MainActivity.java:
private ProgressDialog mProgress;
private Bitmap bitmap;
private Button mUploadBtn;
private Button mSendBtn;
private EditText mEditText;
private ImageView mImageView;
Uri picUri;
private StorageReference mStorage;
private static final int CAMERA_REQUEST_CODE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStorage = FirebaseStorage.getInstance().getReference();
mEditText = (EditText) findViewById(R.id.editText);
mSendBtn = (Button) findViewById(R.id.sendBtn);
mUploadBtn = (Button) findViewById(R.id.uploadBtn);
mImageView = (ImageView) findViewById(R.id.imageView);
mProgress = new ProgressDialog(this);
mUploadBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file=getOutputMediaFile(1);
picUri = Uri.fromFile(file); // create
i.putExtra(MediaStore.EXTRA_OUTPUT,picUri); // set the image file
startActivityForResult(i, CAMERA_REQUEST_CODE);
}
});
}
public void UploadWithText(){
String name = mEditText.getText().toString().trim();
}
/** Create a File for saving an image */
private File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyApplication");
/**Create the storage directory if it does not exist*/
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
/**Create a media file name*/
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == 1){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".png");
} else {
return null;
}
return mediaFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK ) {
mProgress.setMessage("Uploading Image...");
mProgress.show();
Uri uri = picUri;
StorageReference filepath = mStorage.child("Photos").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mProgress.dismiss();
Uri downloadUri = taskSnapshot.getDownloadUrl();
Picasso.with(MainActivity.this).load(downloadUri).fit().centerCrop().into(mImageView);
Toast.makeText(MainActivity.this, "Uploaded Successfully.", Toast.LENGTH_LONG).show();
}
});
}
}
Maybe there is a way that I can send the image to Firebase Storage but a Text(description) is sending to Database with a Name field(from Firebase Storage) and with this I can recognize which Text belongs to a particular image?
Could somebody help me to resolve this challenge?
Regards
I can only answer broadly, since there's a bit too much code to answer specifically without doing it for you. In general, there are few ways to do this:
Add text to the image file itself, upload the new image with changes made
Store text as an image attribute, upload the file and save attributes elsewhere
You can either store the data in the Realtime Database, or
You can store the data in Storage file metadata (assuming pairs)

Copy file from the directory to another , having the path's of file and directory

in my android application I want to copy file from one directory to another , I have the path of file filePath , and have the path of directory dirPath in what I must copy the file. I tried many ways , but nothing helped , some ways only make some empty(0 kb) file with strange name different from the name of my file. SO help please :)
here is some part of code, if it help's you, I have two buttons for Gallery and for Camera , and I must pick images from there
Button btnCam = (Button) dialog.findViewById(R.id.btncamera);
btnCam.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
dialog.cancel();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, 2500);
}
});
//end of camera button
Button btnGal = (Button) dialog.findViewById(R.id.btngalary);
btnGal.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
dialog.cancel();
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
});
and Activity Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data)
{
Uri selectedImage = data.getData();
url = new String(selectedImage.toString());
//here I must copy file with path `selectedImage` and replace it in
// directory with path `currentDir.hetPath()`
}
if (requestCode == 2500)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
//here I must do the same thing above
}
}
I found some way , in my Activity result I must call copyFile(String, String) function , here is the body
public static boolean copyFile(String from, String to) {
try {
File sd = Environment.getExternalStorageDirectory();
if (sd.canWrite()) {
int end = from.toString().lastIndexOf("/");
String str1 = from.toString().substring(0, end);
String str2 = from.toString().substring(end+1, from.length());
File source = new File(str1, str2);
File destination= new File(to, str2);
if (source.exists()) {
FileChannel src = new FileInputStream(source).getChannel();
FileChannel dst = new FileOutputStream(destination).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
return true;
} catch (Exception e) {
return false;
}
}
If you feel up to it, you can include Apache Commons I/O in your app. I don't know how big it is. See Standard concise way to copy a file in Java?
Or maybe you could download the source, and cherry-pick the source to FileUtils.copyFile()

How do I access the full size image taken with the camera from an Android Intent?

My button's onclick listener is as follows:
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
});
And the result is handled as follows:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
if (resultCode == Activity.RESULT_OK) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ImageView Preview = (ImageView) findViewById(R.id.PreviewImage1);
Preview.setImageBitmap(thumbnail);
Preview.setVisibility(View.VISIBLE);
}
}
}
I got the thumbnail working but how do I access the full image so that I can do some manipulations? I want to avoid saving the file if possible.
Here is a working example: http://achorniy.wordpress.com/2010/04/26/howto-launch-android-camera-using-intents/
Getting the full-sized image is not possible without saving to a file. Also it won't be a good idea, because having so big Bitmaps in memory will soon cause Out of memory exception.

Categories