App Crashes on upload\_image.setImageURI(im);

Issue

Hello Guys I am new to Android Studio so the problem is that I have 10 screen for my app. On screen 7 I use startActivityForResult to call screen 8 which input some data and images from gallery and send back the response to screen 7. The screen 7 use recycle view which display that entries. I have put a click listener on specific row which opens up screen 10 which displays the data and image but screen 10 shows other data but on setting image uri it crashes. I am using parecelable which has all the fields including image uri. I don’t why it crashes on one screen but not the other

**Screen-7**
package com.hamza.i180502;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Screen_7 extends AppCompatActivity implements MyAdapter.CallbackInterface{
    List<Ad> ls;
    Button add_data;
    ImageView back;
    RecyclerView rv;
    MyAdapter adapter;
    TextView dummy;
    static int MY_REQUEST1001;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen7);
        add_datafindViewById(R.id.add_data);
        backfindViewById(R.id.back);
        rvfindViewById(R.id.rv);
        dummyfindViewById(R.id.dummy);
        lsnew ArrayList<>();
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
        add_data.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent myIntent  new Intent(Screen_7.this,Screen_8.class);
                startActivityForResult(myIntent,1);
                //startActivity(myIntent);
            }
        });
        adapternew MyAdapter(Screen_7.this,ls);
        rv.setLayoutManager(new GridLayoutManager(Screen_7.this, 3));
        rv.setAdapter(adapter);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {

            case (1): {
                if (resultCode  RESULT_OK) {
                    Ad dene  data.getParcelableExtra("MyClass");
                    ls.add(new Ad(dene.getImage(), dene.getName(), dene.getPrice(), dene.getLocation(), dene.getDesc(), dene.getTags()));
                    adapter.notifyDataSetChanged();
                }
                if (resultCode  RESULT_CANCELED) {
                    Toast.makeText(Screen_7.this, "Nothing Entered", Toast.LENGTH_LONG);
                }
            }
            break;

            case (1001): {
                if (resultCode  RESULT_OK) {
                    Ad dene  data.getParcelableExtra("screen9");
                    String positiondata.getStringExtra("Position9");
                    ls.remove(Integer.parseInt(position));
                    ls.add(new Ad(dene.getImage(), dene.getName(), dene.getPrice(), dene.getLocation(), dene.getDesc(), dene.getTags()));
                    adapter.notifyDataSetChanged();
                }
                if (resultCode  RESULT_CANCELED) {
                    Toast.makeText(Screen_7.this, "Nothing Entered", Toast.LENGTH_LONG);
                }
            }
            break;


        }
    }

    @Override
    public void onHandleSelection(int position, Ad text) {
        Intent secondActivity  new Intent(Screen_7.this, Screen_9.class);
        secondActivity.putExtra("viewClass1",text);
        secondActivity.putExtra("Position", String.valueOf(position));
        secondActivity.putExtra("image",String.valueOf(text.getImage()));
        startActivityForResult(secondActivity, MY_REQUEST);

    }
}


**Screen10**
package com.hamza.i180502;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class Screen_10 extends AppCompatActivity {
    TextView name,price,tags,description,location;
    ImageView upload_image;
    ImageView back;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen10);
        Ad ad  (Ad)getIntent().getParcelableExtra("viewClass");
        upload_imagefindViewById(R.id.image_10);
        namefindViewById(R.id.name);
        locationfindViewById(R.id.location);
        descriptionfindViewById(R.id.description);
        tagsfindViewById(R.id.tags);
        pricefindViewById(R.id.price);
        name.setText(ad.getName());
        description.setText(ad.getDesc());
        price.setText(ad.getPrice());
        tags.setText(ad.getTags());
        location.setText(ad.getLocation());
        Uri im (Uri)ad.getImage();
        Log.d("Var", String.valueOf(im));
        upload_image.setImageURI(im);
        backfindViewById(R.id.back);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }
}


**MyAdapter**
package com.hamza.i180502;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;


