I am starting to program in Android and I am testing some functionalities. now I'm trying to get an image from the gallery and save it to a byte array. The problem is that the code that I leave below, works for images saved in the internal memory but not for those that are in the SD, I already spent 3 hours searching to see what it could be but nothing worked for now. Thank you and have a good day!
In the manifest I have this line
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
and the fragment has this code:
public class PhotoFragment extends Fragment {
private ImageButton buttonphoto;
private Context mContext;
private byte[] bytes;
public void getPhoto(){
Intent photoPicker = new Intent(Intent.ACTION_GET_CONTENT);
photoPicker.setType("image/*");
startActivityForResult(photoPicker, 2);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 2){
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
getPhoto();
}
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_report, container, false);
buttonphoto = v.findViewById(R.id.fragmentreportesCameraButton);
buttonphoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(ActivityCompat.checkSelfPermission(getContext(),Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},2);
}else{
getPhoto();
}
}
});
return v;
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri images = data.getData();
if(requestCode == 2 && resultCode == Activity.RESULT_OK && data !=null){
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(),images);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Toast.makeText(mContext,"agarro?",Toast.LENGTH_SHORT).show();
bitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
bytes = stream.toByteArray();
}catch (Exception e){
e.printStackTrace();
}
}
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
mContext = context;
}
}
Android Level 10,11 changing your privacy policy. In this policy we cannot get data directly then add this tag in the manifest file inside the application tag:
android:requestLegacyExternalStorage="true"
Related
I want to pick multiple or single images from phone gallery. But my code returning null pointer also one major problem I have notice the createChooser runs twice.
After tries two pick image two time it sends me to the parent activity
OnCreate Method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_item_business);
ItemName = findViewById(R.id.item_name);
ItemDes = findViewById(R.id.item_des);
pickImage = findViewById(R.id.pickImage);
ChooseImageList = new ArrayList<>();
UrlsList = new ArrayList<>();
pickImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckPermission();
PickImageFromGallery();
}
});
}
Checking Permission
private void CheckPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(addItemBusiness.this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(addItemBusiness.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
} else {
PickImageFromGallery();
}
}
}
Move to gallery
private void PickImageFromGallery() {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Select images"), 100);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
Log.i("result", "inside activity result");
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == RESULT_OK) {
Log.i("result", "result is ok");
if (data.getClipData() != null) {
Log.i("result", "fine");
int count = data.getClipData().getItemCount();
for (int i = 0; i < count; i++) {
ImageUri = data.getClipData().getItemAt(i).getUri();
ChooseImageList.add(ImageUri);
SetAdapter();
}
} else if (data.getData() != null) {
Log.i("result", "clip data is null");
ImageUri = data.getData();
ChooseImageList.add(ImageUri);
SetAdapter();
}
}
}
Adapter
private void SetAdapter(){
ViewPagerAdapter adapter = new ViewPagerAdapter(this, ChooseImageList);
viewPager.setAdapter(adapter);
}
Adapter Class
private Context context;
ArrayList<Uri> ImageUrls;
LayoutInflater layoutInflater;
public ViewPagerAdapter(Context context, ArrayList<Uri> imageUrls) {
this.context = context;
ImageUrls = imageUrls;
layoutInflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return ImageUrls.size();
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
View view=layoutInflater.inflate(R.layout.show_imgaes_layout,container,false);
ImageView imageView=view.findViewById(R.id.UploadImage);
imageView.setImageURI(ImageUrls.get(position));
container.addView(view);
return view ;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view== object;
}
#Override
public void destroyItem(#NonNull View container, int position, #NonNull Object object) {
((RelativeLayout)object).removeView(container);
}
Hope that you can find the issue. Thank you
Code for picking an image from gallery
private void pickImageFromGallery() {
Intent intent=new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case PERMISSION_CODE:{
if(grantResults.length >0 && grantResults[0]== PackageManager.PERMISSION_GRANTED){
pickImageFromGallery();
}else {
Toast.makeText(this,"access denied", Toast.LENGTH_LONG).show();
}
}
}
}
To handle the picked image, i inflated the layout_ticket which contains image view.Assigned the image to it which i picked.
// handle the picked image
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if(resultCode==RESULT_OK && requestCode==IMAGE_PICK_CODE){
LayoutInflater mInflater = getLayoutInflater();
View myView = mInflater.inflate(R.layout.layout_ticket, null);
ImageView imageview = (ImageView) myView.findViewById(R.id.imageview);
imageview.setImageURI(data.getData());
}
}
}
I've one MainActivity, and few fragments on it.
I am trying to change a ImageView in a fragment using Gallery. But once image is selected, the MainActivity get refresh, which changes the MainActivity back to the default fragment.
Getting permission
textViewChangeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG,"Select Image executed");
requestPermissions(
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE);
}
});
On Request permission
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.d(TAG,"Select Image Permission executed");
if(requestCode == REQUEST_CODE){
progressDialogUploadDp.setMessage("Uploading...");
progressDialogUploadDp.show();
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
intent.putExtra("imageUpdate","true");
startActivityForResult(intent,REQUEST_CODE);
}else{
Toast.makeText(getActivity(), "No Permission Granted", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
On Activity Result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null){
try {
Uri uri = data.getData();
StorageReference filepath =
storageReference.child("Photos").child("DPs").child(ID).child("profilepicture.jpg");
InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageviewpropic.setImageBitmap(bitmap);
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialogUploadDp.hide();
progressDialogUploadDp.dismiss();
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Looking forward for a solution!
Updated ---
MainActivity
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState==null) {
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("questioners")) {
adapter = new SectionStatePagerAdapter(getSupportFragmentManager());
adapter.addFragment(new HomeFragment(), "HomeFragment");
viewPager.setAdapter(adapter);
}}
}
Back form gallery , activity will run onActivityResult then it will run onResume .
so you can set a FLAG at onActivityResult and make an IF in onResume to set your fragment.
From what you've said it looks like your activity is calling onCreate method and setting default fragment again. What you can do is to in onCreate() create new fragment only if there is no saved state.
if(savedInstanceState==null) setFragment(fragment);
I have a fragment and I filled a RecyclerView in it, a post contains a camera and I need to take the information it brings when I take the photo. I do not know how to do it.
Please help.
This is mi code:
PostAdapter.java
public HeaderViewHolder (View itemView) {
super (itemView);
this.mCamera = (ImageView) itemView.findViewById(R.id.ivCamera);
mCameraPhoto = new CameraPhoto(itemView.getContext());
this.mCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
((Activity) v.getContext()).startActivityForResult(mCameraPhoto.takePhotoIntent(), CAMERA_REQUEST_ASIST);
}catch (Exception e){
Log.e("Error camera permission", e.getMessage());
}
}
});
}
MainActivity.java
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
String photoPath = mCameraPhoto.getPhotoPath();
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
fragment.onActivityResult(requestCode, resultCode, data);
Log.d("Result in fragment",":D --> "+photoPath);
}
}
MyFragment.java
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("Result in fragment",":D");
}
Pass fragment into PostAdapter's constructor.
class PostAdapter {
private Fragment fragment;
public PostAdapter(Fragment fragment) {
this.fragment = fragment;
}
}
then inside onclick
this.mCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
fragment.startActivityForResult(mCameraPhoto.takePhotoIntent(), CAMERA_REQUEST_ASIST);
}catch (Exception e){
Log.e("Error camera permission", e.getMessage());
}
}
});
Use one of getFragmentById() or getFragmentByTag() methods to get the reference to your fragment
You can get the information of the photo you took as the following.
In your fragment
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK){
if(requestCode == CAMERA_REQUEST_ASIST ){
String photoPath = mCameraPhoto.getPhotoPath();
try {
// Update data in your Custom RecyclerView Adapter
// and call notifyDatasetChanged
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}//end if resultCode
}
And more information https://github.com/kosalgeek/PhotoUtil/blob/master/README.md
I'm working on an android app that produces effects in images. I want the users of my app to have two options.
1) They can choose pictures from Gallery
2) They can capture a new photo from camera
Here is how I'm accomplishing the aforementioned two tasks:
Button takePhotoFromCameraButton;
Button chooseFromGalleryButton;
String imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + System.currentTimeMillis() + "_image.jpg";
File imageFile = new File(imagePath);
imageUri = Uri.fromFile(imageFile);
In both buttons, I'm passing the same onClickListner.
#Override
public void onClick(View clickedView) {
int clickedViewId = clickedView.getId();
switch(clickedViewId) {
case R.id.takeFromCamera:
Intent imageCaptureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
imageCaptureIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(imageCaptureIntent,0);
break;
case R.id.chooseFromGallery:
Intent choosePictureIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(choosePictureIntent, 1);
break;
default:
// As we have only two buttons, and nothing else can be clicked except the buttons. So no need to put
// code in the "DEFAULT CASE"
}
}
And I'm capturing the result from both, the following way:
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch(requestCode) {
case 0:
Intent cameraIntent = new Intent(MainOptionsActivity.this,ApplyEffectsActivity.class);
cameraIntent.putExtra("imageFileUri", imageUri);
startActivity(cameraIntent);
break;
case 1:
Uri imageUriForGallery = intent.getData();
Intent galleryIntent = new Intent(MainOptionsActivity.this,ApplyEffectsActivity.class);
galleryIntent.putExtra("imageFileUri", imageUriForGallery);
startActivity(galleryIntent);
break;
}
}
}
The button for gallery images works fine. But when I invoke camera by pressing the second button and capture the image, nothing happens. It stays there till I cancel the camera and come back to my app. I don't receive any image back!
Where I'm wrong? Don't mind this silly question, I'm just a beginner in android! :(
When I implemented mine, I made it work this way through a fragment:
public class ConcertFragment extends Fragment implements SurfaceHolder.Callback {
ImageView toto;
ToggleButton btnFlashlight;
RayMenu menu;
View rootView;
private Camera cam;
boolean hasCamera;
Parameters params;
private int REQUEST_IMAGE_CAPTURE;
Bitmap photo;
Uri imageUri;
public ConcertFragment() {
}
public void startCameraIntent() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE);
}
#Override
public void onStart() {
super.onStart();
SurfaceView preview = (SurfaceView)getView().findViewById(R.id.background);
SurfaceHolder mHolder = preview.getHolder();
mHolder.addCallback(this);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.concert, menu);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getCamera();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_concert, container, false);
toto = (ImageView) rootView.findViewById(R.id.toto);
return rootView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode != 0)
{
if (requestCode == REQUEST_IMAGE_CAPTURE) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
toto.setImageBitmap(photo);
View content = rootView.findViewById(R.id.toto);
content.setDrawingCacheEnabled(true);
Bitmap bitmap = content.getDrawingCache();
File root = Environment.getExternalStorageDirectory();
File cachePath = new File(root.getAbsolutePath() + "/DCIM/Camera/image.jpg");
try {
cachePath.createNewFile();
FileOutputStream ostream = new FileOutputStream(cachePath);
bitmap.compress(CompressFormat.JPEG, 100, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/*");
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(cachePath));
startActivity(Intent.createChooser(share,"Share via"));
}
else {
cam.release();
}
}
}
// Get the camera
private void getCamera() {
if (cam != null) {
try {
cam = Camera.open();
params = cam.getParameters();
cam.startPreview();
hasCamera = true;
} catch (RuntimeException e) {
Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
cam.release();
}
}
}
Hope this helps :) Just ask if you need more information.
How to do it with an activity, instead of fragment
public class MyCameraActivity extends Activity {
private static final int CAMERA_REQUEST = 1888;
private ImageView imageView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.imageView = (ImageView)this.findViewById(R.id.imageView1);
Button photoButton = (Button) this.findViewById(R.id.button1);
photoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
}
}