2012-12-03 67 views
2

我是Android開發的新手,我正在使用Onur Cinar的書「Android應用程序與Eclipse」開始。顯示電影文件的縮略圖

我已完成開發MoviePlayer應用程序的第6章(源代碼:http://www.apress.com/9781430244349),但是當在手機上運行應用程序時,我無法看到列出的電影的任何縮略圖。當我使用手機錄製新電影時,新電影將添加到電影列表中,默認綠色Android圖標作爲縮略圖,而原始電影仍然沒有縮略圖圖標。

我的代碼似乎與給定的源代碼相匹配。本書中給出的代碼是否有問題或者是這種預期的行爲?如果是後者,在什麼情況下會在電影列表中顯示(非默認)縮略圖圖標?

Movie.java:

package com.apress.movieplayer; 

import android.database.Cursor; 
import android.provider.MediaStore; 

/** 
* Movie file meta data. 
* 
* @author Josh 
*/ 
public class Movie 
{ 
/** Movie title */ 
private final String title; 

/** Movie file */ 
private final String moviePath; 

/** MIME type */ 
private final String mimeType; 

/** Movie duration in ms */ 
private final long duration; 

/** Thumbnail file */ 
private final String thumbnailPath; 

/** 
* Constructor. 
* 
* @param mediaCursor media cursor. 
* @param thumbnailCursor thumbnail cursor. 
*/ 
public Movie(Cursor mediaCursor, Cursor thumbnailCursor) 
{ 
    title = mediaCursor.getString(mediaCursor.getColumnIndexOrThrow(
      MediaStore.Video.Media.TITLE)); 

    moviePath = mediaCursor.getString(mediaCursor.getColumnIndex(
      MediaStore.Video.Media.DATA)); 

    mimeType = mediaCursor.getString(mediaCursor.getColumnIndex(
      MediaStore.Video.Media.MIME_TYPE)); 

    duration = mediaCursor.getLong(mediaCursor.getColumnIndex(
      MediaStore.Video.Media.DURATION)); 

    if ((thumbnailCursor != null) && thumbnailCursor.moveToFirst()) 
    { 
     thumbnailPath = thumbnailCursor.getString(
       thumbnailCursor.getColumnIndex(
         MediaStore.Video.Thumbnails.DATA)); 
    } 
    else 
    { 
     thumbnailPath = null; 
    } 
} 

/** 
* Get the movie title. 
* 
* @return movie title. 
*/ 
public String getTitle() { 
    return title; 
} 

/** 
* Get the movie path. 
* 
* @return movie path. 
*/ 
public String getMoviePath() { 
    return moviePath; 
} 

/** 
* Get the MIME type. 
* 
* @return MIME type. 
*/ 
public String getMimeType() { 
    return mimeType; 
} 

/** 
* Get the movie duration. 
* 
* @return movie duration. 
*/ 
public long getDuration() { 
    return duration; 
} 

/** 
* Get the thumbnail path. 
* 
* @return thumbnail path. 
*/ 
public String getThumbnailPath() { 
    return thumbnailPath; 
} 

/* 
* @see java.lang.Object#toString() 
*/ 
@Override 
public String toString() 
{ 
    return "Movie [title=" + title + ", moviePath=" + moviePath 
      + ", mimeType=" + mimeType + ", duration=" + duration 
      + ", thumbnailPath=" + thumbnailPath + "]"; 
} 
} 

MovieListAdapter.java:

package com.apress.movieplayer; 

import java.util.ArrayList; 

import android.content.Context; 
import android.net.Uri; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 

/** 
* Movie list view adapter. 
* 
* @author Josh 
*/ 
public class MovieListAdapter extends BaseAdapter 
{ 
/** Context instance */ 
private final Context context; 

/** Movie list */ 
private final ArrayList<Movie> movieList; 

/** 
* Constructor. 
* 
* @param context context instance. 
* @param movieList movie list. 
*/ 
public MovieListAdapter(Context context, ArrayList<Movie> movieList) 
{ 
    this.context = context; 
    this.movieList = movieList; 
} 

/** 
* Gets the number of elements in movie list. 
* 
* @see BaseAdapter#getCount() 
*/ 
public int getCount() { 
    return movieList.size(); 
} 

/** 
* Gets the movie item at given position. 
* 
* @param position item position. 
* @see BaseAdapter#getItem(int) 
*/ 
public Object getItem(int position) { 
    return movieList.get(position); 
} 

/** 
* Gets the movie id at given position. 
* 
* @param position item position. 
* @return movie id. 
* @see BaseAdapter#getItemId(int) 
*/ 
public long getItemId(int position) { 
    return position; 
} 

/** 
* Gets the item view for given position. 
* 
* @param position item position. 
* @param convertView existing view to use. 
* @param parent parent view to use. 
*/ 
public View getView(int position, View convertView, ViewGroup parent) { 
    // check if convert view exists or inflate the layout 
    if (convertView == null) 
    { 
     LayoutInflater layoutInflater = (LayoutInflater) 
       context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = layoutInflater.inflate(R.layout.movie_item, null); 
    } 

    // Get the movie at given position 
    Movie movie = (Movie) getItem(position); 

    // Set thumbnail 
    ImageView thumbnail = (ImageView) convertView.findViewById(
      R.id.thumbnail); 

    if (movie.getThumbnailPath() != null) 
    { 
     thumbnail.setImageURI(Uri.parse(movie.getThumbnailPath())); 
    } 
    else 
    { 
     thumbnail.setImageResource(R.drawable.ic_launcher); 
    } 

    // Set title 
    TextView title = (TextView) convertView.findViewById(R.id.title); 
    title.setText(movie.getTitle()); 

    // Set duration 
    TextView duration = (TextView) convertView.findViewById(R.id.duration); 
    duration.setText(getDurationAsString(movie.getDuration())); 

    return convertView; 
} 

private static String getDurationAsString(long duration) 
{ 
    // Calculate milliseconds 
    long milliseconds = duration % 1000; 
    long seconds = duration/1000; 

    // Calculate seconds 
    long minutes = seconds/60; 
    seconds %= 60; 

    // Calculate hours and minutes 
    long hours = minutes/60; 
    minutes %= 60; 

    // Build the duration string 
    String durationString = String.format("%1$02d:%2$02d:%3$02d.%4$03d", 
      hours, minutes, seconds, milliseconds); 

    return durationString; 
} 

} 

MoviePlayerActivity.java:

package com.apress.movieplayer; 

import java.util.ArrayList; 

import android.app.Activity; 
import android.content.Intent; 
import android.database.Cursor; 
import android.net.Uri; 
import android.os.Bundle; 
import android.provider.MediaStore; 
import android.util.Log; 
//import android.view.Menu; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ListView; 

/** 
* Movie Player. 
* 
* @author Josh 
* 
*/ 
public class MoviePlayerActivity extends Activity implements OnItemClickListener 
{ 
/** Log tag. */ 
private static final String LOG_TAG = "MoviePlayer"; 


/** 
* On create lifecycle method. 
* 
* @param savedInstanceState saved state. 
* @see Activity#onCreate(Bundle) 
*/ 
@Override 
    protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_movie_player); 

    ArrayList<Movie> movieList = new ArrayList<Movie>(); 

    // Media columns to query 
    String[] mediaColumns = { 
      MediaStore.Video.Media._ID, 
      MediaStore.Video.Media.TITLE, 
      MediaStore.Video.Media.DURATION, 
      MediaStore.Video.Media.DATA, 
      MediaStore.Video.Media.MIME_TYPE }; 

    // Thumbnail columns to query 
    String[] thumbnailColumns = { MediaStore.Video.Thumbnails.DATA }; 

    // Query external movie content for selected media columns 
    Cursor mediaCursor = getContentResolver().query(
      MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 
      mediaColumns, null, null, null); 

      /*managedQuery(
      MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaColumns, 
      null, null, null);*/ 

    // Loop through media results 
    if ((mediaCursor != null) && mediaCursor.moveToFirst()) 
    { 
     do 
     { 
      // Get the video id 
      int id = mediaCursor.getInt(mediaCursor 
        .getColumnIndex(MediaStore.Video.Media._ID)); 

      // Get the thumbnail associated with the video 
      Cursor thumbnailCursor = getContentResolver().query(
        MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, 
        thumbnailColumns, MediaStore.Video.Thumbnails.VIDEO_ID 
         + "=" + id, null, null); 

        /*managedQuery(
        MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, 
        thumbnailColumns, MediaStore.Video.Thumbnails.VIDEO_ID 
          + "=" + id, null, null);*/ 

      // New movie object from the data 
      Movie movie = new Movie(mediaCursor, thumbnailCursor); 
      Log.d(LOG_TAG, movie.toString()); 

      // Add to movie list 
      movieList.add(movie); 

     } 
     while (mediaCursor.moveToNext()); 
    } 

    // Define movie list adapter 
    MovieListAdapter movieListAdapter = new MovieListAdapter(this, 
      movieList); 

    // Set list view adapter to movie list adapter 
    ListView movieListView = (ListView) findViewById(R.id.movieListView); 
    movieListView.setAdapter(movieListAdapter); 

    // Set item click listener 
    movieListView.setOnItemClickListener(this); 
} 

