|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<item |
|||
android:state_pressed="false" |
|||
android:drawable="@drawable/header_browser" /> |
|||
<item |
|||
android:state_pressed="true" |
|||
android:drawable="@drawable/header_browser_pressed" /> |
|||
</selector> |
|||
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<item |
|||
android:state_pressed="false" |
|||
android:drawable="@drawable/header_playlist" /> |
|||
<item |
|||
android:state_pressed="true" |
|||
android:drawable="@drawable/header_playlist_pressed" /> |
|||
</selector> |
|||
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<item |
|||
android:state_pressed="false" |
|||
android:drawable="@drawable/header_loupe" /> |
|||
<item |
|||
android:state_pressed="true" |
|||
android:drawable="@drawable/header_loupe_pressed" /> |
|||
</selector> |
|||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout |
|||
xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="fill_parent" |
|||
android:gravity="center"> |
|||
<TextView |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="About"/> |
|||
</LinearLayout> |
|||
@ -0,0 +1,45 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout |
|||
xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:orientation="vertical" |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="fill_parent"> |
|||
<LinearLayout |
|||
android:background="@drawable/header" |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="48dip" |
|||
android:orientation="horizontal"> |
|||
<ImageView |
|||
android:src="@drawable/header_logo" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="48dip" |
|||
android:scaleType="fitStart" |
|||
android:paddingLeft="12dip"/> |
|||
<View |
|||
android:layout_width="0dip" |
|||
android:layout_height="wrap_content" |
|||
android:layout_weight="1"/> |
|||
<ProgressBar |
|||
android:id="@+id/ml_progress_bar" |
|||
android:layout_width="22dip" |
|||
android:layout_height="22dip" |
|||
android:layout_margin="13dip" |
|||
android:visibility="invisible"/> |
|||
<ImageButton |
|||
android:id="@+id/ml_header_button_view" |
|||
android:background="@drawable/header_button_playlist" |
|||
android:layout_width="48dip" |
|||
android:layout_height="48dip" |
|||
android:onClick="changeView"/> |
|||
<ImageButton |
|||
android:layout_width="48dip" |
|||
android:layout_height="48dip" |
|||
android:background="@drawable/header_button_search" |
|||
android:onClick="search"/> |
|||
</LinearLayout> |
|||
<ListView |
|||
android:id="@+id/ml_list" |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="0dip" |
|||
android:layout_weight="1"/> |
|||
</LinearLayout> |
|||
@ -0,0 +1,10 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout |
|||
xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="match_parent"> |
|||
<TextView |
|||
android:id="@+id/ml_item_title" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content"/> |
|||
</LinearLayout> |
|||
@ -0,0 +1,10 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<FrameLayout |
|||
xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="fill_parent"> |
|||
<android.opengl.GLSurfaceView |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="fill_parent" |
|||
android:id="@+id/player_surface_view"/> |
|||
</FrameLayout> |
|||
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout |
|||
xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:layout_width="fill_parent" |
|||
android:layout_height="fill_parent"> |
|||
</LinearLayout> |
|||
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<item android:id="@+id/ml_menu_about" android:icon="@android:drawable/ic_menu_info_details" android:title="@string/about"></item> |
|||
|
|||
<item android:title="@string/preferences" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/ml_menu_preferences"></item> |
|||
</menu> |
|||
@ -0,0 +1,4 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<PreferenceScreen |
|||
xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
</PreferenceScreen> |
|||
@ -0,0 +1,4 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<searchable xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:hint="blub" android:label="VLC"> |
|||
</searchable> |
|||
@ -0,0 +1,18 @@ |
|||
package vlc.android; |
|||
|
|||
import android.app.Activity; |
|||
import android.os.Bundle; |
|||
|
|||
public class AboutActivity extends Activity { |
|||
|
|||
public final static String TAG = "VLC/AboutActivity"; |
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
setContentView(R.layout.about); |
|||
super.onCreate(savedInstanceState); |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
package vlc.android; |
|||
|
|||
public class Constants { |
|||
|
|||
private Constants() { } |
|||
|
|||
public final static String[] EXTENTIONS = {".3gp", ".asf", ".wmv", ".au", |
|||
".avi", ".flv", ".mov", ".mp4", ".ogm", ".ogg", ".mkv", ".mka", ".ts", |
|||
".mpg", ".mp3", ".mp2", ".nsc", ".nsv", ".nut", ".ra", ".ram", ".rm", |
|||
".rv" , ".rmbv", ".a52", ".dts", ".aac", ".flac", ".dv", ".vid", ".tta", |
|||
".tac", ".ty", ".wav", ".dts", ".xa"}; |
|||
|
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
package vlc.android; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import android.content.ContentValues; |
|||
import android.content.Context; |
|||
import android.database.Cursor; |
|||
import android.database.sqlite.SQLiteDatabase; |
|||
import android.database.sqlite.SQLiteOpenHelper; |
|||
|
|||
public class DatabaseManager { |
|||
|
|||
private SQLiteDatabase db; |
|||
private final String DB_NAME = "vlc_database"; |
|||
private final int DB_VERSION = 1; |
|||
|
|||
private final String DIR_TABLE_NAME = "directories_table"; |
|||
private final String DIR_ROW_PATH = "path"; |
|||
|
|||
// TODO: Create database table for items
|
|||
// private final String ITEM_TABLE_NAME = "item_table";
|
|||
// private final String ITEM_ROW_ID = "id";
|
|||
|
|||
|
|||
/** |
|||
* Constructor |
|||
* |
|||
* @param context |
|||
*/ |
|||
public DatabaseManager(Context context) { |
|||
// create or open database
|
|||
DatabaseHelper helper = new DatabaseHelper(context); |
|||
this.db = helper.getWritableDatabase(); |
|||
} |
|||
|
|||
private class DatabaseHelper extends SQLiteOpenHelper { |
|||
|
|||
public DatabaseHelper(Context context) { |
|||
super(context, DB_NAME, null, DB_VERSION); |
|||
} |
|||
|
|||
@Override |
|||
public void onCreate(SQLiteDatabase db) { |
|||
|
|||
String createTabelQuery = |
|||
"CREATE TABLE " + DIR_TABLE_NAME + " (" + |
|||
DIR_ROW_PATH + " TEXT PRIMARY KEY NOT NULL);"; |
|||
|
|||
// Create the directories table
|
|||
db.execSQL(createTabelQuery); |
|||
} |
|||
|
|||
@Override |
|||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { |
|||
// TODO ??
|
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
/** |
|||
* Add path to the directories table |
|||
* |
|||
* @param path |
|||
*/ |
|||
public void addPath(String path) { |
|||
ContentValues values = new ContentValues(); |
|||
values.put(DIR_ROW_PATH, path); |
|||
db.insert(DIR_TABLE_NAME, null, values); // -1 if already exists
|
|||
} |
|||
|
|||
/** |
|||
* Delete path from directories table |
|||
* |
|||
* @param path |
|||
*/ |
|||
public void removePath(String path) { |
|||
db.delete(DIR_TABLE_NAME, DIR_ROW_PATH + "=" + path, null); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @return |
|||
*/ |
|||
public List<String> getPaths() { |
|||
|
|||
List<String> paths = new ArrayList<String>(); |
|||
Cursor cursor; |
|||
|
|||
cursor = db.query( |
|||
DIR_TABLE_NAME, |
|||
new String[] { DIR_ROW_PATH }, |
|||
null, null, null, null, null); |
|||
cursor.moveToFirst(); |
|||
if (!cursor.isAfterLast()) { |
|||
do { |
|||
paths.add(cursor.getString(0)); |
|||
} while (cursor.moveToNext()); |
|||
} |
|||
|
|||
return paths; |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
package vlc.android; |
|||
|
|||
import java.io.File; |
|||
|
|||
import android.graphics.Bitmap; |
|||
|
|||
public class MediaItem implements Comparable<MediaItem> { |
|||
|
|||
public final static String TAG = "VLC/MediaItem"; |
|||
|
|||
private Bitmap thumbnail; |
|||
private File file; |
|||
|
|||
public MediaItem(File file) { |
|||
this.file = file; |
|||
// mThumbnailerManager.addJob(this);
|
|||
// thumbnail = BitmapFactory.decodeResource(getResources(),
|
|||
// R.drawable.thumbnail);
|
|||
} |
|||
|
|||
public String getName() { |
|||
return file.getName().substring(0, file.getName().lastIndexOf('.')); |
|||
} |
|||
|
|||
public String getLenght() { |
|||
return "0:21:45"; |
|||
} |
|||
|
|||
public String getFormat() { |
|||
return "608x336"; |
|||
} |
|||
|
|||
public Bitmap getThumbnail() { |
|||
return thumbnail; |
|||
} |
|||
|
|||
public void setThumbnail(Bitmap t) { |
|||
// TODO: save thumbnail on storage
|
|||
thumbnail = t; |
|||
} |
|||
|
|||
public String getPath() { |
|||
return file.getPath(); |
|||
} |
|||
|
|||
/** |
|||
* Compare the filenames to sort items |
|||
*/ |
|||
public int compareTo(MediaItem another) { |
|||
return getName().toUpperCase().compareTo( |
|||
another.getName().toUpperCase()); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,238 @@ |
|||
package vlc.android; |
|||
|
|||
import java.io.File; |
|||
import java.io.FileFilter; |
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.LinkedList; |
|||
import java.util.List; |
|||
import java.util.Queue; |
|||
import java.util.concurrent.BrokenBarrierException; |
|||
import java.util.concurrent.CyclicBarrier; |
|||
|
|||
import android.app.Activity; |
|||
import android.content.Intent; |
|||
import android.content.SharedPreferences; |
|||
import android.os.Bundle; |
|||
import android.os.Environment; |
|||
import android.os.Handler; |
|||
import android.preference.PreferenceManager; |
|||
import android.view.Menu; |
|||
import android.view.MenuInflater; |
|||
import android.view.MenuItem; |
|||
import android.view.View; |
|||
import android.widget.ListView; |
|||
import android.widget.ProgressBar; |
|||
import android.widget.Toast; |
|||
|
|||
public class MediaLibraryActivity extends Activity { |
|||
|
|||
/** |
|||
* TODO: |
|||
* + fill List with media files |
|||
* + onClick events for header buttons |
|||
* + search functionality |
|||
*/ |
|||
public final static String TAG = "VLC/MediaLibraryActivity"; |
|||
|
|||
private final Handler mHandler = new Handler(); |
|||
private final CyclicBarrier mBarrier = new CyclicBarrier(2); |
|||
|
|||
private MediaItem mItemToAdd = null; |
|||
private MediaLibraryAdapter mAdapter; |
|||
private List<MediaItem> mItems = new ArrayList<MediaItem>(); |
|||
private ListView mMediaList; |
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
setContentView(R.layout.media_library); |
|||
super.onCreate(savedInstanceState); |
|||
|
|||
SharedPreferences prefs = |
|||
PreferenceManager.getDefaultSharedPreferences(this); |
|||
|
|||
|
|||
mAdapter = new MediaLibraryAdapter(this, R.layout.media_library_item); |
|||
mMediaList = (ListView)findViewById(R.id.ml_list); |
|||
mMediaList.setAdapter(mAdapter); |
|||
|
|||
/* Firstly, let's check the SD card state */ |
|||
boolean mExternalStorageAvailable = false; |
|||
final String state = Environment.getExternalStorageState(); |
|||
if (Environment.MEDIA_MOUNTED.equals(state)) { |
|||
mExternalStorageAvailable = true; |
|||
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { |
|||
mExternalStorageAvailable = true; |
|||
} |
|||
|
|||
// FIXME Support internal storage as well
|
|||
if (!mExternalStorageAvailable) { |
|||
Util.toaster(R.string.filebrowser_sdfail); |
|||
return; |
|||
} |
|||
|
|||
final File rootDir = Environment.getExternalStorageDirectory(); |
|||
|
|||
/* Load all media files on storage */ |
|||
new Thread(new Runnable() { |
|||
|
|||
private Queue<File> directorys = new LinkedList<File>(); |
|||
|
|||
public void run() { |
|||
directorys.add(rootDir); |
|||
MediaItemFilter mediaFileFilter = new MediaItemFilter(); |
|||
|
|||
while (!directorys.isEmpty()) { |
|||
File dir = directorys.poll(); |
|||
File[] f = null; |
|||
if ((f = dir.listFiles(mediaFileFilter)) != null) { |
|||
|
|||
for (int i = 0; i < f.length; i++) { |
|||
if (f[i].isFile()) { |
|||
mItemToAdd = new MediaItem(f[i]); |
|||
mHandler.post(mAddMediaItem); |
|||
try { |
|||
mBarrier.await(); |
|||
} catch (InterruptedException e) { |
|||
e.printStackTrace(); |
|||
} catch (BrokenBarrierException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} else if (f[i].isDirectory()) { |
|||
directorys.add(f[i]); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
}).start(); |
|||
|
|||
} |
|||
|
|||
/** Create menu from XML |
|||
* TODO: Add images |
|||
*/ |
|||
@Override |
|||
public boolean onCreateOptionsMenu(Menu menu) { |
|||
MenuInflater inflater = getMenuInflater(); |
|||
inflater.inflate(R.menu.media_library, menu); |
|||
return super.onCreateOptionsMenu(menu); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Handle onClick form menu buttons |
|||
*/ |
|||
@Override |
|||
public boolean onOptionsItemSelected(MenuItem item) { |
|||
|
|||
// Intent to start new Activity
|
|||
Intent intent; |
|||
|
|||
// Handle item selection
|
|||
switch (item.getItemId()) { |
|||
// About
|
|||
case R.id.ml_menu_about: |
|||
intent = new Intent(MediaLibraryActivity.this, |
|||
AboutActivity.class); |
|||
MediaLibraryActivity.this.startActivity(intent); |
|||
break; |
|||
// Preferences
|
|||
case R.id.ml_menu_preferences: |
|||
intent = new Intent(MediaLibraryActivity.this, |
|||
PreferencesActivity.class); |
|||
MediaLibraryActivity.this.startActivity(intent); |
|||
break; |
|||
} |
|||
return super.onOptionsItemSelected(item); |
|||
} |
|||
|
|||
/** |
|||
* onClick event from xml |
|||
* @param view |
|||
*/ |
|||
public void changeView(View view) { |
|||
// TODO: implement!! ;)
|
|||
Toast.makeText(this, "not implemented", Toast.LENGTH_LONG).show(); |
|||
} |
|||
|
|||
/** |
|||
* onClick event from xml |
|||
* @param view |
|||
*/ |
|||
public void search(View view) { |
|||
// TODO: implement!! ;)
|
|||
Toast.makeText(this, "not implemented", Toast.LENGTH_LONG).show(); |
|||
} |
|||
|
|||
/** |
|||
* hide progress bar |
|||
*/ |
|||
protected final Runnable mHideProgressBar = new Runnable() { |
|||
|
|||
public void run() { |
|||
ProgressBar pb = (ProgressBar)findViewById(R.id.ml_progress_bar); |
|||
pb.setVisibility(View.INVISIBLE); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* show progress bar |
|||
*/ |
|||
protected final Runnable mShowProgressBar = new Runnable() { |
|||
|
|||
public void run() { |
|||
ProgressBar pb = (ProgressBar)findViewById(R.id.ml_progress_bar); |
|||
pb.setVisibility(View.VISIBLE); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* add items to list |
|||
*/ |
|||
private final Runnable mAddMediaItem = new Runnable() { |
|||
|
|||
public void run() { |
|||
mItems.add(mItemToAdd); |
|||
Collections.sort(mItems); |
|||
int index = mItems.indexOf(mItemToAdd); |
|||
mAdapter.insert(mItemToAdd, index); |
|||
mItemToAdd = null; |
|||
try { |
|||
mBarrier.await(); |
|||
} catch (InterruptedException e) { |
|||
e.printStackTrace(); |
|||
} catch (BrokenBarrierException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Filters all irrelevant files |
|||
*/ |
|||
private class MediaItemFilter implements FileFilter { |
|||
|
|||
// FIXME: save extensions in external database
|
|||
private String[] extensions = Constants.EXTENTIONS; |
|||
|
|||
public boolean accept(File f) { |
|||
boolean accepted = false; |
|||
if (!f.isHidden()) { |
|||
if (f.isDirectory()) { |
|||
accepted = true; |
|||
} else { |
|||
String fileName = f.getName().toLowerCase(); |
|||
int dotIndex = fileName.lastIndexOf("."); |
|||
if (dotIndex != -1) { |
|||
String fileExt = fileName.substring(dotIndex); |
|||
accepted = Arrays.asList(extensions).contains(fileExt); |
|||
} |
|||
} |
|||
} |
|||
return accepted; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
package vlc.android; |
|||
|
|||
import android.content.Context; |
|||
import android.view.LayoutInflater; |
|||
import android.view.View; |
|||
import android.view.ViewGroup; |
|||
import android.widget.ArrayAdapter; |
|||
import android.widget.TextView; |
|||
|
|||
public class MediaLibraryAdapter extends ArrayAdapter<MediaItem> { |
|||
|
|||
public MediaLibraryAdapter(Context context, int textViewResourceId) { |
|||
super(context, textViewResourceId); |
|||
} |
|||
|
|||
/** |
|||
* Display the view of a file browser item. |
|||
*/ |
|||
@Override |
|||
public View getView(int position, View convertView, ViewGroup parent) { |
|||
|
|||
View view = convertView; |
|||
if (view == null){ |
|||
LayoutInflater inflater = (LayoutInflater) this.getContext() |
|||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
|||
view = inflater.inflate(R.layout.media_library_item, |
|||
parent, false); |
|||
} |
|||
|
|||
MediaItem item = getItem(position); |
|||
if ( item != null ) { |
|||
TextView titleTextView = |
|||
(TextView)view.findViewById(R.id.ml_item_title); |
|||
titleTextView.setText(item.getName()); |
|||
} |
|||
|
|||
return view; |
|||
} |
|||
|
|||
} |
|||
|
|||
@ -0,0 +1,16 @@ |
|||
package vlc.android; |
|||
|
|||
import android.app.Activity; |
|||
import android.os.Bundle; |
|||
|
|||
public class PlayerActivity extends Activity { |
|||
|
|||
public final static String TAG = "VLC/PlayerActivity"; |
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
setContentView(R.layout.player); |
|||
super.onCreate(savedInstanceState); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
package vlc.android; |
|||
|
|||
import android.os.Bundle; |
|||
import android.preference.PreferenceActivity; |
|||
|
|||
public class PreferencesActivity extends PreferenceActivity { |
|||
|
|||
public final static String TAG = "VLC/PreferencesActivity"; |
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
super.onCreate(savedInstanceState); |
|||
addPreferencesFromResource(R.xml.preferences); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
|||