Reputation: 33
In the SecondActivity
, it has an ImageView
and a Button
public class SecondActivity extends AppCompatActivity
{
private ImageView galleryImage;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
galleryImage = findViewById(R.id.galleryImage);
Button openGalleryButton = findViewById(R.id.openGalleryButton);
openGalleryButton.setOnClickListener(view ->
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
activityResultLauncher.launch(intent);
});
/*...*/
}
}
for the activityResultLauncher
, it is an ActivityResultLauncher
that I used to open gallery and pick an Image.
ActivityResultLauncher<Intent> activityResultLauncher =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result ->
{
if (result.getResultCode() == Activity.RESULT_OK)
{
Intent data = result.getData();
if (data != null)
{
galleryImage.setImageURI(data.getData());
try
{
openFileOutput("uri", MODE_PRIVATE).write((data.getData() + "\n").getBytes());
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
});
As you can see, this not only shows the image that users pick, but also stores the uri string into a file for later use. But when I change to ThirdActivity
, there is always a SecurityException stop me.
/*SecondActivity.java*/
Button showPickedButton = findViewById(R.id.showPickedButton);
showPickedButton.setOnClickListener(view ->
{
Intent thirdActivity = new Intent(SecondActivity.this, ThirdActivity.class);
thirdActivity.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(thirdActivity);
});
/*ThirdActivity.java*/
public class ThirdActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
LinkedList<String> uriStrings = new LinkedList<>();
String readImageURI;
try
{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(openFileInput("uri"), StandardCharsets.UTF_8));
while (true)
{
readImageURI = bufferedReader.readLine();
if (readImageURI != null)
uriStrings.add(readImageURI);
else
break;
}
}
catch (IOException e)
{
e.printStackTrace();
}
LinearLayout imagesList = findViewById(R.id.imagesList);
uriStrings.forEach(imageURIString ->
{
ImageView imageView = new ImageView(this);
imageView.setImageURI(Uri.parse(imageURIString));
imageView.setAdjustViewBounds(true);
imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
imagesList.addView(imageView);
});
}
}
Upvotes: 1
Views: 72
Reputation: 1007474
As you can see, this not only shows the image that users pick, but also stores the uri string into a file for later use
That will not work with ACTION_PICK
.
But when I change to ThirdActivity, there is always a SecurityException stop me.
For the purposes of using the Uri
in the same process invocation as when you got it, you can pass the Uri
along in the Intent
:
Intent thirdActivity = new Intent(SecondActivity.this, ThirdActivity.class);
thirdActivity.setData(theImageUriThatWeAreTalkingAbout);
thirdActivity.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(thirdActivity);
However, that will not help for durable access via your persisted Uri
value. Either get rid of that, or:
ACTION_OPEN_DOCUMENT
instead of ACTION_PICK
, andtakePersistableUriPermission()
on a ContentResolver
when you get the image Uri
valueSee this blog post for more.
Upvotes: 0