@Override 
/*public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.activity_movie_player, menu); 
    return true; 
}*/ 

    /** 
    * On item click listener. 
    */ 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
    { 
     // Gets the selected movie 
     Movie movie = (Movie) parent.getAdapter().getItem(position); 

     // Plays the selected movie 
     Intent intent = new Intent(Intent.ACTION_VIEW); 
     intent.setDataAndType(Uri.parse(movie.getMoviePath()), movie.getMimeType()); 
     startActivity(intent); 
    } 
} 

activity_movie_player.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <ListView 
     android:id="@+id/movieListView" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 
    </ListView> 
</LinearLayout> 

movie_item.xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

<ImageView 
    android:contentDescription="@string/thumbnail_description" 
    android:id="@+id/thumbnail" 
    android:layout_width="64dp" 
    android:layout_height="64dp" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentTop="true" 
    android:layout_marginRight="16dp" 
    android:src="@drawable/ic_launcher" /> 
<TextView 
    android:id="@+id/title" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignTop="@+id/thumbnail" 
    android:layout_toRightOf="@+id/thumbnail" 
    android:text="@string/large_text" 
    android:textAppearance="?android:attr/textAppearanceLarge" /> 

<TextView 
    android:id="@+id/duration" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignLeft="@+id/title" 
    android:layout_below="@+id/title" 
    android:text="@string/small_text" 
    android:textAppearance="?android:attr/textAppearanceSmall" /> 

</RelativeLayout> 
+0

你在哪個版本(2.2及以下版本不支持縮略圖)?你在哪裏存儲你的文件(內部存儲或SD卡)? – znat

+0

我的手機使用的是Android 4.0.3版本,所有電影文件都存儲在SD卡上。 – Josh

+0

如果您顯示您的代碼,我們可能會幫助您更好 – znat

回答

0

鑑於代碼,看來這是Android OS的正常功能。一旦視頻被其他視頻播放應用程序打開,看起來好像縮略圖是在這些更復雜的程序中生成的,並可供其他應用程序(包括此演示電影播放器​​應用程序)使用。

如果有人能詳細說明這個實際的「幕後」工作,我會很高興,因爲我的分析有點黑匣子。