Ringtone.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import android.content.ContentResolver;
20import android.content.Context;
21import android.content.res.AssetFileDescriptor;
22import android.database.Cursor;
23import android.media.AudioManager;
24import android.media.MediaPlayer;
25import android.net.Uri;
26import android.os.ParcelFileDescriptor;
27import android.provider.DrmStore;
28import android.provider.MediaStore;
29import android.provider.Settings;
30import android.util.Log;
31
32import java.io.FileDescriptor;
33import java.io.IOException;
34
35/**
36 * Ringtone provides a quick method for playing a ringtone, notification, or
37 * other similar types of sounds.
38 * <p>
39 * For ways of retrieving {@link Ringtone} objects or to show a ringtone
40 * picker, see {@link RingtoneManager}.
41 *
42 * @see RingtoneManager
43 */
44public class Ringtone {
45    private static String TAG = "Ringtone";
46
47    private static final String[] MEDIA_COLUMNS = new String[] {
48        MediaStore.Audio.Media._ID,
49        MediaStore.Audio.Media.DATA,
50        MediaStore.Audio.Media.TITLE
51    };
52
53    private static final String[] DRM_COLUMNS = new String[] {
54        DrmStore.Audio._ID,
55        DrmStore.Audio.DATA,
56        DrmStore.Audio.TITLE
57    };
58
59    private MediaPlayer mAudio;
60
61    private Uri mUri;
62    private String mTitle;
63    private FileDescriptor mFileDescriptor;
64    private AssetFileDescriptor mAssetFileDescriptor;
65
66    private int mStreamType = AudioManager.STREAM_RING;
67
68    private Context mContext;
69
70    Ringtone(Context context) {
71        mContext = context;
72    }
73
74    /**
75     * Sets the stream type where this ringtone will be played.
76     *
77     * @param streamType The stream, see {@link AudioManager}.
78     */
79    public void setStreamType(int streamType) {
80        mStreamType = streamType;
81    }
82
83    /**
84     * Gets the stream type where this ringtone will be played.
85     *
86     * @return The stream type, see {@link AudioManager}.
87     */
88    public int getStreamType() {
89        return mStreamType;
90    }
91
92    /**
93     * Returns a human-presentable title for ringtone. Looks in media and DRM
94     * content providers. If not in either, uses the filename
95     *
96     * @param context A context used for querying.
97     */
98    public String getTitle(Context context) {
99        if (mTitle != null) return mTitle;
100        return mTitle = getTitle(context, mUri, true);
101    }
102
103    private static String getTitle(Context context, Uri uri, boolean followSettingsUri) {
104        Cursor cursor = null;
105        ContentResolver res = context.getContentResolver();
106
107        String title = null;
108
109        if (uri != null) {
110            String authority = uri.getAuthority();
111
112            if (Settings.AUTHORITY.equals(authority)) {
113                if (followSettingsUri) {
114                    Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context,
115                            RingtoneManager.getDefaultType(uri));
116                    String actualTitle = getTitle(context, actualUri, false);
117                    title = context
118                            .getString(com.android.internal.R.string.ringtone_default_with_actual,
119                                    actualTitle);
120                }
121            } else {
122
123                if (DrmStore.AUTHORITY.equals(authority)) {
124                    cursor = res.query(uri, DRM_COLUMNS, null, null, null);
125                } else if (MediaStore.AUTHORITY.equals(authority)) {
126                    cursor = res.query(uri, MEDIA_COLUMNS, null, null, null);
127                }
128
129                if (cursor != null && cursor.getCount() == 1) {
130                    cursor.moveToFirst();
131                    return cursor.getString(2);
132                } else {
133                    title = uri.getLastPathSegment();
134                }
135            }
136        }
137
138        if (title == null) {
139            title = context.getString(com.android.internal.R.string.ringtone_unknown);
140
141            if (title == null) {
142                title = "";
143            }
144        }
145
146        return title;
147    }
148
149    private void openMediaPlayer() throws IOException {
150        mAudio = new MediaPlayer();
151        if (mUri != null) {
152            mAudio.setDataSource(mContext, mUri);
153        } else if (mFileDescriptor != null) {
154            mAudio.setDataSource(mFileDescriptor);
155        } else if (mAssetFileDescriptor != null) {
156            mAudio.setDataSource(mAssetFileDescriptor.getFileDescriptor(),
157                    mAssetFileDescriptor.getStartOffset(),
158                    mAssetFileDescriptor.getLength());
159        } else {
160            throw new IOException("No data source set.");
161        }
162        mAudio.setAudioStreamType(mStreamType);
163        mAudio.prepare();
164    }
165
166    void open(FileDescriptor fd) throws IOException {
167        mFileDescriptor = fd;
168        openMediaPlayer();
169    }
170
171    void open(AssetFileDescriptor fd) throws IOException {
172        mAssetFileDescriptor = fd;
173        openMediaPlayer();
174    }
175
176    void open(Uri uri) throws IOException {
177        mUri = uri;
178        openMediaPlayer();
179    }
180
181    /**
182     * Plays the ringtone.
183     */
184    public void play() {
185        if (mAudio == null) {
186            try {
187                openMediaPlayer();
188            } catch (Exception ex) {
189                Log.e(TAG, "play() caught ", ex);
190                mAudio = null;
191            }
192        }
193        if (mAudio != null) {
194            mAudio.start();
195        }
196    }
197
198    /**
199     * Stops a playing ringtone.
200     */
201    public void stop() {
202        if (mAudio != null) {
203            mAudio.reset();
204            mAudio.release();
205            mAudio = null;
206        }
207    }
208
209    /**
210     * Whether this ringtone is currently playing.
211     *
212     * @return True if playing, false otherwise.
213     */
214    public boolean isPlaying() {
215        return mAudio != null && mAudio.isPlaying();
216    }
217
218    void setTitle(String title) {
219        mTitle = title;
220    }
221}
222