Unable to load thumbnails into ListView - android

I am currently attempting to make a simple image gallery like the now deprecated Android Gallery. From this gallery the user can also navigate to a simple image editor by selecting an image form the gallery. After a lot of Googling I managed to find a HorizontalListView here which is exactly what I need. Initially I had a lot of success with this by just inserting the images in my folder as compressed bitmaps. Since then however I have found this video from Google I/O in which they create an image gallery and an image editor; similar to what I am attempting to create. There are however two main differences between my app and theirs:
they use a GridView for their gallery and I use the aforementioned HorizontalListView
I am attempting to only load images from a specified target path rather than just all images on the SD card.
So far I am unable to adapt their code to mine as none of the images are loading into my gallery. As with the video I use an AsyncTask to load my thumbnails:
private class ThumbnailAsyncTask extends AsyncTask<Long, Void, Bitmap>
{
//The ImageView we will be adding the thumbnail to
private final ImageView mTarget;
public ThumbnailAsyncTask(ImageView target)
{
mTarget = target;
}
#Override
protected Bitmap doInBackground(Long... params)
{
final long photoID = params[0];
final Bitmap result = MediaStore.Images.Thumbnails.getThumbnail(
getContentResolver(), photoID, MediaStore.Images.Thumbnails.MINI_KIND, null);
return result;
}
#Override
protected void onPreExecute()
{
mTarget.setTag(this);
}
#Override
protected void onPostExecute(Bitmap result)
{
if (mTarget.getTag() == this)
{
mTarget.setImageBitmap(result);
mTarget.setTag(null);
}
}
}
and I am using a CursorAdapter for the images in the gallery:
private class PhotoAdapter extends CursorAdapter
{
public PhotoAdapter(Context context)
{
super(context, null, false);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor)
{
final long photoId = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
/*
* Cancel any pending thumbnail task, since this view is now bound
* to new thumbnail
*/
final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) imageView.getTag();
if (oldTask != null)
oldTask.cancel(false);
/*
* If we arrived here, either cache is disabled or cache miss, so we
* need to kick task to load manually
*/
final ThumbnailAsyncTask task = new ThumbnailAsyncTask(imageView);
imageView.setImageBitmap(null);
imageView.setTag(task);
task.execute(photoId);
}
}
With the following CursorLoader
final LoaderCallbacks<Cursor> mCursorCallbacks = new LoaderCallbacks<Cursor>()
{
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
final String[] columns = {BaseColumns._ID};
return new CursorLoader(NewProjectActivity.this,
Uri.fromFile(new File(mTargetPath)), columns, null, null,
MediaStore.Images.Media.DATE_ADDED + " DESC");
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
mAdapter.swapCursor(null);
}
};
getLoaderManager().initLoader(LOADER_CURSOR, null, mCursorCallbacks);
Any ideas on why none of my images are loading?

The basic problem here is, bindView() method is not waiting for asynctask's result. You need to notify your list view when some of its content get changed.
You can do the following changes.
1) Change task.execute(photoId); to task.execute(photoId).get(); this will force your bindView() method to wait till you get your image. This approach is not advisable but it will help you to understand the exact problem.
OR
2) In onPost() of asynctask, invalidate your list view's old content and try to reload it with new content.
mAdapter.notifyDataSetChanged();
mAdapter.notifyDataSetInvalidated();
OR
3) Personally i will suggest you to finish all network operation first (i.e. fetching images ) by changing your code structure and then after try to set your adapter with the prefetched data. This is not a perfect solution but it worked in my case.

Related

Problem using LoaderManager.LoaderCallbacks<Cursor> with custom RecyclerView.Adapter

