11

The question was asked here and here but there was no real answer.

Android has a built-in "Set Wallpaper" feature, such feature is available when starting an activity intent with mime "image/jpeg" or long-tapping on images in browser.

My question is: how do I programmatically invoke the built-in "Set Wallpaper" feature using a file Uri?

Community
  • 1
  • 1
Jeremy
  • 463
  • 1
  • 4
  • 10

4 Answers4

22

Seems like there is no answer to the question however I did discover a workaround:

    Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    intent.setDataAndType(uri, "image/jpeg");
    intent.putExtra("mimeType", "image/jpeg");
    this.startActivity(Intent.createChooser(intent, "Set as:"));
Jeremy
  • 463
  • 1
  • 4
  • 10
  • I'm getting the error: Unable to load photo. I'm using a drawable and getting its Uri: Uri uri = Uri.parse(context.getResources().getDrawable(drawable).toString()); – Neha Agarwal Jan 27 '19 at 08:16
  • @NehaAgarwal try using `Uri uri = Uri.parse("android.resource://your.package.here/drawable/image_name")` – Shrey Garg May 29 '19 at 09:47
  • On Pixel Android 10, It show "No apps can perform this action" – thecr0w Apr 24 '22 at 02:37
8

For me work only:

Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setDataAndType(uri, "image/*");
intent.putExtra("mimeType", "image/*");
this.startActivity(Intent.createChooser(intent, "Set as:"));

If mime "image/jpeg" apps not found image.

stalkerg
  • 494
  • 6
  • 9
4

If your app crashes after choosing the application you want to set wallpaper with, you need to add

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

A typical example is attachments in a email app. Access to the emails should be protected by permissions, since this is sensitive user data. However, if a URI to an image attachment is given to an image viewer, that image viewer no longer has permission to open the attachment since it has no reason to hold a permission to access all email.

The solution to this problem is per-URI permissions: when starting an activity or returning a result to an activity, the caller can set Intent.FLAG_GRANT_READ_URI_PERMISSION and/or Intent.FLAG_GRANT_WRITE_URI_PERMISSION. This grants the receiving activity permission access the specific data URI in the intent, regardless of whether it has any permission to access data in the content provider corresponding to the intent. https://developer.android.com/guide/topics/permissions/overview

val intent = Intent(Intent.ACTION_ATTACH_DATA)
        .apply {
            addCategory(Intent.CATEGORY_DEFAULT)
            setDataAndType(uri, "image/*")
            putExtra("mimeType", "image/*")
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }
    startActivity(Intent.createChooser(intent, "Set as:"))
Michal Engel
  • 134
  • 1
  • 2
0

And for me work only

 Intent intent = new Intent();
 intent.setAction(Intent.ACTION_ATTACH_DATA);
 intent.addCategory(Intent.CATEGORY_DEFAULT);
 intent.setDataAndType(ContactsContract.Contacts.CONTENT_URI, "image/*");
 intent.putExtra("mimeType", "image/*");
 startActivityForResult(Intent.createChooser(intent, "Select service:"), position);

position - it is your : getIntent().getExtras().getInt("id_test");

nicolas asinovich
  • 3,201
  • 3
  • 27
  • 37