/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ringdroid;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import com.feebe.lib.AdsView;
import com.feebe.musicsearch.R;
import com.ringdroid.soundfile.CheapSoundFile;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Main screen that shows up when you launch Ringdroid. Handles selecting
* an audio file or using an intent to record a new one, and then
* launches RingdroidEditActivity from here.
*/
public class RingdroidSelectActivity
extends ListActivity
implements TextWatcher
{
private TextView mFilter;
private SimpleCursorAdapter mAdapter;
private boolean mWasGetContentIntent;
private boolean mShowAll;
// Result codes
private static final int REQUEST_CODE_EDIT = 1;
// Menu commands
private static final int CMD_SHOW_ALL = 2;
// Context menu
private static final int CMD_EDIT = 3;
private static final int CMD_DELETE = 4;
public RingdroidSelectActivity() {
}
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mShowAll = false;
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
showFinalAlert(getResources().getText(R.string.sdcard_readonly));
return;
}
if (status.equals(Environment.MEDIA_SHARED)) {
showFinalAlert(getResources().getText(R.string.sdcard_shared));
return;
}
if (!status.equals(Environment.MEDIA_MOUNTED)) {
showFinalAlert(getResources().getText(R.string.no_sdcard));
return;
}
Intent intent = getIntent();
String action = intent.getAction();
mWasGetContentIntent = action != null && action.equals(
Intent.ACTION_GET_CONTENT);
// Inflate our UI from its XML layout description.
setContentView(R.layout.media_select);
AdsView.createQWAd(this);
Button recordButton = (Button) findViewById(R.id.record);
recordButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View clickedButton) {
onRecord();
}
});
try {
mAdapter = new SimpleCursorAdapter(
this,
// Use a template that displays a text view
R.layout.media_select_row,
// Give the cursor to the list adatper
createCursor(""),
// Map from database columns...
new String[] {
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media._ID },
// To widget ids in the row layout...
new int[] {
R.id.row_artist,
R.id.row_album,
R.id.row_title,
R.id.row_icon });
setListAdapter(mAdapter);
// Normal click - open the editor
getListView().setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent,
View view,
int position,
long id) {
startRingdroidEditor();
}
});
} catch (SecurityException e) {
// No permission to retrieve audio?
// Log.e("Ringdroid", e.toString());
// todo error 1
} catch (IllegalArgumentException e) {
// No permission to retrieve audio?
// Log.e("Ringdroid", e.toString());
// todo error 2
}
mAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view,
Cursor cursor,
int columnIndex) {
if (view.getId() == R.id.row_icon) {
setSoundIconFromCursor((ImageView) view, cursor);
return true;
}
return false;
}
});
// Long-press opens a context menu
registerForContextMenu(getListView());
mFilter = (TextView) findViewById(R.id.search_filter);
if (mFilter != null) {
mFilter.addTextChangedListener(this);
}
}
private void setSoundIconFromCursor(ImageView view, Cursor cursor) {
// TODO: isOurDownload use different color, or even rank on top
if (0 != cursor.getInt(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_RINGTONE))) {
view.setImageResource(R.drawable.type_ringtone);
((View) view.getParent()).setBackgroundColor(
getResources().getColor(R.drawable.type_bkgnd_ringtone));
} else if (0 != cursor.getInt(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_ALARM))) {
view.setImageResource(android.R.drawable.ic_dialog_alert);
((View) view.getParent()).setBackgroundColor(
getResources().getColor(R.drawable.type_bkgnd_alarm));
} else if (0 != cursor.getInt(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_NOTIFICATION))) {
view.setImageResource(android.R.drawable.ic_notification_overlay);
((View) view.getParent()).setBackgroundColor(
getResources().getColor(R.drawable.type_bkgnd_notification));
} else if (0 != cursor.getInt(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.IS_MUSIC))) {
view.setImageResource(R.drawable.type_music);
((View) view.getParent()).setBackgroundColor(
getResources().getColor(R.drawable.type_bkgnd_music));
}
String filename = cursor.getString(cursor.getColumnIndexOrThrow(
MediaStore.Audio.Media.DATA));
if (!CheapSoundFile.isFilenameSupported(filename)) {
((View) view.getParent()).setBackgroundColor(
getResources().getColor(R.drawable.type_bkgnd_unsupported));
}
}
/** Called with an Activity we started with an Intent returns. */
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent dataIntent) {
if (requestCode != REQUEST_CODE_EDIT) {
return;
}
if (resultCode != RESULT_OK) {
return;
}
setResult(RESULT_OK, dataIntent);
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuItem item;
item = menu.add(0, CMD_SHOW_ALL, 0, R.string.menu_show_all_audio);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(CMD_SHOW_ALL).setVisible(true);
menu.findItem(CMD_SHOW_ALL).setEnabled(!mShowAll);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CMD_SHOW_ALL:
mShowAll = true;
refreshListView();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onCreateContextMenu(ContextMenu menu,
View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
Cursor c = mAdapter.getCursor();
String title = c.getString(c.getColumnIndexOrThrow(
MediaStore.Audio.Media.TITLE));
menu.setHeaderTitle(title);
menu.add(0, CMD_EDIT, 0, R.string.context_menu_edit);
menu.add(0, CMD_DELETE, 0, R.string.context_menu_delete);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CMD_EDIT:
startRingdroidEditor();
return true;
case CMD_DELETE:
onDelete();
return true;
default:
return super.onContextItemSelected(item);
}
}
private void onDelete() {
Cursor c = mAdapter.getCursor();
int dataIndex = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
String filename = c.getString(dataIndex);
int uriIndex = c.getColumnIndex(
"\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "\"");
if (uriIndex == -1) {
uriIndex = c.getColumnIndex(
"\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"");
}
if (uriIndex == -1) {
showFinalAlert(getResources().getText(R.string.delete_failed));
return;
}
if (!new File(filename).delete()) {
showAlert(getResources().getText(R.string.delete_failed));
}
String itemUri = c.getString(uriIndex) + "/" +
c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
getContentResolver().delete(Uri.parse(itemUri), null, null);
}
private void showAlert(CharSequence message) {
new AlertDialog.Builder(RingdroidSelectActivity.this)
.setTitle(getResources().getText(R.string.alert_title_failure))
.setMessage(message)
.setPositiveButton(
R.string.alert_ok_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
}
})
.setCancelable(false)
.show();
}
private void showFinalAlert(CharSequence message) {
new AlertDialog.Builder(RingdroidSelectActivity.this)
.setTitle(getResources().getText(R.string.alert_title_failure))
.setMessage(message)
.setPositiveButton(
R.string.alert_ok_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
finish();
}
})
.setCancelable(false)
.show();
}
private void onRecord() {
try {
Intent intent = new Intent(Intent.ACTION_EDIT,
Uri.parse("record"));
intent.putExtra("was_get_content_intent",
mWasGetContentIntent);
intent.setClassName(
"com.feebe.rings",
"com.ringdroid.RingdroidEditActivity");
startActivityForResult(intent, REQUEST_CODE_EDIT);
} catch (Exception e) {
// Log.e("Ringdroid", "Couldn't start editor");
}
}
private void startRingdroidEditor() {
Cursor c = mAdapter.getCursor();
int dataIndex = c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
String filename = c.getString(dataIndex);
startPureEditor(filename);
}
private void startPureEditor(String filename) {
Intent intent = new Intent(Intent.ACTION_EDIT,
Uri.parse(filename));
intent.putExtra("was_get_content_intent",
mWasGetContentIntent);
intent.setClassName(
"com.feebe.rings",
"com.ringdroid.RingdroidEditActivity");
startActivityForResult(intent, REQUEST_CODE_EDIT);
}
private Cursor getInternalAudioCursor(String selection,
String[] selectionArgs) {
return managedQuery(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI,
INTERNAL_COLUMNS,
selection,
selectionArgs,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
}
private Cursor getExternalAudioCursor(String selection,
String[] selectionArgs) {
return managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
EXTERNAL_COLUMNS,
selection,
selectionArgs,
MediaStore.Audio.Media.DATE_ADDED + " DESC");
}
Cursor createCursor(String filter) {
ArrayList<String> args = new ArrayList<String>();
String selection;
if (mShowAll) {
selection = "(_DATA LIKE ?)";
args.add("%");
} else {
selection = "(";
for (String extension : CheapSoundFile.getSupportedExtensions()) {
args.add("%." + extension);
if (selection.length() > 1) {
selection += " OR ";
}
selection += "(_DATA LIKE ?)";
}
selection += ")";
selection = "(" + selection + ") AND (_DATA NOT LIKE ?)";
args.add("%espeak-data/scratch%");
}
if (filter != null && filter.length() > 0) {
filter = "%" + filter + "%";
selection =
"(" + selection + " AND " +
"((TITLE LIKE ?) OR (ARTIST LIKE ?) OR (ALBUM LIKE ?)))";
args.add(filter);
args.add(filter);
args.add(filter);
}
String[] argsArray = args.toArray(new String[args.size()]);
Cursor c = new MergeCursor(new Cursor[] {
getExternalAudioCursor(selection, argsArray),
getInternalAudioCursor(selection, argsArray)});
startManagingCursor(c);
return c;
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s,
int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
refreshListView();
}
private void refreshListView() {
String filterStr = mFilter.getText().toString();
mAdapter.changeCursor(createCursor(filterStr));
}
private static final String[] INTERNAL_COLUMNS = new String[] {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.IS_RINGTONE,
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.IS_NOTIFICATION,
MediaStore.Audio.Media.IS_MUSIC,
"\"" + MediaStore.Audio.Media.INTERNAL_CONTENT_URI + "\""
};
private static final String[] EXTERNAL_COLUMNS = new String[] {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.IS_RINGTONE,
MediaStore.Audio.Media.IS_ALARM,
MediaStore.Audio.Media.IS_NOTIFICATION,
MediaStore.Audio.Media.IS_MUSIC,
"\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\""
};
}