I have tried loading the list using the ListView along with LoaderManager.LoaderCallbacks and custom CursorAdapter and it works fine. But I am trying to accomplish the same using RecyclerView along with custom RecyclerView.Adapter but I am getting this issue:
I am getting the list displayed for the first time but when I rotate the device the list disappears.
Here is the code, please have a look.
CatalogActivity
public class CatalogActivity extends AppCompatActivity implements ItemAdapter.OnItemClickListener,
LoaderManager.LoaderCallbacks<Cursor> {
private static final int ITEMS_LOADER_ID = 1;
public static final String EXTRA_ITEM_NAME = "extra_item_name";
public static final String EXTRA_ITEM_STOCK = "extra_item_stock";
#BindView(R.id.list_items)
RecyclerView mListItems;
private ItemAdapter mItemAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);
ButterKnife.bind(this);
setupListItems();
getLoaderManager().initLoader(ITEMS_LOADER_ID, null, this);
}
private void setupListItems() {
mListItems.setHasFixedSize(true);
LayoutManager layoutManager = new LinearLayoutManager(this);
mListItems.setLayoutManager(layoutManager);
mListItems.setItemAnimator(new DefaultItemAnimator());
mListItems.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
mItemAdapter = new ItemAdapter(getApplicationContext(), this);
mListItems.setAdapter(mItemAdapter);
}
#Override
public void OnClickItem(int position) {
Intent intent = new Intent(this, EditorActivity.class);
Item item = mItemAdapter.getItems().get(position);
intent.putExtra(EXTRA_ITEM_NAME, item.getName());
intent.putExtra(EXTRA_ITEM_STOCK, item.getStock());
startActivity(intent);
}
private ArrayList<Item> getItems(Cursor cursor) {
ArrayList<Item> items = new ArrayList<>();
if (cursor != null) {
while (cursor.moveToNext()) {
int columnIndexId = cursor.getColumnIndex(ItemEntry._ID);
int columnIndexName = cursor.getColumnIndex(ItemEntry.COLUMN_NAME);
int columnIndexStock = cursor.getColumnIndex(ItemEntry.COLUMN_STOCK);
int id = cursor.getInt(columnIndexId);
String name = cursor.getString(columnIndexName);
int stock = Integer.parseInt(cursor.getString(columnIndexStock));
items.add(new Item(id, name, stock));
}
}
return items;
}
#Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
switch (loaderId) {
case ITEMS_LOADER_ID: {
String[] projection = {
ItemEntry._ID,
ItemEntry.COLUMN_NAME,
ItemEntry.COLUMN_STOCK
};
return new CursorLoader(
this,
ItemEntry.CONTENT_URI,
projection,
null,
null,
null
);
}
default:
return null;
}
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mItemAdapter.setItems(getItems(cursor));
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}
ItemAdapter
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ItemViewHolder> {
private ArrayList<Item> mItems;
private OnItemClickListener mOnItemClickListener;
private Context mContext;
public ItemAdapter(Context context, OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
mContext = context;
}
public void setItems(ArrayList<Item> items) {
if (items != null) {
mItems = items;
notifyDataSetChanged();
}
}
public ArrayList<Item> getItems() {
return mItems;
}
public interface OnItemClickListener {
void OnClickItem(int position);
}
public class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
#BindView(R.id.tv_item)
TextView tv_item;
#BindView(R.id.tv_stock)
TextView tv_stock;
public ItemViewHolder(#NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int position = getAdapterPosition();
mOnItemClickListener.OnClickItem(position);
}
}
#NonNull
#Override
public ItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_inventory, parent, false);
return new ItemViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ItemViewHolder itemViewHolder, int position) {
final Item item = mItems.get(position);
itemViewHolder.tv_item.setText(item.getName());
itemViewHolder.tv_stock.setText(mContext.getString(R.string.display_stock, item.getStock()));
}
#Override
public int getItemCount() {
if (mItems == null) {
return 0;
} else {
return mItems.size();
}
}
}
I am not able to figure out the extact issue. Please help.
Briefly, the issue here is that, after rotation, you're being handed the same Cursor that you had previously looped over before the rotation, but you're not accounting for its current position.
A Cursor tracks and maintains its own position within its set of records, as I'm sure you've gathered from the various move*() methods it contains. When first created, a Cursor's position will be set to right before the first record; i.e., its position will be set to -1.
When you first start your app, the LoaderManager calls onCreateLoader(), where your CursorLoader is instantiated, and then causes it to load and deliver its Cursor, with the Cursor's position at -1. At this point, the while (cursor.moveToNext()) loop works just as expected, since the first moveToNext() call will move it to the first position (index 0), and then to each available position after that, until the end.
Upon rotation, however, the LoaderManager determines that it already has the requested Loader (determined by ID), which itself sees that it already has the appropriate Cursor loaded, so it just immediately delivers that same Cursor object again. (This is a major feature of the Loader framework – it won't reload resources it already has, regardless of configuration changes.) This is the crux of the issue. That Cursor has been left at the last position to which it was moved before the rotation; i.e., at its end. Consequently, the Cursor cannot moveToNext(), so that while loop just never runs at all, after the initial
onLoadFinished(), before rotation.
The simplest fix, with the given setup, would be to manually reposition the Cursor yourself. For example, in getItems(), change the if to moveToFirst() if the Cursor is not null, and change the while to a do-while, so we don't inadvertently skip over the first record. That is:
if (cursor != null && cursor.moveToFirst()) {
do {
int columnIndexId = cursor.getColumnIndex(ItemEntry._ID);
...
} while (cursor.moveToNext());
}
With this, when that same Cursor object is re-delivered, its position is kinda "reset" to position 0. Since that position is directly on the first record, rather than right before it (remember, initially -1), we change to a do-while, so that the first moveToNext() call doesn't skip the first record in the Cursor.
Notes:
I would mention that it is possible to implement a RecyclerView.Adapter to take a Cursor directly, similar to the old CursorAdapter. In this, the Cursor would necessarily be moved in the onBindViewHolder() method to the correct position for each item, and the separate ArrayList would be unnecessary. It'd take a little effort, but translating CursorAdapter to a RecyclerView.Adapter isn't terribly difficult. Alternatively, there are certainly solutions already available. (For example, possibly, this one, though I cannot vouch for it, atm, I often see a trusted fellow user recommend it often.)
I would also mention that the native Loader framework has been deprecated, in favor of the newer ViewModel/LiveData architecture framework in support libraries. However, it appears that the newest androidx library has its own internal, improved Loader framework which is a simple wrapper around said ViewModel/LiveData setup. This seems to be a nice, easy way to utilize the known Loader constructs while still benefiting from the recent architecture refinements.
Instead of LoaderManager.initLoader() call LoaderManager.restartLoader()

Adding array of Uris into a GridView

When setting an ArrayList of Uris in the gridView, only one item is displayed. Why ?
Adapter:
public class ImageGridAdapter extends BaseAdapter {
private Context mContext;
public ImageGridAdapter(Context c) {
this.mContext = c;
}
#Override
public int getCount() {
try {
return PictureGroupActivity.ALofSelectedImgs.size();
} catch (NullPointerException e) {
return 0;
}
}
#Override
public Object getItem(int position) {
return PictureGroupActivity.ALofSelectedImgs.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(5, 5, 5, 5);
} else {
imageView = (ImageView) convertView;
}
try {
imageView.setImageURI(PictureGroupActivity.ALofSelectedImgs.get(position));
Toast.makeText(mContext.getApplicationContext(), "Idee: " + PictureGroupActivity.ALofSelectedImgs, Toast.LENGTH_SHORT).show();
}catch (NullPointerException e) {}
return imageView;
}
Setting the adapter:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.picture_group_activity_layout);
GridView gridView = (GridView) findViewById(R.id.picture_group_gridView);
gridView.setAdapter(new ImageGridAdapter(this));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(PictureGroupActivity.this, "You clicked " + position, Toast.LENGTH_SHORT).show();
}
});
}
From where I take the Image (After choosing from the phones gallery):
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
selectedImage = data.getData();
ALofSelectedImgs = new ArrayList<Uri>();
ALofSelectedImgs.add(selectedImage);
Intent restart = getIntent();
finish();
startActivity(restart);
}
}
How do I make it add multiple Images into the ArrayList and make them stay there and not overwrite each other ?
There are a few problems that I can see with your approach here.
The simplest solution (changing the least code). Would be to move ALofSelectedImgs = new ArrayList(); from onActivityResult(int, int, Intent) and put it in onCreate(Bundle).
This still won't persist the data between orientation changes or closing the app. You'll get a new empty ArrayList every time onCreate(Bundle) is called.
And I wouldn't recommend using static fields like that. For starters, you can't use ImageGridAdapter with any other Activity or Fragment. You need to pass the List to it, either in the constructor or a setter method. That way you can reuse it more easily.
private Context mContext;
private List<Uri> mUris;
public ImageGridAdapter(Context context, List<Uri> uris) {
super(context);
mContext = context;
mUris = uris;
}
For a better solution... there are many ways to do this. Here's what I'd do:
Create a class extending SQLiteOpenHelper in order to save the selected Uris in an SQLite table. I learned a lot from this tutorial. I probably would not worry with a ContentProvider for something this simple. If you're interested I could pm you a template I use for keeping many tables' columns and other constants in a contract class.
Create an adapter extending SimpleCursorAdapter to create Views from a Cursor containing a query from your SQLite table. This is explained in the above tutorial.
In PhotoGroupActivity, perform a query of your table and initialize the adapter with the Cursor returned in onCreate(Bundle).
In onActivityResult(int, int, Intent) you need to insert the Uri into the SQLite table, then perform another query and give the adapter the new Cursor.
EDIT:
To answer your second question. This didn't occur to me at first, but you'll want to use thumbnails to display in your GridView. Use Bitmap.createScaledBitmap(Bitmap, int, int, boolean) to create the thumbnail. Store the thumbnail in your app's private storage to avoid it going in your gallery, then add the Uri to the thumbnail to your ArrayList. You'll probably want to keep track of the Uri for the full-size image as well for when the user touches the thumbnail.
Try using HashMap with the thumbnail Uri as the key and the full-size Uri as the value.
// Create the HashMap like this:
HashMap<Uri, Uri> uriMap = new HashMap<>();
// You have the main Uri. Get the bitmap, create a thumbnail and store it.
// Add an entry to the HashMap like this:
uriMap.put(thumbnailUri, fullSizeUri);
// To get the list of thumbnail Uris for the adapter:
List<Uri> thumbnailList = new ArrayList<>(uriMap.keySet());
// When user presses an image in GridView, get the relevant full-size
// Uri like this:
fullSizeUri = uriMap.get(thumbnailUri);
EDIT AGAIN:
I looked again and realised I suggested a CursorAdapter and then gave info on how to get a HashMap of the data.
Instead, just add another column to the SQLite table and store both Uris there. When you obtain the Uri and thumbnail Uri, store them both in the table and query the table for the SimpleCursorAdapter.

