2

我是 Android 开发的新手,我正在使用 Onur Cinar 的“Android Apps with Eclipse”一书开始。

我已经完成了开发 MoviePlayer 应用程序的第 6 章(源代码: http: //www.apress.com/9781430244349),但是在我的手机上运行该应用程序时,我无法看到我列出的电影的任何缩略图。当我使用手机录制新电影时,新电影会以默认绿色 Android 图标作为缩略图添加到电影列表中,而原始电影仍然没有缩略图图标。

我的代码似乎与给定源代码的代码相匹配。书中给出的代码有问题还是这是预期的行为?如果是后者,什么情况下(非默认)缩略图图标会出现在电影列表中?

电影.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>

电影项目.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>
4

1 回答 1

0

鉴于代码,这似乎是 Android 操作系统的正常功能。一旦视频被其他视频播放应用程序打开,就好像缩略图是在这些更复杂的程序中生成的,并可供其他应用程序使用(包括这个演示电影播放器​​应用程序)。

如果有人能详细说明这在“幕后”是如何运作的,我会很高兴,因为我的分析有点黑匣子。

于 2012-12-14T21:52:58.883 回答