Jak określić typ pliku MIME w systemie Android?

176

Załóżmy, że mam pełną ścieżkę do pliku, taką jak: (/ sdcard / tlogo.png). Chcę poznać jego typ mime.

Stworzyłem dla niego funkcję

public static String getMimeType(File file, Context context)    
{
    Uri uri = Uri.fromFile(file);
    ContentResolver cR = context.getContentResolver();
    MimeTypeMap mime = MimeTypeMap.getSingleton();
    String type = mime.getExtensionFromMimeType(cR.getType(uri));
    return type;
}

ale kiedy to nazywam, zwraca wartość null.

File file = new File(filePath);
String fileType=CommonFunctions.getMimeType(file, context);
Sushant Bhatnagar
źródło

Odpowiedzi:

323

Przede wszystkim powinieneś rozważyć zadzwonienie w MimeTypeMap#getMimeTypeFromExtension()ten sposób:

// url = file path or whatever suitable URL you want.
public static String getMimeType(String url) {
    String type = null;
    String extension = MimeTypeMap.getFileExtensionFromUrl(url);
    if (extension != null) {
        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    }
    return type;
}
Jens
źródło
4
dzięki za pracę dla mnie i innym rozwiązaniem mojego problemu jest: public static String getMimeType (ścieżka ciągu, kontekst kontekstu) {String extention = path.substring (path.lastIndexOf (".")); String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl (extention); String mimeType = MimeTypeMap.getSingleton () .getMimeTypeFromExtension (mimeTypeMap); return mimeType;}
Sushant Bhatnagar
13
A jeśli plik nie ma dobrego rozszerzenia? osoba może stworzyć .mp3 i zawiera tekst
throrin19
2
Następnie musiałbyś faktycznie otworzyć plik i sprawdzić magiczną liczbę (w zależności od formatu c) na wejściu - zakłada to jednak również, że osoba zmieniająca nazwy plików txt na mp3 nie pisała po prostu ID3w początek jego tekstu, by jeszcze bardziej zepsuć z Tobą.
Jens,
1
Jeśli plik ma nieznane rozszerzenie. Czy metoda zwraca */*?
3
Jeśli masz ścieżkę do pliku / storage / emulated / 0 / Download / images (4) .jpg i poprosisz o podanie typu MIME, zwraca wartość null.
Kalaiselvan
165

Wykryj typ MIME dowolnego pliku

public String getMimeType(Uri uri) {           
    String mimeType = null;
    if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
        ContentResolver cr = getAppContext().getContentResolver();
        mimeType = cr.getType(uri);
    } else {
        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
                .toString());
        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                fileExtension.toLowerCase());
    }
    return mimeType;
}
Hoa Le
źródło
5
To powinna być prawidłowa odpowiedź. toLowerCase()załatwił sprawę.
Rajat Saxena
1
To zdecydowanie najlepsza odpowiedź, ale kończy się to żałośnie, jeśli nazwa pliku ma znak specjalny, w moim przypadku apostrophe! Na przykład. nazwa pliku = Don't go baby.mp3. PatternMatcherWewnątrz MimeTypeMap.getFileExtensionFromUrl()nie może obsłużyć nazwę pliku i zwraca pusty ciąg; null jest ciągiem typu MIME!
sud007
Istnieje podobne, ale bezbłędne rozwiązanie poniżej autorstwa I. ShvedenenkoWorked dla problemów, które wskazałem powyżej. Ale ta odpowiedź była wskazówką we właściwym kierunku.
sud007
ten kod zwraca wartość null z ciągiem „/ storage / emulated / 0 / dcim / screenshots / screenshot_20190319-123828_ubl digital app.jpg”.
Abdul
@Abdul Dzieje się tak, ponieważ ta ścieżka nie ma schematu Uri. Powinien zaczynać się od file://lub content://.
HB.
33

Powyższe rozwiązanie MimeTypeMap zwróciło wartość null w moim użyciu. To działa i jest łatwiejsze:

Uri uri = Uri.fromFile(file);
ContentResolver cR = context.getContentResolver();
String mime = cR.getType(uri);
Jeb
źródło
19
Ta metoda może również zwrócić wartość null.
Mister Smith
Wygląda na to, że może zwrócić wartość null lub nie, zgodnie z identyfikatorem URI. Wydaje się, że nikt nie wie dlaczego ;-(
Thomas Decaux
10
Jeśli nośnik zostanie wybrany z galerii Androida, zwracany jest TYPE. Jeśli wybrano z Menedżera plików, zwracana jest wartość null.
Rahul Rastogi
Mogę pozytywnie potwierdzić to, co powiedział Rahul, właśnie to przetestowałem i ma rację
Chris
W niektórych urządzeniach gdybym wybrać obraz z galerii również to wraca NULL
Ghanshyam Nayma
21

Zoptymalizowana wersja odpowiedzi Jensa z typem zerowym i awaryjnym.

@NonNull
static String getMimeType(@NonNull File file) {
    String type = null;
    final String url = file.toString();
    final String extension = MimeTypeMap.getFileExtensionFromUrl(url);
    if (extension != null) {
        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
    }
    if (type == null) {
        type = "image/*"; // fallback type. You might set it to */*
    }
    return type;
}