import java.util.List;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    Context c;
    List<Ad> values;

    private CallbackInterface mCallback;


    public interface CallbackInterface{
        void onHandleSelection(int position, Ad text);
    }

    public MyAdapter(Context c, List<Ad> values) {
        this.c  c;
        this.values  values;
        // .. Attach the interface
        try{

            mCallback  (CallbackInterface) c;
        }catch(ClassCastException ex){
            //.. should log the error or throw and exception
            Log.e("MyAdapter","Must implement the CallbackInterface in the Activity", ex);
        }
    }
    @NonNull
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View row LayoutInflater.from(c).inflate(R.layout.ad, parent,false);
        return new MyViewHolder(row);
    }
    @Override
    public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, @SuppressLint("RecyclerView") int position) {
        holder.name.setText(values.get(position).getName());
        holder.price.setText(values.get(position).getPrice());
        holder.location.setText(values.get(position).getLocation());
        holder.imageView.setImageURI(values.get(position).getImage());
        values.get(position).setId(position);
        holder.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent myIntentnew Intent(c,Screen_10.class);
                Ad advalues.get(holder.getAdapterPosition());
                myIntent.putExtra("viewClass",(Ad)ad);

                c.startActivity(myIntent);
            }
        });
        holder.imageView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                if(mCallback ! null){
                    mCallback.onHandleSelection(position, values.get(position));
                }
                return false;
            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode  1) {
            if (resultCode  1) {
                Ad dene data.getParcelableExtra("screen9");
                Log.d("Description",dene.getDesc());
                values.remove(dene.getId());
            }
            if (resultCode  0) {
                Toast.makeText(((Activity) c),"Nothing Entered",Toast.LENGTH_LONG);
            }
        }

    }


    @Override
    public int getItemCount() {
        return values.size();
    }
    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView name,price,location;
        ImageView imageView;
        public MyViewHolder(@NonNull View row) {
            super(row);
            imageViewrow.findViewById(R.id.image);
            namerow.findViewById(R.id.name);
            locationrow.findViewById(R.id.location);
            pricerow.findViewById(R.id.price);

        }
    }
}


**Ad(Object)**
package com.hamza.i180502;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;


public class Ad implements Parcelable{

    public int getId() {
        return id;
    }
    public void setId(int id){
        this.idid;
    }


    public static Creator<Ad> getCREATOR() {
        return CREATOR;
    }

    private int id;
    public Ad(Uri image, String name, String price, String location, String desc,String tags) {
        this.image  image;
        this.name  name;
        this.price  price;
        this.location  location;
        this.desc  desc;
        this.tags  tags;

    }
    public Ad(){

    }

    protected Ad(Parcel in) {
        image  in.readParcelable(Uri.class.getClassLoader());
        name  in.readString();
        price  in.readString();
        tags  in.readString();
        location  in.readString();
        desc  in.readString();
    }

    public static final Creator<Ad> CREATOR  new Creator<Ad>() {
        @Override
        public Ad createFromParcel(Parcel in) {
            return new Ad(in);
        }

        @Override
        public Ad[] newArray(int size) {
            return new Ad[size];
        }
    };

    public Uri getImage() {
        return image;
    }

    public String getName() {
        return name;
    }

    public String getPrice() {
        return price;
    }

    public String getLocation() {
        return location;
    }

    public String getDesc() {
        return desc;
    }

    private Uri image;
    private String name , price, tags,location,desc;


    public String getTags() {
        return tags;
    }

    public void setTags(String tags) {
        this.tags  tags;
    }



    public void setImage(Uri image) {
        this.image  image;
    }

    public void setName(String name) {
        this.name  name;
    }

    public void setPrice(String price) {
        this.price  price;
    }

    public void setLocation(String location) {
        this.location  location;
    }

    public void setDesc(String desc) {
        this.desc  desc;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeParcelable(image, i);
        parcel.writeString(name);
        parcel.writeString(price);
        parcel.writeString(tags);
        parcel.writeString(location);
        parcel.writeString(desc);
    }
}


**Manifest**
<?xml version"1.0" encoding"utf-8"?>
<manifest xmlns:android"http://schemas.android.com/apk/res/android"
    package"com.hamza.i180502">
    <uses-permission android:name"android.permission.MANAGE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup"true"
        android:icon"@mipmap/ic_launcher"
        android:label"@string/app_name"
        android:roundIcon"@mipmap/ic_launcher_round"
        android:supportsRtl"true"
        android:theme"@style/Theme.I180502">
        <activity
            android:name".Screen_10"
            android:exported"true" />
        <activity
            android:name".Screen_8"
            android:exported"true" />
        <activity
            android:name".Screen_9"
            android:exported"true" />
        <activity
            android:name".Screen_7"
            android:exported"true" />
        <activity
            android:name".Screen_6"
            android:exported"true" />
        <activity
            android:name".Screen_5"
            android:exported"true" />
        <activity
            android:name".Screen_4"
            android:exported"true" />
        <activity
            android:name".Screen_3"
            android:exported"true" />
        <activity
            android:name".Screen_2"
            android:exported"true" />
        <activity
            android:name".MainActivity"
            android:exported"true">
            <intent-filter>
                <action android:name"android.intent.action.MAIN" />

                <category android:name"android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Solution

This is a common problem people face when using URIs. URIs are temporary addresses to a image/file. They are similar to a link you click to open a website i.e.url. Once a session ends the URI to access a file/image expires and using it to access a file again crashes the app and gives a permission denial exception. This is the same in your case when you try to access the uri again it crashes.

Solution

once you get the uri in screen_8 store the image in the app’s internal storage using bitmap and then generate a new uri for the image stored in the inernal storage with Uri.fromFile(file);. Now use this new generated uri in any activity in the app. This should solve your problem. Good luck and Happy coding!

Answered By – umar Ali

Leave a Comment