Images from URL appear and disappear on ListView Scroll

Hello I fill my ListView with a BaseAdapter, here a Download an Image from url, then I set the BitMap result in ImageView inside the xml row.
It works fine, but when I scroll the images appear and disapear in diferent places.
This my Code:
Activity:
public class MyActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
lvData = (ListView) findViewById(R.id.listview1);
AdapterClass adapter = new AdapterClass(this, String[] urls);
lvData.setAdapter(adapter);
}
}
Adapter:
public class PopularAdapter extends BaseAdapter {
private String[] mList;
private LayoutInflater mLayotInflalter;
public PopularAdapter(Context context, String[] list) {
mList = list;
mLayotInflalter = ((Activity) context).getLayoutInflater();
}
#Override
public int getCount() {
return mList.size();
}
#Override
public Object getItem(int position) {
return mList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
WrapperRow wrapper;
if (convertView == null) {
convertView = mLayotInflalter.inflate(R.layout.row, null);
wrapper = new WrapperRow (convertView);
convertView.setTag(wrapper);
} else
wrapper = (WrapperRow ) convertView.getTag();
// //
new DownloadImage(wrapper.getImageView()).execute(mList.[position]);
return convertView;
}
}
Image Downloader Class:
public class DownloadImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Can you help me please? :D
This happens because the views get recycled in a ListView. This answer does a good job of explaining how the recycling mechanism works. Now coming on to your case, whenever getView gets called in your adapter, you are kick starting a new AsyncTask that downloads the image at the given url and sets it in the imageView inside WrapperRow.
Let's see why exactly the views flicker. Consider that you have a wrapper rows - wr1, wr2, wr3 .... wr8 and they get recycled by the listView (i arbitrarily chose to explain with 8 rows. the listView could use less or more). As soon as getView gets called the first time, you inflate a wrapper row (wr1) and then pass it to the AsyncTask which downloads the image & then sets it. Now you scroll through the list and the same process takes place for views wr2 to wr8 and on further scrolling it is time to recycle the views and wr1 comes into play again. You kick start another asyncTask to download the image but you never cleared the imageView (it already holds the first image now) and when the task is done downloading it sets the new image in imageview and this is when you an image disappearing and a new image showing up. When you scroll through the list, you see this happening repeatedly for all the rows!!
You could use any of the libraries like Picasso or UIL, but if you wanna spin up your own implementation remember these things
Don't hold on to strong references of views in asyncTasks (this would prevent the activity instance from GC even if it gets destroyed leading to memory leaks)
Whenever you start a new asyncTask make sure to cancel the previous asyncTask (if any) that still works with this view
And it always better to use caches (memory & disk)

