jak uzyskać identyfikator URI zasobu obrazu w systemie Android

96

Muszę otworzyć zamiar wyświetlenia obrazu w następujący sposób:

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("@drawable/sample_1.jpg");
intent.setData(uri);
startActivity(intent);

Problem w tym, że Uri uri = Uri.parse("@drawable/sample_1.jpg");to nieprawda.

user602874
źródło

Odpowiedzi:

138

Format to:

"android.resource://[package]/[res id]"

[pakiet] to nazwa twojego pakietu

[res id] to wartość identyfikatora zasobu, np. R.drawable.sample_1

aby go zszyć, użyj

Uri path = Uri.parse("android.resource://your.package.name/" + R.drawable.sample_1);

Axarydax
źródło
3
Uri path = Uri.parse ("android.resource: //net.londatiga.android.twitpic/" + R.drawable.icon); String mpath = path.toString (); Nie widzę takiego błędu pliku lub katalogu, kiedy to robię
hemanth kumar
4
kiedy próbuję wysłać obraz jako załącznik do wiadomości e-mail, wysyła plik, ale bez rozszerzenia .jpg. Więc obraz nie jest ważny w komputerze odbiorcy.
ruben
@hemanthkumar Zobacz tę odpowiedź jako odniesienie: stackoverflow.com/a/8476930/62921 Wyjaśnia, że ​​nie ma folderu do rysowania poza Twoim komputerem. Dlatego używa identyfikatorów i twoja path.toString () nie działa.
ForceMagic,
To nie działa dla mnie. Otrzymuję ActivityNotFoundException. (android.content.ActivityNotFoundException: Nie znaleziono działania obsługującego zamiar {act = android.intent.action.VIEW dat = android.resource: //com.mypackage.myapp/2130837582}. LG E400 Android 2.3.6.
Lucio Crusca
@LucioCrusca - może powinieneś określić typ intencji - czy jest to obraz jpeg czy png?
Axarydax
65

Oto przejrzyste rozwiązanie, które w pełni wykorzystuje android.net.Uriklasę poprzez jej Builderwzorzec, unikając powtarzającego się składu i dekompozycji łańcucha URI, bez polegania na ciągach zakodowanych na stałe lub ad hoc pomysłów dotyczących składni URI.

Resources resources = context.getResources();
Uri uri = new Uri.Builder()
    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
    .authority(resources.getResourcePackageName(resourceId))
    .appendPath(resources.getResourceTypeName(resourceId))
    .appendPath(resources.getResourceEntryName(resourceId))
    .build();
Uli
źródło
to rozwiązało mój problem. Mój kształt uri wyglądał jak „android.resource: //com.craiovadata.guessthecountry/drawable/sky”
Dan Alboteanu
56
public static Uri resourceToUri(Context context, int resID) {
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                context.getResources().getResourcePackageName(resID) + '/' +
                context.getResources().getResourceTypeName(resID) + '/' +
                context.getResources().getResourceEntryName(resID) );
    }
xnagyg
źródło
9

Dla tych, którzy mają błąd, być może wprowadzasz niewłaściwą nazwę pakietu. Po prostu użyj tej metody.

public static Uri resIdToUri(Context context, int resId) {
    return Uri.parse(Consts.ANDROID_RESOURCE + context.getPackageName()
                     + Consts.FORESLASH + resId);
}

Gdzie

public static final String ANDROID_RESOURCE = "android.resource://";
public static final String FORESLASH = "/";
sandalon
źródło
10
czy naprawdę stworzyłeś stałą dla foreslash?
Sartheris Stormhammer
@SartherisStormhammer Tak :), chociaż zwykle używam stałej systemowej do foreslash;)
sandalone
4

Potrzebujesz identyfikatora URI zasobu obrazu i R.drawable.goombjest to zasób obrazu. Funkcja Builder tworzy identyfikator URI, o który prosisz:

String resourceScheme = "res";
Uri uri = new Uri.Builder()
  .scheme(resourceScheme)
  .path(String.valueOf(intResourceId))
  .build();
roide
źródło
Więc mijasz coś w rodzaju „18” do ścieżki. Wydaje się to niepoprawne
Nick Cardoso
@NickCardoso R.drawable.goomba to plik do rysowania, który mam w folderze zasobów. Jeśli jego wartość wynosi 18, czy to powoduje, że przypisanie jest nieprawidłowe?
roide
Oczywiście, że tak. developer.android.com/reference/android/net/… Identyfikator w pliku R musi być użyty do znalezienia prawdziwej ścieżki.
Nick Cardoso
@NickCardoso dzięki, ale nie działa i działa idealnie. Schemat zajmuje się tą ścieżką, jak sugeruje wskazana przez ciebie dokumentacja.
roide
3

W oparciu o powyższe odpowiedzi chcę podzielić się przykładem kotlin pokazującym, jak uzyskać prawidłowy Uri dla dowolnego zasobu w Twoim projekcie. Myślę, że to najlepsze rozwiązanie, ponieważ nie musisz wpisywać żadnych ciągów w swoim kodzie i ryzykujesz wpisanie go nieprawidłowo.

    val resourceId = R.raw.scannerbeep // r.mipmap.yourmipmap; R.drawable.yourdrawable
    val uriBeepSound = Uri.Builder()
        .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
        .authority(resources.getResourcePackageName(resourceId))
        .appendPath(resources.getResourceTypeName(resourceId))
        .appendPath(resources.getResourceEntryName(resourceId))
        .build()
Sergio
źródło