modify mime type detection for shared files
add support for audiobooks
This commit is contained in:
parent
95aea4291e
commit
541c8ba80d
|
@ -74,6 +74,8 @@ public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHol
|
||||||
Log.d(Config.LOGTAG, "mime=" + mime);
|
Log.d(Config.LOGTAG, "mime=" + mime);
|
||||||
if (mime == null) {
|
if (mime == null) {
|
||||||
attr = R.attr.media_preview_unknown;
|
attr = R.attr.media_preview_unknown;
|
||||||
|
} else if (mime.equals("audio/x-m4b")) {
|
||||||
|
attr = R.attr.media_preview_audiobook;
|
||||||
} else if (mime.startsWith("audio/")) {
|
} else if (mime.startsWith("audio/")) {
|
||||||
attr = R.attr.media_preview_audio;
|
attr = R.attr.media_preview_audio;
|
||||||
} else if (mime.equals("text/calendar") || (mime.equals("text/x-vcalendar"))) {
|
} else if (mime.equals("text/calendar") || (mime.equals("text/x-vcalendar"))) {
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class MediaPreviewAdapter extends RecyclerView.Adapter<MediaPreviewAdapte
|
||||||
this.mediaPreviews.clear();
|
this.mediaPreviews.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
class MediaPreviewViewHolder extends RecyclerView.ViewHolder {
|
static class MediaPreviewViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final MediaPreviewBinding binding;
|
private final MediaPreviewBinding binding;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -260,7 +262,8 @@ public final class MimeUtils {
|
||||||
add("audio/mpeg", "mpga");
|
add("audio/mpeg", "mpga");
|
||||||
add("audio/mpeg", "mpega");
|
add("audio/mpeg", "mpega");
|
||||||
add("audio/mpeg", "mp2");
|
add("audio/mpeg", "mp2");
|
||||||
add("audio/mpeg", "m4a");
|
add("audio/mp4", "m4a");
|
||||||
|
add("audio/x-m4b", "m4b");
|
||||||
add("audio/mpegurl", "m3u");
|
add("audio/mpegurl", "m3u");
|
||||||
add("audio/ogg", "oga");
|
add("audio/ogg", "oga");
|
||||||
add("audio/opus", "opus");
|
add("audio/opus", "opus");
|
||||||
|
@ -413,6 +416,9 @@ public final class MimeUtils {
|
||||||
applyOverrides();
|
applyOverrides();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mime types that are more reliant by path
|
||||||
|
private static final Collection<String> PATH_PRECEDENCE_MIME_TYPE = Arrays.asList("audio/x-m4b");
|
||||||
|
|
||||||
private static void add(String mimeType, String extension) {
|
private static void add(String mimeType, String extension) {
|
||||||
// If we have an existing x -> y mapping, we do not want to
|
// If we have an existing x -> y mapping, we do not want to
|
||||||
// override it with another mapping x -> y2.
|
// override it with another mapping x -> y2.
|
||||||
|
@ -537,44 +543,49 @@ public final class MimeUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String guessMimeTypeFromUriAndMime(final Context context, final Uri uri, final String mime) {
|
public static String guessMimeTypeFromUriAndMime(final Context context, final Uri uri, final String mime) {
|
||||||
Log.d(Config.LOGTAG, "guessMimeTypeFromUriAndMime " + uri + " and mime=" + mime);
|
Log.d(Config.LOGTAG, "guessMimeTypeFromUriAndMime(" + uri + "," + mime+")");
|
||||||
if (mime == null || mime.equals("application/octet-stream")) {
|
final String mimeFromUri = guessMimeTypeFromUri(context, uri);
|
||||||
final String guess = guessMimeTypeFromUri(context, uri);
|
Log.d(Config.LOGTAG,"mimeFromUri:"+mimeFromUri);
|
||||||
if (guess != null) {
|
if (PATH_PRECEDENCE_MIME_TYPE.contains(mimeFromUri)) {
|
||||||
return guess;
|
return mimeFromUri;
|
||||||
|
} else if (mime == null || mime.equals("application/octet-stream")) {
|
||||||
|
return mimeFromUri;
|
||||||
} else {
|
} else {
|
||||||
return mime;
|
return mime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return guessMimeTypeFromUri(context, uri);
|
|
||||||
|
public static String guessMimeTypeFromUri(final Context context, final Uri uri) {
|
||||||
|
final String mimeTypeContentResolver = guessFromContentResolver(context, uri);
|
||||||
|
final String mimeTypeFromQueryParameter = uri.getQueryParameter("mimeType");
|
||||||
|
final String name = "content".equals(uri.getScheme()) ? getDisplayName(context, uri) : null;
|
||||||
|
final String mimeTypeFromName = Strings.isNullOrEmpty(name) ? null : guessFromPath(name);
|
||||||
|
final String path = uri.getPath();
|
||||||
|
final String mimeTypeFromPath = Strings.isNullOrEmpty(path) ? null : guessFromPath(path);
|
||||||
|
if (PATH_PRECEDENCE_MIME_TYPE.contains(mimeTypeFromName)) {
|
||||||
|
return mimeTypeFromName;
|
||||||
|
}
|
||||||
|
if (PATH_PRECEDENCE_MIME_TYPE.contains(mimeTypeFromPath)) {
|
||||||
|
return mimeTypeFromPath;
|
||||||
|
}
|
||||||
|
if (mimeTypeContentResolver != null && !"application/octet-stream".equals(mimeTypeContentResolver)) {
|
||||||
|
return mimeTypeContentResolver;
|
||||||
|
}
|
||||||
|
if (mimeTypeFromName != null) {
|
||||||
|
return mimeTypeFromName;
|
||||||
|
}
|
||||||
|
if (mimeTypeFromQueryParameter != null) {
|
||||||
|
return mimeTypeFromQueryParameter;
|
||||||
|
}
|
||||||
|
return mimeTypeFromPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String guessMimeTypeFromUri(Context context, Uri uri) {
|
private static String guessFromContentResolver(final Context context, final Uri uri) {
|
||||||
// try the content resolver
|
|
||||||
String mimeType;
|
|
||||||
try {
|
try {
|
||||||
mimeType = context.getContentResolver().getType(uri);
|
return context.getContentResolver().getType(uri);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable e) {
|
||||||
mimeType = null;
|
return null;
|
||||||
}
|
}
|
||||||
// try the extension
|
|
||||||
if (mimeType == null || mimeType.equals("application/octet-stream")) {
|
|
||||||
final String path = uri.getPath();
|
|
||||||
if (path != null) {
|
|
||||||
mimeType = guessFromPath(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mimeType == null && "content".equals(uri.getScheme())) {
|
|
||||||
final String name = getDisplayName(context, uri);
|
|
||||||
if (name != null) {
|
|
||||||
mimeType = guessFromPath(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sometimes this works (as with the commit content api)
|
|
||||||
if (mimeType == null) {
|
|
||||||
mimeType = uri.getQueryParameter("mimeType");
|
|
||||||
}
|
|
||||||
return mimeType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getDisplayName(final Context context, final Uri uri) {
|
private static String getDisplayName(final Context context, final Uri uri) {
|
||||||
|
|
|
@ -481,6 +481,8 @@ public class UIHelper {
|
||||||
return context.getString(R.string.file);
|
return context.getString(R.string.file);
|
||||||
} else if (MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime)) {
|
} else if (MimeUtils.AMBIGUOUS_CONTAINER_FORMATS.contains(mime)) {
|
||||||
return context.getString(R.string.multimedia_file);
|
return context.getString(R.string.multimedia_file);
|
||||||
|
} else if (mime.equals("audio/x-m4b")) {
|
||||||
|
return context.getString(R.string.audiobook);
|
||||||
} else if (mime.startsWith("audio/")) {
|
} else if (mime.startsWith("audio/")) {
|
||||||
return context.getString(R.string.audio);
|
return context.getString(R.string.audio);
|
||||||
} else if (mime.startsWith("video/")) {
|
} else if (mime.startsWith("video/")) {
|
||||||
|
|
6
src/main/res/drawable/ic_play_lesson_black_24.xml
Normal file
6
src/main/res/drawable/ic_play_lesson_black_24.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<vector android:height="48dp" android:tint="#000000"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M18,11c0.34,0 0.67,0.03 1,0.08V4c0,-1.1 -0.9,-2 -2,-2H5C3.9,2 3,2.9 3,4v16c0,1.1 0.9,2 2,2h7.26C11.47,20.87 11,19.49 11,18C11,14.13 14.13,11 18,11zM7,11V4h5v7L9.5,9.5L7,11z"/>
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M18,13c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S20.76,13 18,13zM16.75,20.5v-5l4,2.5L16.75,20.5z"/>
|
||||||
|
</vector>
|
6
src/main/res/drawable/ic_play_lesson_white_48dp.xml
Normal file
6
src/main/res/drawable/ic_play_lesson_white_48dp.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<vector android:height="48dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M18,11c0.34,0 0.67,0.03 1,0.08V4c0,-1.1 -0.9,-2 -2,-2H5C3.9,2 3,2.9 3,4v16c0,1.1 0.9,2 2,2h7.26C11.47,20.87 11,19.49 11,18C11,14.13 14.13,11 18,11zM7,11V4h5v7L9.5,9.5L7,11z"/>
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M18,13c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S20.76,13 18,13zM16.75,20.5v-5l4,2.5L16.75,20.5z"/>
|
||||||
|
</vector>
|
|
@ -70,6 +70,7 @@
|
||||||
<attr name="media_preview_tour" format="reference" />
|
<attr name="media_preview_tour" format="reference" />
|
||||||
<attr name="media_preview_contact" format="reference" />
|
<attr name="media_preview_contact" format="reference" />
|
||||||
<attr name="media_preview_app" format="reference" />
|
<attr name="media_preview_app" format="reference" />
|
||||||
|
<attr name="media_preview_audiobook" format="reference" />
|
||||||
<attr name="media_preview_calendar" format="reference" />
|
<attr name="media_preview_calendar" format="reference" />
|
||||||
<attr name="media_preview_archive" format="reference" />
|
<attr name="media_preview_archive" format="reference" />
|
||||||
<attr name="media_preview_ebook" format="reference" />
|
<attr name="media_preview_ebook" format="reference" />
|
||||||
|
|
|
@ -420,6 +420,7 @@
|
||||||
<string name="multimedia_file">multimedia file</string>
|
<string name="multimedia_file">multimedia file</string>
|
||||||
<string name="pdf_document">PDF document</string>
|
<string name="pdf_document">PDF document</string>
|
||||||
<string name="apk">Android App</string>
|
<string name="apk">Android App</string>
|
||||||
|
<string name="audiobook">Audiobook</string>
|
||||||
<string name="vcard">Contact</string>
|
<string name="vcard">Contact</string>
|
||||||
<string name="avatar_has_been_published">Avatar has been published!</string>
|
<string name="avatar_has_been_published">Avatar has been published!</string>
|
||||||
<string name="sending_x_file">Sending %s</string>
|
<string name="sending_x_file">Sending %s</string>
|
||||||
|
|
|
@ -88,6 +88,7 @@
|
||||||
<item name="media_preview_tour" type="reference">@drawable/baseline_tour_black_48</item>
|
<item name="media_preview_tour" type="reference">@drawable/baseline_tour_black_48</item>
|
||||||
<item name="media_preview_contact" type="reference">@drawable/ic_person_black_48dp</item>
|
<item name="media_preview_contact" type="reference">@drawable/ic_person_black_48dp</item>
|
||||||
<item name="media_preview_app" type="reference">@drawable/ic_android_black_48dp</item>
|
<item name="media_preview_app" type="reference">@drawable/ic_android_black_48dp</item>
|
||||||
|
<item name="media_preview_audiobook" type="reference">@drawable/ic_play_lesson_black_24</item>
|
||||||
<item name="media_preview_calendar" type="reference">@drawable/ic_event_black_48dp</item>
|
<item name="media_preview_calendar" type="reference">@drawable/ic_event_black_48dp</item>
|
||||||
<item name="media_preview_archive" type="reference">@drawable/ic_archive_black_48dp</item>
|
<item name="media_preview_archive" type="reference">@drawable/ic_archive_black_48dp</item>
|
||||||
<item name="media_preview_ebook" type="reference">@drawable/ic_book_black_48dp</item>
|
<item name="media_preview_ebook" type="reference">@drawable/ic_book_black_48dp</item>
|
||||||
|
@ -244,6 +245,7 @@
|
||||||
<item name="media_preview_tour" type="reference">@drawable/baseline_tour_white_48</item>
|
<item name="media_preview_tour" type="reference">@drawable/baseline_tour_white_48</item>
|
||||||
<item name="media_preview_contact" type="reference">@drawable/ic_person_white_48dp</item>
|
<item name="media_preview_contact" type="reference">@drawable/ic_person_white_48dp</item>
|
||||||
<item name="media_preview_app" type="reference">@drawable/ic_android_white_48dp</item>
|
<item name="media_preview_app" type="reference">@drawable/ic_android_white_48dp</item>
|
||||||
|
<item name="media_preview_audiobook" type="reference">@drawable/ic_play_lesson_white_48dp</item>
|
||||||
<item name="media_preview_calendar" type="reference">@drawable/ic_event_white_48dp</item>
|
<item name="media_preview_calendar" type="reference">@drawable/ic_event_white_48dp</item>
|
||||||
<item name="media_preview_archive" type="reference">@drawable/ic_archive_white_48dp</item>
|
<item name="media_preview_archive" type="reference">@drawable/ic_archive_white_48dp</item>
|
||||||
<item name="media_preview_ebook" type="reference">@drawable/ic_book_white_48dp</item>
|
<item name="media_preview_ebook" type="reference">@drawable/ic_book_white_48dp</item>
|
||||||
|
|
Loading…
Reference in a new issue