Ringtone.java revision 076357b8567458d4b6dfdcf839ef751634cd2bfb
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.provider.DrmStore;
27import android.provider.MediaStore;
28import android.provider.Settings;
29import android.util.Log;
30
31import java.io.FileDescriptor;
32import java.io.IOException;
33
34/**
35 * Ringtone provides a quick method for playing a ringtone, notification, or
36 * other similar types of sounds.
37 * <p>
38 * For ways of retrieving {@link Ringtone} objects or to show a ringtone
39 * picker, see {@link RingtoneManager}.
40 *
41 * @see RingtoneManager
42 */
43public class Ringtone {
44    private static String TAG = "Ringtone";
45
46    private static final String[] MEDIA_COLUMNS = new String[] {
47        MediaStore.Audio.Media._ID,
48        MediaStore.Audio.Media.DATA,
49        MediaStore.Audio.Media.TITLE
50    };
51
52    private static final String[] DRM_COLUMNS = new String[] {
53        DrmStore.Audio._ID,
54        DrmStore.Audio.DATA,
55        DrmStore.Audio.TITLE
56    };
57
58    private MediaPlayer mAudio;
59
60    private Uri mUri;
61    private String mTitle;
62    private FileDescriptor mFileDescriptor;
63    private AssetFileDescriptor mAssetFileDescriptor;
64
65    private int mStreamType = AudioManager.STREAM_RING;
66
67    private Context mContext;
68
69    Ringtone(Context context) {
70        mContext = context;
71    }
72
73    /**
74     * Sets the stream type where this ringtone will be played.
75     *
76     * @param streamType The stream, see {@link AudioManager}.
77     */
78    public void setStreamType(int streamType) {
79        mStreamType = streamType;
80
81        if (mAudio != null) {
82            /*
83             * The stream type has to be set before the media player is
84             * prepared. Re-initialize it.
85             */
86            try {
87                openMediaPlayer();
88            } catch (IOException e) {
89                Log.w(TAG, "Couldn't set the stream type", e);
90            }
91        }
92    }
93
94    /**
95     * Gets the stream type where this ringtone will be played.
96     *
97     * @return The stream type, see {@link AudioManager}.
98     */
99    public int getStreamType() {
100        return mStreamType;
101    }
102
103    /**
104     * Returns a human-presentable title for ringtone. Looks in media and DRM
105     * content providers. If not in either, uses the filename
106     *
107     * @param context A context used for querying.
108     */
109    public String getTitle(Context context) {
110        if (mTitle != null) return mTitle;
111        return mTitle = getTitle(context, mUri, true);
112    }
113
114    private static String getTitle(Context context, Uri uri, boolean followSettingsUri) {
115        Cursor cursor = null;
116        ContentResolver res = context.getContentResolver();
117
118        String title = null;
119
120        if (uri != null) {
121            String authority = uri.getAuthority();
122
123            if (Settings.AUTHORITY.equals(authority)) {
124                if (followSettingsUri) {
125                    Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context,
126                            RingtoneManager.getDefaultType(uri));
127                    String actualTitle = getTitle(context, actualUri, false);
128                    title = context
129                            .getString(com.android.internal.R.string.ringtone_default_with_actual,
130                                    actualTitle);
131                }
132            } else {
133
134                if (DrmStore.AUTHORITY.equals(authority)) {
135                    cursor = res.query(uri, DRM_COLUMNS, null, null, null);
136                } else if (MediaStore.AUTHORITY.equals(authority)) {
137                    cursor = res.query(uri, MEDIA_COLUMNS, null, null, null);
138                }
139
140                if (cursor != null && cursor.getCount() == 1) {
141                    cursor.moveToFirst();
142                    return cursor.getString(2);
143                } else {
144                    title = uri.getLastPathSegment();
145                }
146            }
147        }
148
149        if (title == null) {
150            title = context.getString(com.android.internal.R.string.ringtone_unknown);
151
152            if (title == null) {
153                title = "";
154            }
155        }
156
157        return title;
158    }
159
160    private void openMediaPlayer() throws IOException {
161        mAudio = new MediaPlayer();
162        if (mUri != null) {
163            mAudio.setDataSource(mContext, mUri);
164        } else if (mFileDescriptor != null) {
165            mAudio.setDataSource(mFileDescriptor);
166        } else if (mAssetFileDescriptor != null) {
167            mAudio.setDataSource(mAssetFileDescriptor.getFileDescriptor(),
168                    mAssetFileDescriptor.getStartOffset(),
169                    mAssetFileDescriptor.getLength());
170        } else {
171            throw new IOException("No data source set.");
172        }
173        mAudio.setAudioStreamType(mStreamType);
174        mAudio.prepare();
175    }
176
177    void open(FileDescriptor fd) throws IOException {
178        mFileDescriptor = fd;
179        openMediaPlayer();
180    }
181
182    void open(AssetFileDescriptor fd) throws IOException {
183        mAssetFileDescriptor = fd;
184        openMediaPlayer();
185    }
186
187    void open(Uri uri) throws IOException {
188        mUri = uri;
189        openMediaPlayer();
190    }
191
192    /**
193     * Plays the ringtone.
194     */
195    public void play() {
196        if (mAudio == null) {
197            try {
198                openMediaPlayer();
199            } catch (Exception ex) {
200                Log.e(TAG, "play() caught ", ex);
201                mAudio = null;
202            }
203        }
204        if (mAudio != null) {
205            mAudio.start();
206        }
207    }
208
209    /**
210     * Stops a playing ringtone.
211     */
212    public void stop() {
213        if (mAudio != null) {
214            mAudio.reset();
215            mAudio.release();
216            mAudio = null;
217        }
218    }
219
220    /**
221     * Whether this ringtone is currently playing.
222     *
223     * @return True if playing, false otherwise.
224     */
225    public boolean isPlaying() {
226        return mAudio != null && mAudio.isPlaying();
227    }
228
229    void setTitle(String title) {
230        mTitle = title;
231    }
232}
233