Ważne : getFileExtensionFromUrl () działa tylko z małymi literami !


Aktualizacja (19.03.2018)

Bonus: powyższe metody jako mniej szczegółowa funkcja rozszerzenia Kotlin :

fun File.getMimeType(fallback: String = "image/*"): String {
    return MimeTypeMap.getFileExtensionFromUrl(toString())
            ?.run { MimeTypeMap.getSingleton().getMimeTypeFromExtension(toLowerCase()) }
            ?: fallback // You might set it to */*
}
Tobias
źródło
to zadziałało. trochę zbyt gadatliwe, jak na mój gust.
filthy_wizard
Oczywiście może to być krótsze. Z Kotlinem prawdopodobnie tylko dwie lub trzy linie, jednak lis był na zerowym bezpieczeństwie i toLoverCaseczęściowo.
Tobias
@filthy_wizard, dodano zoptymalizowaną wersję specjalnie dla Ciebie ;-)
Tobias
Jak dla mnie użycie metody getPath () zamiast toString () jest bardziej przejrzyste i wystarczy ścieżka używając składni dostępu do właściwości kotlin.
Leonid
15
File file = new File(path, name);

    MimeTypeMap mime = MimeTypeMap.getSingleton();
    int index = file.getName().lastIndexOf('.')+1;
    String ext = file.getName().substring(index).toLowerCase();
    String type = mime.getMimeTypeFromExtension(ext);

    intent.setDataAndType(Uri.fromFile(file), type);
    try
    {
      context.startActivity(intent);
    }
    catch(ActivityNotFoundException ex)
    {
        ex.printStackTrace();

    }
umerk44
źródło
1
U mnie działa idealnie! Ale co powiesz na użycie pliku FilenameUtils.getExetension (ścieżka), aby uzyskać rozszerzenie pliku?
peterb
7

Płacić bardzo baczną uwagę na umerk44 „s rozwiązania powyżej. getMimeTypeFromExtensionwywołuje guessMimeTypeTypeFromExtensioni rozróżnia wielkość liter. Spędziłem nad tym popołudnie, a potem przyjrzałem się bliżej - getMimeTypeFromExtensionwrócę, NULLjeśli podasz "JPG", a zwróci "image / jpeg", jeśli podasz "jpg".

Mike Kogan
źródło
5

Oto rozwiązanie, którego użyłem w mojej aplikacji na Androida:

public static String getMimeType(String url)
    {
        String extension = url.substring(url.lastIndexOf("."));
        String mimeTypeMap = MimeTypeMap.getFileExtensionFromUrl(extension);
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mimeTypeMap);
        return mimeType;
    }
