diff --git a/ring-android/app/src/main/assets/ringtones/default.wav b/ring-android/app/src/main/assets/ringtones/default.wav index b25755cc6c6b8f06f1c8df815af7b375c12e09d2..d4db374267acfd87033482a76fd3115760d98fb9 100644 Binary files a/ring-android/app/src/main/assets/ringtones/default.wav and b/ring-android/app/src/main/assets/ringtones/default.wav differ diff --git a/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java index 88c2da9721830398cecb093f89960d9940820fb7..5bf01d1bdccdcdba7ea0869aaf2189ae359cc7f0 100644 --- a/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java +++ b/ring-android/app/src/main/java/cx/ring/fragments/MediaPreferenceFragment.java @@ -64,6 +64,8 @@ public class MediaPreferenceFragment extends PreferenceFragment protected AccountCallbacks mCallbacks = DUMMY_CALLBACKS; + private int MAX_SIZE_RINGTONE = 800; + private static final int SELECT_RINGTONE_PATH = 40; private Preference.OnPreferenceClickListener filePickerListener = new Preference.OnPreferenceClickListener() { @Override @@ -128,11 +130,28 @@ public class MediaPreferenceFragment extends PreferenceFragment String path = FileUtils.getRealPathFromURI(getActivity(), data.getData()); File myFile = new File(path); - Log.i(TAG, "file selected:" + myFile.getAbsolutePath()); + Log.i(TAG, "file selected: " + myFile.getAbsolutePath()); if (requestCode == SELECT_RINGTONE_PATH) { - findPreference(ConfigKey.RINGTONE_PATH.key()).setSummary(myFile.getName()); - mCallbacks.getAccount().setDetail(ConfigKey.RINGTONE_PATH, myFile.getAbsolutePath()); - mCallbacks.saveAccount(); + String type = getActivity().getContentResolver().getType(data.getData()); + if ("audio/mpeg3".equals(type) || "audio/x-mpeg-3".equals(type) || "audio/mpeg".equals(type) || "audio/x-mpeg".equals(type)) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.ringtone_error_title); + builder.setMessage(R.string.ringtone_error_format_not_supported); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + Log.d(TAG, "The extension file is not supported"); + } else if (myFile.length() / 1024 > MAX_SIZE_RINGTONE) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.ringtone_error_title); + builder.setMessage(getString(R.string.ringtone_error_size_too_big, MAX_SIZE_RINGTONE)); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + Log.d(TAG, "The file is too big " + myFile.length() / 1024); + } else { + findPreference(ConfigKey.RINGTONE_PATH.key()).setSummary(myFile.getName()); + mCallbacks.getAccount().setDetail(ConfigKey.RINGTONE_PATH, myFile.getAbsolutePath()); + mCallbacks.saveAccount(); + } } } diff --git a/ring-android/app/src/main/java/cx/ring/utils/FileUtils.java b/ring-android/app/src/main/java/cx/ring/utils/FileUtils.java index 4884e73932c934074dc1b432b542671b435ec7a2..c022da6f08824c32aa40118fcf453b66501ce4d9 100644 --- a/ring-android/app/src/main/java/cx/ring/utils/FileUtils.java +++ b/ring-android/app/src/main/java/cx/ring/utils/FileUtils.java @@ -19,10 +19,14 @@ package cx.ring.utils; +import android.content.ContentUris; import android.content.Context; import android.content.res.AssetManager; import android.database.Cursor; import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; import android.provider.MediaStore; import android.util.Log; @@ -86,19 +90,73 @@ public class FileUtils { } } - public static String getRealPathFromURI(Context context, Uri contentUri) { - String path; - Cursor cursor; + public static String getRealPathFromURI(Context context, Uri uri) { + String path = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("primary".equalsIgnoreCase(type)) { + path = Environment.getExternalStorageDirectory() + "/" + split[1]; + } + } else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + path = getDataColumn(context, contentUri, null, null); + } else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{split[1]}; + path = getDataColumn(context, contentUri, selection, selectionArgs); + } + } else if ("content".equalsIgnoreCase(uri.getScheme())) { + path = getDataColumn(context, uri, null, null); + } else if ("file".equalsIgnoreCase(uri.getScheme())) { + path = uri.getPath(); + } + return path; + } + + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + Cursor cursor = null; + String path = null; + final String column = "_data"; + final String[] projection = {column}; try { - String[] proj = {MediaStore.Audio.Media.DATA}; - cursor = context.getContentResolver().query(contentUri, proj, null, null, null); - int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA); - cursor.moveToFirst(); - path = cursor.getString(column_index); - cursor.close(); + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + path = cursor.getString(column_index); + } } catch (Exception e) { - Log.e(TAG, "Error while saving file to disk", e); - path = null; + Log.e(TAG, "Error while saving the ringtone", e); + } finally { + if (cursor != null) + cursor.close(); } return path; } diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml index 86cbb3860213a93830471ea8717ae27447b93b72..e163cc947aed333767a4522baacf82fd27061efd 100644 --- a/ring-android/app/src/main/res/values/strings.xml +++ b/ring-android/app/src/main/res/values/strings.xml @@ -140,6 +140,9 @@ along with this program; if not, write to the Free Software <!-- MediaPreferenceFragment --> <string name="permission_dialog_camera_title">Camera permission</string> <string name="permission_dialog_camera_message">Video conversations require the camera permission to work. Please consider enabling it.</string> + <string name="ringtone_error_title">Error</string> + <string name="ringtone_error_format_not_supported">This format is not supported.</string> + <string name="ringtone_error_size_too_big">This file is too big. The maximum size is %1$ikB.</string> <!-- Read contacts permission --> <string name="permission_dialog_read_contacts_message">Ring needs the "Read contacts" permission to enable this feature. Please grant it.</string>