Volley - NetworkImageView sometimes doesn't show the error image?

So I've decided to try out the new Volley library as shown on Google IO 2013.
I've tried it out while using the easy solution of NetworkImageView to show multiple images on a GridView.
It works nice and shows images, but if I let it download the images and then I turn off the WiFi during the download, it doesn't show an error as if everything still loads. Not only that, but if I restore the connection, it doesn't resume the loading.
Why does it occur, and how can I fix it? Maybe it's actually a bug?
Here's my sample code, if anyone wishes to try it out (BitmapCacheLru code here):
public class MainActivity extends Activity {
private static final int COLUMNS_COUNT = 4;
private RequestQueue _requestQueue;
private ImageLoader _imageLoader;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_requestQueue=Volley.newRequestQueue(this);
_imageLoader=new ImageLoader(_requestQueue, new BitmapLruCache());
final GridView gridView = new GridView(this);
gridView.setNumColumns(COLUMNS_COUNT);
final int screenWidth = getResources().getDisplayMetrics().widthPixels;
gridView.setAdapter(new BaseAdapter() {
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
NetworkImageView rootView = (NetworkImageView) convertView;
if (rootView == null) {
rootView = new NetworkImageView(MainActivity.this);
rootView.setLayoutParams(new AbsListView.LayoutParams(screenWidth / COLUMNS_COUNT, screenWidth / COLUMNS_COUNT));
rootView.setScaleType(ScaleType.CENTER_CROP);
rootView.setDefaultImageResId(android.R.drawable.sym_def_app_icon);
rootView.setErrorImageResId(android.R.drawable.ic_dialog_alert);
}
final String url = getItem(position);
rootView.setImageUrl(url, _imageLoader);
return rootView;
}
#Override
public long getItemId(final int position) {
return 0;
}
#Override
public String getItem(final int position) {
return Images.imageThumbUrls[position];
}
#Override
public int getCount() {
return Images.imageThumbUrls.length;
}
});
setContentView(gridView);
}
#Override
protected void onStop() {
_requestQueue.cancelAll(this);
super.onStop();
}
}
P.S. If you want to see the code of NetworkImageView, I think it's available here .
I think the problem is that the volley does not help you to reload the image.
A quick inspection shows that the NetworkImageView only loads data when onLayout method is called and the method loadImageIfNecessary will queue the network request if necessary.
When there is no Internet connection, the error callback will be called and there is no further action once the Internet get itself connected.
However, since you have the NetworkImage in a list, when you scroll the list, I suppose you will reuse the cell view and call setImageURL once again. If the Internet connection is available, the image will be loaded automatically. Alternatively, once the Internet connection is up, you can refresh the list view and so that the image will be loaded automatically.

Video thumbnail return null

I am creating thumbnails from videos stored in my sd card ,displaying thumbnails and its names in grid view. On item selected event of the grid view pop ups a dialog and asking x, y, right, bottom positions then pasting it to the main activity . I got the video files, and tried to create thumbnail using media store also am retrieving thumbnail as bitmap, but the bitmap is null. In the grid view video names are shown and i am able to select the corresponding thumbnail and can give positions also am able set the thumbnail to the main activity. The problem is the bitmap is null and bitmap image not showing(text vie video name shown). What's the problem ? I can't figure it out? Plz help me? My code is given below. thanks in advance.
if (f.isFile()) {
if (fName.endsWith(".mpg")
|| fName.endsWith(".mov")
|| fName.endsWith(".wmv")
|| fName.endsWith(".rm")
|| fName.endsWith(".mp4")) {
tv.setText(fName);
path = f.getAbsolutePath();
System.out.println("Video file path=>"+path);
thumb = ThumbnailUtils.createVideoThumbnail(f.getAbsolutePath(),MediaStore.Video.Thumbnails.MICRO_KIND);
if(thumb==null)
{
/**Every time it printing null**/
System.out.println("Thumb is null");
}
iv.setImageBitmap(thumb);
From ThumbnailUtils.createVideoThumbnail documentation: May return null if the video is corrupt or the format is not supported.
By default, almost all supported formats are mp4 and 3gp. See here: http://developer.android.com/guide/appendix/media-formats.html for full list of default-supported media formats.
If you are creating thumbnail from sd card video this would create ThumbnailUtils.createVideoThumbnail otherwise use a cursor.
See this example.
Try this code. It is getting the thumbnail of videos from urls. instead of pass the path of sd card .it will help you . Dont forgot to add internet permission in manifest file.
public class VideoThumbnailActivity extends Activity {
public static final String Downloader = null;
static String uri1="http://daily3gp.com/vids/lucky_guy.3gp";
static String uri2="http://daily3gp.com/vids/reporter_hit_by_plane.3gp";
static String uri3="http://daily3gp.com/vids/motorcycle_wipesout_explodes.3gp";
static String uri4="http://commonsware.com/misc/test2.3gp";
public static String uri_array[]={uri1,uri2,uri3,uri4,uri1,uri2,uri3,uri4,uri1,uri2,uri3,uri4};
ImageView imageView;
String url;
Gallery ga1,ga2;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageView = (ImageView)findViewById(R.id.imageView);
ga1 = (Gallery)findViewById(R.id.gallery1);
ga1.setAdapter(new ImageAdapter(getApplicationContext()));
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(uri_array[0], MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
//on click event on gallery
ga1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, final int position,long arg3) {
imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(uri_array[position], MediaStore.Video.Thumbnails.FULL_SCREEN_KIND));
//on click event on imageview to play video
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(),PlayActivity.class);
intent.putExtra("path",uri_array[position]);
startActivity(intent);
}
});
}
});
}
public class ImageAdapter extends BaseAdapter {
private Context ctx;
int imageBackground;
public ImageAdapter(Context c) {
ctx = c;
TypedArray ta = obtainStyledAttributes(R.styleable.Gallery1);
imageBackground = ta.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 1);
ta.recycle();
}
#Override
public int getCount() {
return uri_array.length;
}
#Override
public Object getItem(int arg0) {
return arg0;
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View view, ViewGroup arg2) {
ImageView iv = new ImageView(ctx);
Bitmap curThumb = null;
curThumb = ThumbnailUtils.createVideoThumbnail(uri_array[position],MediaStore.Video.Thumbnails.FULL_SCREEN_KIND);
iv.setImageBitmap(curThumb);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setLayoutParams(new Gallery.LayoutParams(150,120));
iv.setBackgroundResource(imageBackground);
return iv;
}
}
let me know your problem is resolved or not.

Categories

Resources