Mahendra Liya
źródło
1
url? Wiele adresów URL nie ma rozszerzenia. Na przykład ta strona nie ma rozszerzenia. W przypadku adresu URL należy użyć nowego adresu URL (url) .openConnection (). GetRequestProperty ("Content-type");
barwnikk
5

Czasami odpowiedzi Jeba i Jensa nie działają i zwracają zero. W tym przypadku korzystam z rozwiązania follow. Nagłówek pliku zwykle zawiera sygnaturę typu. Przeczytałem i porównuję ze znanymi na liście podpisów .

/**
 *
 * @param is InputStream on start of file. Otherwise signature can not be defined.
 * @return int id of signature or -1, if unknown signature was found. See SIGNATURE_ID_(type) constants to
 *      identify signature by its id.
 * @throws IOException in cases of read errors.
 */
public static int getSignatureIdFromHeader(InputStream is) throws IOException {
    // read signature from head of source and compare with known signatures
    int signatureId = -1;
    int sigCount = SIGNATURES.length;
    int[] byteArray = new int[MAX_SIGNATURE_LENGTH];
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
        byteArray[i] = is.read();
        builder.append(Integer.toHexString(byteArray[i]));
    }
    if (DEBUG) {
        Log.d(TAG, "head bytes=" + builder.toString());
    }
    for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {

        // check each bytes with known signatures
        int bytes = byteArray[i];
        int lastSigId = -1;
        int coincidences = 0;

        for (int j = 0; j < sigCount; j++) {
            int[] sig = SIGNATURES[j];

            if (DEBUG) {
                Log.d(TAG, "compare" + i + ": " + Integer.toHexString(bytes) + " with " + sig[i]);
            }
            if (bytes == sig[i]) {
                lastSigId = j;
                coincidences++;
            }
        }

        // signature is unknown
        if (coincidences == 0) {
            break;
        }
        // if first bytes of signature is known we check signature for full coincidence
        if (coincidences == 1) {
            int[] sig = SIGNATURES[lastSigId];
            int sigLength = sig.length;
            boolean isSigKnown = true;
            for (; i < MAX_SIGNATURE_LENGTH && i < sigLength; i++) {
                bytes = byteArray[i];
                if (bytes != sig[i]) {
                    isSigKnown = false;
                    break;
                }
            }
            if (isSigKnown) {
                signatureId = lastSigId;
            }
            break;
        }
    }
    return signatureId;
}

signatureIdjest indeksem podpisu w tablicy podpisów. Na przykład,

private static final int[] SIGNATURE_PNG = hexStringToIntArray("89504E470D0A1A0A");
private static final int[] SIGNATURE_JPEG = hexStringToIntArray("FFD8FF");
private static final int[] SIGNATURE_GIF = hexStringToIntArray("474946");

public static final int SIGNATURE_ID_JPEG = 0;
public static final int SIGNATURE_ID_PNG = 1;
public static final int SIGNATURE_ID_GIF = 2;
private static final int[][] SIGNATURES = new int[3][];

static {
    SIGNATURES[SIGNATURE_ID_JPEG] = SIGNATURE_JPEG;
    SIGNATURES[SIGNATURE_ID_PNG] = SIGNATURE_PNG;
    SIGNATURES[SIGNATURE_ID_GIF] = SIGNATURE_GIF;
}

Teraz mam typ pliku, nawet jeśli nie ma identyfikatora URI pliku. Następnie otrzymuję typ MIME według typu pliku. Jeśli nie wiesz, jaki typ MIME uzyskać, możesz znaleźć odpowiedni w tej tabeli .

Działa dla wielu typów plików. Ale w przypadku wideo to nie działa, ponieważ potrzebujesz znanego kodeka wideo, aby uzyskać typ MIME. Aby uzyskać typ MIME wideo, używam MediaMetadataRetriever .

Siergiej Wasilenko
źródło
4

Próbowałem użyć standardowych metod do określenia typu MIME, ale nie mogę zachować rozszerzenia pliku za pomocą MimeTypeMap.getFileExtensionFromUrl(uri.getPath()). Ta metoda zwróciła mi pusty ciąg. Zrobiłem więc nietrywialne rozwiązanie, aby zachować rozszerzenie pliku.

Oto metoda zwracająca rozszerzenie pliku:

private String getExtension(String fileName){
    char[] arrayOfFilename = fileName.toCharArray();
    for(int i = arrayOfFilename.length-1; i > 0; i--){
        if(arrayOfFilename[i] == '.'){
            return fileName.substring(i+1, fileName.length());
        }
    }
    return "";
}

Zachowując rozszerzenie pliku, można uzyskać typ MIME, jak poniżej:

public String getMimeType(File file) {
    String mimeType = "";
    String extension = getExtension(file.getName());
    if (MimeTypeMap.getSingleton().hasExtension(extension)) {
        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    }
    return mimeType;
}
I. Shvedenenko
źródło
Człowieku, to przybiło wszystkie odpowiedzi zamieszczone tutaj na ten problem! Miałem ten sam problem ze wszystkimi klasami Legacy. Problem był taki sam, jak wspomniałeś, MimeTypeMap.getFileExtensionFromUrlzwrócił pusty ciąg dla nazw plików, które zawierają nieprawidłowe znaki zgodnie z wewnętrzną implementacją pliku PatternMatcher. To zadziałało dla mnie całkowicie! Uwielbiałem to, do tej pory żadnych problemów!
sud007
@JA. Shvedenenko String extension = file.getName().split("\\.")[1]również działałby, eliminując w ten sposób metodę getExtension ().
Shahood ul Hassan
Ale chodzi o to, co się stanie, jeśli podczas tworzenia pliku zostanie użyte niewłaściwe rozszerzenie? Czy rozszerzenie powinno być jedynym sędzią typu pantomimy?
Shahood ul Hassan
2

MimeTypeMapmoże nie rozpoznawać niektórych rozszerzeń plików, takich jak flv, mpeg, 3gpp, cpp. Musisz więc pomyśleć, jak rozszerzyć MimeTypeMap w celu utrzymania kodu. Oto taki przykład.

http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/net/MimeUtils.java#MimeUtils

Dodatkowo, oto pełna lista typów MIME

http: //www.sitepoint.com/web-foundations/mime-types-complete-list/

Min Thant Htoo
źródło
2

Dla platformy Xamarin Android (powyższa odpowiedź z @ HoaLe)

public String getMimeType(Uri uri) {
    String mimeType = null;
    if (uri.Scheme.Equals(ContentResolver.SchemeContent))
    {
        ContentResolver cr = Application.Context.ContentResolver;
        mimeType = cr.GetType(uri);
    }
    else
    {
        String fileExtension = MimeTypeMap.GetFileExtensionFromUrl(uri.ToString());
        mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(
        fileExtension.ToLower());
    }
    return mimeType;
}
Ciekawość
źródło
1
get file object....
File file = new File(filePath);

then....pass as a parameter to...

getMimeType(file);

...here is 


public String getMimeType(File file) {
        String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()).toLowerCase());
        if (mimetype == null) {
            return "*/*";
        }
        return mimetype;///return the mimeType
    }
Nilesh Panchal
źródło
1

Podczas gdy z zasobu / pliku (zwróć uwagę, że brakuje kilku przypadków w MimeTypeMap).

private String getMimeType(String path) {
    if (null == path) return "*/*";

    String extension = path;
    int lastDot = extension.lastIndexOf('.');
    if (lastDot != -1) {
        extension = extension.substring(lastDot + 1);
    }

    // Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
    extension = extension.toLowerCase(Locale.getDefault());
    if (extension.equals("3ga")) {
        return "audio/3gpp";
    } else if (extension.equals("js")) {
        return "text/javascript";
    } else if (extension.equals("woff")) {
        return "application/x-font-woff";
    } else {
        // TODO
        // anyting missing from the map (http://www.sitepoint.com/web-foundations/mime-types-complete-list/)
        // reference: http://grepcode.com/file/repo1.maven.org/maven2/com.google.okhttp/okhttp/20120626/libcore/net/MimeUtils.java#MimeUtils
    }

    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}

