Home > Software design >  App Crashes on upload_image.setImageURI(im);
App Crashes on upload_image.setImageURI(im);

Time:09-30

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_REQUEST=1001;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen7);
        add_data=findViewById(R.id.add_data);
        back=findViewById(R.id.back);
        rv=findViewById(R.id.rv);
        dummy=findViewById(R.id.dummy);
        ls=new 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);
            }
        });
        adapter=new 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 position=data.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_image=findViewById(R.id.image_10);
        name=findViewById(R.id.name);
        location=findViewById(R.id.location);
        description=findViewById(R.id.description);
        tags=findViewById(R.id.tags);
        price=findViewById(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);
        back=findViewById(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 myIntent=new Intent(c,Screen_10.class);
                Ad ad=values.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);
            imageView=row.findViewById(R.id.image);
            name=row.findViewById(R.id.name);
            location=row.findViewById(R.id.location);
            price=row.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.id=id;
    }


    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>

CodePudding user response:

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!

  • Related