1 /* 2 * Copyright (C) 2007 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 17 package com.android.development; 18 19 import android.app.Activity; 20 import android.content.ContentResolver; 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.content.BroadcastReceiver; 26 import android.database.sqlite.SQLiteConstraintException; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.os.Environment; 30 import android.os.Handler; 31 import android.os.Message; 32 import android.provider.MediaStore; 33 import android.provider.MediaStore.Audio; 34 import android.text.Editable; 35 import android.text.TextWatcher; 36 import android.util.Log; 37 import android.view.View; 38 import android.widget.Button; 39 import android.widget.EditText; 40 import android.widget.TextView; 41 42 import java.util.Random; 43 44 public class MediaScannerActivity extends Activity 45 { 46 private TextView mTitle; 47 private int mNumToInsert = 20; 48 private int mArtists; 49 private int mAlbums; 50 private int mSongs; 51 private ContentResolver mResolver; 52 private Uri mAudioUri; 53 ContentValues mValues[] = new ContentValues[10]; 54 Random mRandom = new Random(); 55 StringBuilder mBuilder = new StringBuilder(); 56 MediaScannerActivity()57 public MediaScannerActivity() { 58 } 59 60 /** Called when the activity is first created or resumed. */ 61 @Override onCreate(Bundle icicle)62 public void onCreate(Bundle icicle) { 63 super.onCreate(icicle); 64 65 setContentView(R.layout.media_scanner_activity); 66 67 IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED); 68 intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 69 intentFilter.addDataScheme("file"); 70 registerReceiver(mReceiver, intentFilter); 71 72 EditText t = (EditText) findViewById(R.id.numsongs); 73 t.addTextChangedListener(new TextWatcher() { 74 75 public void afterTextChanged(Editable s) { 76 String text = s.toString(); 77 try { 78 mNumToInsert = Integer.valueOf(text); 79 } catch (NumberFormatException ex) { 80 mNumToInsert = 20; 81 } 82 setInsertButtonText(); 83 } 84 85 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 86 } 87 88 public void onTextChanged(CharSequence s, int start, int before, int count) { 89 } 90 91 }); 92 mTitle = (TextView) findViewById(R.id.title); 93 mResolver = getContentResolver(); 94 mAudioUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 95 96 for (int i = 0; i < 10; i++) { 97 mValues[i] = new ContentValues(); 98 } 99 setInsertButtonText(); 100 } 101 102 /** Called when the activity going into the background or being destroyed. */ 103 @Override onDestroy()104 public void onDestroy() { 105 unregisterReceiver(mReceiver); 106 mInsertHandler.removeMessages(0); 107 super.onDestroy(); 108 } 109 110 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 111 @Override 112 public void onReceive(Context context, Intent intent) { 113 if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 114 mTitle.setText("Media Scanner started scanning " + intent.getData().getPath()); 115 } 116 else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 117 mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath()); 118 } 119 } 120 }; 121 startScan(View v)122 public void startScan(View v) { 123 sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" 124 + Environment.getExternalStorageDirectory()))); 125 126 mTitle.setText("Sent ACTION_MEDIA_MOUNTED to trigger the Media Scanner."); 127 } 128 setInsertButtonText()129 private void setInsertButtonText() { 130 String label = getString(R.string.insertbutton, Integer.valueOf(mNumToInsert)); 131 Button b = (Button) findViewById(R.id.insertbutton); 132 b.setText(label); 133 } 134 135 insertItems(View v)136 public void insertItems(View v) { 137 if (mInsertHandler.hasMessages(0)) { 138 mInsertHandler.removeMessages(0); 139 setInsertButtonText(); 140 } else { 141 mInsertHandler.sendEmptyMessage(0); 142 } 143 } 144 145 Handler mInsertHandler = new Handler() { 146 @Override 147 public void handleMessage(Message msg) { 148 149 if (mNumToInsert-- > 0) { 150 addAlbum(); 151 runOnUiThread(mDisplayUpdater); 152 153 if (!isFinishing()) { 154 sendEmptyMessage(0); 155 } 156 } 157 } 158 }; 159 160 Runnable mDisplayUpdater = new Runnable() { 161 public void run() { 162 mTitle.setText("Added " + mArtists + " artists, " + mAlbums + " albums, " 163 + mSongs + " songs."); 164 } 165 }; 166 167 // Add one more album (with 10 songs) to the database. This will be a compilation album, 168 // with one album artist for the album, and a separate artist for each song. addAlbum()169 private void addAlbum() { 170 try { 171 String albumArtist = "Various Artists"; 172 String albumName = getRandomWord(3); 173 int baseYear = 1969 + mRandom.nextInt(30); 174 for (int i = 0; i < 10; i++) { 175 mValues[i].clear(); 176 String artist = getRandomName(); 177 final ContentValues map = mValues[i]; 178 map.put(MediaStore.MediaColumns.DATA, 179 "http://bogus/" + albumName + "/" + artist + "_" + i); 180 map.put(MediaStore.MediaColumns.TITLE, 181 getRandomWord(4) + " " + getRandomWord(2) + " " + (i + 1)); 182 map.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3"); 183 184 map.put(Audio.Media.ARTIST, artist); 185 map.put("album_artist", albumArtist); 186 map.put(Audio.Media.ALBUM, albumName); 187 map.put(Audio.Media.TRACK, i + 1); 188 map.put(Audio.Media.DURATION, 4*60*1000); 189 map.put(Audio.Media.IS_MUSIC, 1); 190 map.put(Audio.Media.YEAR, baseYear + mRandom.nextInt(10)); 191 } 192 mResolver.bulkInsert(mAudioUri, mValues); 193 mSongs += 10; 194 mAlbums++; 195 mArtists += 11; 196 } catch (SQLiteConstraintException ex) { 197 Log.d("@@@@", "insert failed", ex); 198 } 199 } 200 201 /** 202 * Some code to generate random names. This just strings together random 203 * syllables, and randomly inserts a modifier between the first 204 * and last name. 205 */ 206 private String[] elements = new String[] { 207 "ab", "am", 208 "bra", "bri", 209 "ci", "co", 210 "de", "di", "do", 211 "fa", "fi", 212 "ki", 213 "la", "li", 214 "ma", "me", "mi", "mo", 215 "na", "ni", 216 "pa", 217 "ta", "ti", 218 "vi", "vo" 219 }; 220 getRandomWord(int len)221 private String getRandomWord(int len) { 222 int max = elements.length; 223 mBuilder.setLength(0); 224 for (int i = 0; i < len; i++) { 225 mBuilder.append(elements[mRandom.nextInt(max)]); 226 } 227 char c = mBuilder.charAt(0); 228 c = Character.toUpperCase(c); 229 mBuilder.setCharAt(0, c); 230 return mBuilder.toString(); 231 } 232 getRandomName()233 private String getRandomName() { 234 boolean longfirst = mRandom.nextInt(5) < 3; 235 String first = getRandomWord(longfirst ? 3 : 2); 236 String last = getRandomWord(3); 237 switch (mRandom.nextInt(6)) { 238 case 1: 239 if (!last.startsWith("Di")) { 240 last = "di " + last; 241 } 242 break; 243 case 2: 244 last = "van " + last; 245 break; 246 case 3: 247 last = "de " + last; 248 break; 249 } 250 return first + " " + last; 251 } 252 253 254 255 } 256