Podczas korzystania z ContentResolver

contentResolver.getType(uri)

Podczas żądania http / https

    try {
        HttpURLConnection conn = httpClient.open(new URL(uri.toString()));
        conn.setDoInput(false);
        conn.setRequestMethod("HEAD");
        return conn.getHeaderField("Content-Type");
    } catch (IOException e) {
    }
WCG
źródło
1
// This will return the mimeType. 
// for eg. xyz.png it will return image/png. 
// here uri is the file that we were picked using intent from ext/internal storage.
private String getMimeType(Uri uri) {
   // This class provides applications access to the content model.  
   ContentResolver contentResolver = getContentResolver();

   // getType(Uri url)-Return the MIME type of the given content URL. 
   return contentResolver.getType(uri);
}
iamdhariot
źródło
Proszę podać wyjaśnienie. Pomoże to początkowemu czytelnikowi dostosować swój kod i dalszym czytelnikom, aby uzyskać jak największą wartość z Twojej odpowiedzi.
Aurélien B
Dzięki za twoją odpowiedź. Edytuję to z wyjaśnieniem.
iamdhariot
1

Miałem podobny problem. Na razie wiem, że wynik może się różnić dla różnych nazw, więc w końcu doszedłem do tego rozwiązania.

public String getMimeType(String filePath) {
    String type = null;
    String extension = null;
    int i = filePath.lastIndexOf('.');
    if (i > 0)
        extension = filePath.substring(i+1);
    if (extension != null)
        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    return type;
}  
Ashish Sahu
źródło
0

Powyższe rozwiązanie zwróciło wartość null w przypadku pliku .rar, w tym przypadku zadziałało użycie adresu URLConnection.guessContentTypeFromName (url).

Luis Barragan
źródło
0

mime z pliku lokalnego:

String url = file.getAbsolutePath();
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mime = fileNameMap.getContentTypeFor("file://"+url);
Flinbor
źródło
0

masz wielokrotny wybór, aby uzyskać rozszerzenie pliku: jak: 1- String filename = uri.getLastPathSegment();Zobacz ten link

2-możesz również użyć tego kodu

 filePath .substring(filePath.lastIndexOf(".")+1);

ale to nie jest dobra aprocha. 3 - jeśli masz URI pliku, użyj tego kodu

String[] projection = { MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.MIME_TYPE };

4-jeśli masz adres URL, użyj tego kodu:

 public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) { 


  type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    }

return type;
}

miłego kodu :)

John Smith
źródło
0
// new processing the mime type out of Uri which may return null in some cases
String mimeType = getContentResolver().getType(uri);
// old processing the mime type out of path using the extension part if new way returned null
if (mimeType == null){mimeType URLConnection.guessContentTypeFromName(path);}
YEH
źródło
0
public static String getFileType(Uri file)
{
    try
    {
        if (file.getScheme().equals(ContentResolver.SCHEME_CONTENT))
            return subStringFromLastMark(SystemMaster.getContentResolver().getType(file), "/");
        else
            return MimeTypeMap.getFileExtensionFromUrl(file.toString()).toLowerCase();
    }
    catch(Exception e)
    {
        return null;
    }
}

public static String getMimeType(Uri file)
{
    try
    {
        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(getFileType(file));
    }
    catch(Exception e)
    {
        return null;
    }
}

public static String subStringFromLastMark(String str,String mark)
{
    int l = str.lastIndexOf(mark);
    int end = str.length();
    if(l == -1)
        return str;

    return str.substring(l + 1, end);
}
Ali Bagheri
źródło
0

Zwrócił również wartość null w mojej ścieżce sprawy

/ storage / emulated / 0 / Music / 01 - Ghost on the Dance Floor.mp3

jako obejście użycia

val url = inUrl.replace ("", "")

tak wygląda metoda

@JvmStatic
    fun getMimeType(inUrl: String?): String {
        if (inUrl == null) return ""

        val url = inUrl.replace(" ","")
        var type: String? = null

        val extension = MimeTypeMap.getFileExtensionFromUrl(url)
        if (extension != null) {
            type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase())
        }

        if(type ==null){
            val cR = WifiTalkie.getApplicationContext().contentResolver
            type = cR.getType(Uri.parse(url))
        }

        if (type == null) {
            type = "*/*" // fallback method_type. You might set it to */*
        }
        return type
    }

w rezultacie zwraca wynik sukcesu:

audio / mpeg

Mam nadzieję, że to pomoże każdemu

Serg Burlaka
źródło
0

Żadna z odpowiedzi tutaj nie jest idealna. Oto odpowiedź łącząca najlepsze elementy ze wszystkich najlepszych odpowiedzi:

public final class FileUtil {

    // By default, Android doesn't provide support for JSON
    public static final String MIME_TYPE_JSON = "application/json";

    @Nullable
    public static String getMimeType(@NonNull Context context, @NonNull Uri uri) {

        String mimeType = null;
        if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
            ContentResolver cr = context.getContentResolver();
            mimeType = cr.getType(uri);
        } else {
            String fileExtension = getExtension(uri.toString());

            if(fileExtension == null){
                return null;
            }

            mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                    fileExtension.toLowerCase());

            if(mimeType == null){
                // Handle the misc file extensions
                return handleMiscFileExtensions(fileExtension);
            }
        }
        return mimeType;
    }

    @Nullable
    private static String getExtension(@Nullable String fileName){

        if(fileName == null || TextUtils.isEmpty(fileName)){
            return null;
        }

        char[] arrayOfFilename = fileName.toCharArray();
        for(int i = arrayOfFilename.length-1; i > 0; i--){
            if(arrayOfFilename[i] == '.'){
                return fileName.substring(i+1, fileName.length());
            }
        }
        return null;
    }

    @Nullable
    private static String handleMiscFileExtensions(@NonNull String extension){

        if(extension.equals("json")){
            return MIME_TYPE_JSON;
        }
        else{
            return null;
        }
    }
}
Manish Kumar Sharma
źródło
0
Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
                        File file = new File(filePatch); 
                        Uri uris = Uri.fromFile(file);
                        String mimetype = null;
                        if 
(uris.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
                            ContentResolver cr = 
getApplicationContext().getContentResolver();
                            mimetype = cr.getType(uris);
                        } else {
                            String fileExtension = 
MimeTypeMap.getFileExtensionFromUrl(uris.toString());
mimetype =  MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase());
                        }
Роман Зыков
źródło
0

Nie zdaję sobie sprawy, dlaczego MimeTypeMap.getFileExtensionFromUrl()ma problemy z spacesi kilkoma innymi znakami, które powracają "", ale właśnie napisałem tę metodę, aby zmienić nazwę pliku na dopuszczalną. To tylko zabawa z Strings. Jednak to trochę działa. W ten sposób spaceznaki występujące w nazwie pliku są zamieniane na pożądany znak (tutaj jest to „x”), replaceAll(" ", "x")a inne nieodpowiednie znaki są zamieniane na odpowiedni znak za pomocą URLEncoder. więc użycie (zgodnie z kodami przedstawionymi w pytaniu i wybraną odpowiedzią) powinno być jakoś getMimeType(reviseUrl(url)).

private String reviseUrl(String url) {

        String revisedUrl = "";
        int fileNameBeginning = url.lastIndexOf("/");
        int fileNameEnding = url.lastIndexOf(".");

        String cutFileNameFromUrl = url.substring(fileNameBeginning + 1, fileNameEnding).replaceAll(" ", "x");

        revisedUrl = url.
                substring(0, fileNameBeginning + 1) +
                java.net.URLEncoder.encode(cutFileNameFromUrl) +
                url.substring(fileNameEnding, url.length());

        return revisedUrl;
    }
elyar abad
źródło