简体   繁体   English

upload_image.setImageURI(im) 上的应用程序崩溃;

[英]App Crashes on upload_image.setImageURI(im);

The problem is that I have 10 screen for my app.问题是我的应用程序有 10 个屏幕。 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.在屏幕 7 上,我使用 startActivityForResult 调用屏幕 8,该屏幕从图库中输入一些数据和图像并将响应发送回屏幕 7。屏幕 7 使用显示该条目的回收视图。 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.我在特定行上放置了一个点击侦听器,它打开了显示数据和图像的屏幕 10,但屏幕 10 显示了其他数据,但在设置图像 uri 时它崩溃了。 I am using parecelable which has all the fields including image uri.我正在使用 parecelable,它具有包括图像 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>

This is a common problem people face when using URIs.这是人们在使用 URI 时面临的常见问题。 URIs are temporary addresses to a image/file. URI 是图像/文件的临时地址。 They are similar to a link you click to open a website ieurl.它们类似于您单击以打开网站 ieurl 的链接。 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.一旦会话结束,访问文件/图像的 URI 就会过期,并再次使用它来访问文件会使应用程序崩溃并给出权限拒绝异常。 This is the same in your case when you try to access the uri again it crashes.当您尝试再次访问 uri 时,这与您的情况相同,但它崩溃了。

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);.一旦你在 screen_8 中获得 uri,就使用位图将图像存储在应用程序的内部存储中,然后使用 Uri.fromFile(file); 为存储在内部存储中的图像生成一个新的 uri。 Now use this new generated uri in any activity in the app.现在在应用程序的任何活动中使用这个新生成的 uri。 This should solve your problem.这应该可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM