How can I get video thumbnails from R.raw folder? - android

The code below can not get the video thumbnails of videos which were located in R.raw folder.
I want to use a gallery to show the thumbnails of videos. Videos were put into R.raw folder (actually I'm new to Android, so I don't really know where to put these videos, so I put them in R.raw folder). Now I want to get the thumbnails of the videos. But someone told that thumbnails can only be got from the SD card. So is it true? And what should I do next? Thanks.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Gallery gallery = (Gallery) findViewById(R.id.gallery);
final String[] videoFileList = new String[] { "R.raw.01", "R.raw.02" };
BaseAdapter adapter = new BaseAdapter() {
public int getCount() {
return videoFileList.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(Select.this);
Bitmap bmThumbnail;
bmThumbnail = ThumbnailUtils.createVideoThumbnail("android.resource://" + getPackageName() + "/"
+ videoFileList[position], Thumbnails.MINI_KIND);
System.out.println(videoFileList[position]);
imageView.setImageBitmap(bmThumbnail);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);
imageView.setBackgroundResource(typedArray.getResourceId(
R.styleable.Gallery_android_galleryItemBackground, 0));
return imageView;
}
};
gallery.setAdapter(adapter);
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(Select.this, Play.class);
intent.putExtra("image", videoFileList[position]);
startActivity(intent);
Select.this.finish();
}
public void onNothingClick(AdapterView<?> parent) {
}
});
}

On Android 5, createVideoThumbnail() always returned null when asking for the thumbnail of a video in resources. Here's what worked for me in the end:
Uri videoURI = Uri.parse("android.resource://" + getActivity().getPackageName() + "/raw/animation");
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(getActivity().getApplicationContext(), videoURI);
Bitmap thumb = retriever.getFrameAtTime(10, MediaMetadataRetriever.OPTION_PREVIOUS_SYNC);
videoView.setBackground(new BitmapDrawable(getResources(), thumb));

Have you looked at, createVideoThumbnail() from ThumbnailUtils Class?
Actually, Your video files are in resource/raw directory so you have to create Thumbnails for it.
If your video files are in External Storage then Android Media Store itself creates for you. And you can get it by MediaStore.Video.Thumbnails Class.

Video on res/raw folder of your application isn't managed by Android Media Content Provider, so you cannot obtain their thumbnail from it.
Alternatively, you can try to save them as normal file in your SD and, then, ask to media provider for thumbnail or create it directly via ThumbnailUtils.createVideoThumbnail class (only Android 2.2 or above)

Related

Glide sharing transformed GIF

I'd like to share GIFs I loaded with Glide but i can't find a way to do it.
I tried to share the GifDrawable data as an array of byte but when i try to share, the GIF doesn't appear.
Here's the code I wrote :
Glide.with(getActivity())
.load(to_add.mMeme.getmUrl())
.asGif()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.transformFrame(new TextTransformation(getContext(), to_add.mMeme.getmText()))
.listener(new RequestListener<String, GifDrawable>() {
#Override
public boolean onException(Exception e, String s, Target<GifDrawable> target, boolean b) {
return false;
}
#Override
public boolean onResourceReady(GifDrawable gifDrawable, String s, Target<GifDrawable> target, boolean b, boolean b1) {
to_add.mDrawable = gifDrawable;
to_add.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Meme to_share = null;
for (Meme meme : mViewList) {
if (meme.mView.equals(v)) {
to_share = meme;
break;
}
}
if (to_share != null) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, to_share.mDrawable.toString());
startActivity(Intent.createChooser(shareIntent, "Share"));
}
}
});
return false;
}
})
.into((ImageView) to_add.mView.findViewById(R.id.memeImageView));
Here is my Meme class used in the previous code :
public static class Meme {
public Meme(StorageManager.Meme meme, View view) {
mMeme = meme;
mView = view;
}
StorageManager.Meme mMeme;
View mView;
GifDrawable mDrawable;
}
mViewList is a List of Meme:
List<Meme> mViewList;
And to_add variable is the Meme containing the GIF i'm trying to share :
final Meme to_add = new Meme(data, getActivity().getLayoutInflater().inflate(R.layout.meme_layout, null));
I miss understood how to use share intents.
Sharing with intents
To answer my question, sharing a file with a Share intent require the file to be accessible on drive.
That's why I had to write it in the cache memory using :
File file = new File(mContext.getExternalCacheDir(), myMeme.getmFileName());
file.setReadable(true);
Don't write your file in your App cache dir, otherwise file will not be accessible by other applications
mContext.getCacheDir()
Then I could easily share my File using Uris :
Uri uri = Uri.fromFile(file);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.setType("image/gif");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Share with"));
Sharing works perfectly now.
Concerning Glide GIF
I wasn't able to get Glide transformed GIF.
To add my text to the GIF, i splitted all frames composing the GIF and writted down the text.
Split GIF into frames using Glide
GifDecoder decoder = mGif.getmDrawable().getDecoder();
Bitmap frame;
Log.d("GIF GENERATION", "STARTED FRAME SPLIT");
int max = mGif.getmDrawable().getFrameCount();
int current = 0;
decoder.advance();
while (current < max && (frame = decoder.getNextFrame()) != null) {
Log.d("GIF GENERATION", "ADDED FRAME");
// Here you get your GIF frame per frame
decoder.advance();
current++;
}
Log.d("GIF GENERATION", "ENDED FRAME SPLIT");
Adding text to every frame
To write down my text on every frame, I used this class that works perfectly for single line text : http://www.skoumal.net/en/android-how-draw-text-bitmap/
Creating new GIF with frames
To do that, I used another class called GifCreator. It can be found here : https://github.com/nbadal/android-gif-encoder
Final Result
Here's how the actual code is :
GifDecoder decoder = mGif.getmDrawable().getDecoder();
GifCreator creator = new GifCreator();
Bitmap frame;
creator.start(mOs);
creator.setSize(mGif.getmDrawable().getDecoder().getWidth(), mGif.getmDrawable().getDecoder().getHeight());
creator.setRepeat(0);
creator.setQuality(15);
Log.d("GIF GENERATION", "STARTED FRAME SPLIT");
int max = mGif.getmDrawable().getFrameCount();
int current = 0;
decoder.advance();
while (current < max && (frame = decoder.getNextFrame()) != null) {
Log.d("GIF GENERATION", "ADDED FRAME");
creator.addFrame(TextTransformation.drawTextToBitmap(mContext, temp, mText));
creator.setDelay(decoder.getNextDelay());
decoder.advance();
current++;
}
Log.d("GIF GENERATION", "ENDED FRAME SPLIT");
creator.finish();

Android Open gallery to folder and slide through images

I'm able to open Gallery in a specific folder and image; however, when I try to slide through the images that functionality does not seem to work. Since I'm opening the Gallery app I figured that Gallery should handle this functionality. Anyone have any ideas? Can't seem to figure out what to do.
Below is my code
public OpenGalleyToSpecificFolder( Context _context, String path, String fileName){
mContext = _context;
mMediaScannerConnection = null;
mPath = path;
mFileName = fileName;
}
public void OpenGallary( ){
File folder_name = new File(mPath);
allFiles = folder_name.listFiles();
for(int i = allFiles.length - 1; i > 0; --i){
if(allFiles[i].getName().equals(mFileName)){
index = i;
break;
}
}
if(mMediaScannerConnection == null)
mMediaScannerConnection = new MediaScannerConnection(mContext, this);
mMediaScannerConnection.connect();
}
#Override
public void onMediaScannerConnected() {
mMediaScannerConnection.scanFile(allFiles[index].getAbsolutePath(), null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
mContext.startActivity(intent);
mMediaScannerConnection.disconnect();
}
There are thousands of Android device models. There will be hundreds of different "gallery apps" pre-installed across those models, let alone other apps that support ACTION_VIEW that users install themselves. What those apps do, in response to your Intent, is up to the developers of those apps, not you.
If you want a specific look-and-feel to browsing images, implement your own image-browsing UI in your app.

Android play video in TextureView from raw or assets

I'm having an annoying problem with playing a video in TextureView from raw or assets folder... or even from the external storage. The code in the fragment looks something like this
public class MainFragment extends Fragment implements TextureView.SurfaceTextureListener, MediaPlayer.OnBufferingUpdateListener,
MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener {
private ParallaxAdapter mAdapter;
private MediaPlayer mMediaPlayer;
private MediaPlayer mMediaPlayer2;
private TextureView tv;
private TextureView tv2;
private ImageView imageview;
private TextureView mTexture;
String path;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) {
super.onCreateView(inflater, container, savedInstance);
View v = inflater.inflate(R.layout.view_fragment, container, false);
path = getArguments().getString("path");
Log.d("Fragment","" + path);
String tag = getArguments().getString("Tag");
imageview = (ImageView) v.findViewById(R.id.imageView);
if (tag == "image") {
imageview.setImageResource(getArguments().getInt("image"));
} else if (tag == "video") {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmapThumb = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.FULL_SCREEN_KIND);
imageview.setImageBitmap(bitmapThumb);
tv = (TextureView) v.findViewById(R.id.textureView);
tv.setSurfaceTextureListener(this);
}
return v;
}
public void setAdapter(ParallaxAdapter Adapter) {
mAdapter = Adapter;
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Surface s = new Surface(surface);
try {
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(path);
mp.setSurface(s);
mp.prepare();
mp.setOnBufferingUpdateListener(this);
mp.setOnCompletionListener(this);
mp.setOnPreparedListener(this);
mp.setOnVideoSizeChangedListener(this);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setVolume(0, 0);
mMediaPlayer.setLooping(true);
mMediaPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
It looks like the MediaPlayer cannot find the file from raw:
defpath = "android.resource://" + getPackageName() + "/" + R.raw.video;
or from assets:
AssetFileDescriptor afd = getAssets().openFd(FILE_NAME);
mp.setDataSource(afd.getFileDescriptor());
and i've tried to copy the assets to the sdcard with some codes from this discussion: android-how-to-copy-files-from-assets-folder-to-sdcard
but if I copy it, the file is somehow corrupt. I cannot even play it with the normal VideoPlayer in my device.
It is not a codec error! If I put the video into my device like on a USB and set the path and it's working with all 3 test videos. The manifest has read and write permission. And the VideoView makes even more problems with the ViewPager and paths.
Hopefully I'm just making some kind of stupid mistake... Thank you!
Only because you can play the video with the default video player of your device doesn't mean it's not a codec problem or another detail it doesn't like about it.
What I' missing here is a MediaPlayer.OnErrorListener
If you get something like
/MediaPlayer﹕ error (1, -2147483648), which indicates a MEDIA_ERROR_UNKNOWN with the extra info MEDIA_ERROR_SYSTEM (-2147483648) - low-level system error it's probably a video issue.
You could take a look at the video metadata with ffmpeg:
ffmpeg -i video.mp4
Check for:
Codec
Metadata (e.g. video is rotated)
Video width/height too big
Didn't get a reasonable error message for any of these.
Here's the official info: Supported Media Formats which doesn't help much IMHO

Can't Open a File Using Intent

What I am trying to do here is that. I locate the Pdf file folder in my SD Card and click the file and it complete action using Adobe Reader. I successfully done the read SD card option and it shows all pdf file in layout as a gridview. But when I click the pdf file it opens Adobe reader but can't open the file. It says "The document can't be opened because it's not a valid pdf doc". Here is my Code-
Here is the code for locating File & folder in SD card
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState)
{
View view =inflater.inflate(R.layout.magica_pdf_layout, container, false);
// Check for SD Card
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
Toast.makeText(PdfFragment.this.getActivity(), "Error! No SDCARD Found!", Toast.LENGTH_LONG).show();
}
else
{
// Locate folder in your SD Card
file = new File(Environment.getExternalStorageDirectory()+ File.separator + "Book");
// Create a new folder if no folder named exist
file.mkdirs();
}
here is the part for onclick method
// Capture gridview item click
grid.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
// get clicked file name from gridview
String pdfname=(String)parent.getItemAtPosition(position);
//prepare pdf file url
selectedFile = new File(file.getAbsolutePath()+File.separator +pdfname+".pdf");
Intent pdfIntent = new Intent();
pdfIntent.setAction(android.content.Intent.ACTION_VIEW);
pdfIntent.setDataAndType(Uri.fromFile(selectedFile), "application/pdf");
startActivity(pdfIntent);
}
});
The document can't be opened because it's not a valid pdf doc
Because you are not passing pdf file path, currently passing only folder path in which all files are present. do it as:
#Override
public void onItemClick(AdapterView<?> parent,
View view,int position, long id)
{
// get clicked file name from gridview
String pdfname=(String)parent.getItemAtPosition(position);
// prepare pdf file url
File selectedFile = new File(file.getAbsolutePath()+"/"+pdfname+".pdf");
Intent pdfIntent = new Intent();
pdfIntent.setAction(android.content.Intent.ACTION_VIEW);
pdfIntent.setDataAndType(Uri.fromFile(selectedFile), "application/pdf");
startActivity(pdfIntent);
}

Making a GridView take images from a specific folder

I am a newbie to android app making and I am still a beginner with a little knowledge . I have been trying to make an android app that works like a gallery , but it only displays images under a specific folder. For the UI , I am starting with only a GridView (or TwoWayGridView which is derived from the latter) , and have been trying to let this GridView take its contents from this folder .
I have made this folder and copied an image to it for testing and failed. No image was displayed .Plus I am not very familiar with Cursors and ListAdapters . Somethings that I'm sure that are correct are permissions , manifest , and layout of the activity.Moreover , I believe my problem is around URIs . Please check my code below :
Some namings:
Uri contentUri;
Cursor mImageCursor;
TwoWayGridView mImageGrid;
ListAdapter mAdapter;
String sdCard = Environment.getExternalStorageDirectory().getAbsolutePath();
onCreate method :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
File motherDirectory = new File(sdCard+"/Favory");
if(!motherDirectory.exists()){
motherDirectory.mkdir();
}
MediaScannerConnection.scanFile(this, new String[]{motherDirectory.getAbsolutePath()} ,null, new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// TODO Auto-generated method stub
contentUri = uri ;
initGrid(uri);
}
});
}
initGrid(Uri) method :
private void initGrid(Uri folderUri) {
mImageCursor = this.getContentResolver().query(folderUri,
ImageThumbnailAdapter.IMAGE_PROJECTION, null, null,
MediaStore.Images.ImageColumns.DISPLAY_NAME);
mImageGrid = (TwoWayGridView) findViewById(R.id.gridview);
mAdapter = new ImageThumbnailAdapter(this, mImageCursor);
mImageGrid.setAdapter(mAdapter);
mImageGrid.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(TwoWayAdapterView<?> parent, View v, int position, long id) {
Log.i(TAG, "showing image: " + mImageCursor.getString(ImageThumbnailAdapter.IMAGE_NAME_COLUMN));
Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
}
Thanks for your help , and please if there is an easier alternative way of doing this tell me, I care for the results more than the methods now . If you need anything or any more information please tell me in the comments below . Thanks again !
To Read the Files of a folder you can use this function ( from this post ):
String directoryName = Environment.getExternalStorageDirectory().toString()+"/YourFolder/";
public ArrayList<File> listf(String directoryName, ArrayList<File> files) {
File directory = new File(directoryName);
// get all the files from a directory
File[] fList = directory.listFiles();
for (File file : fList) {
Log.e("path : "," "+file);
if (file.isFile()) {
files.add(file);
} else if (file.isDirectory()) {
listf(file.getAbsolutePath(), files);
}
}
return files;
}
Then you should load this list of files to your GridView Adapter, i suggest you use Universal Image Loader
You just give your file path and Adapter ImageVIew at that position
loadImageUtil.loadBitmapToImageView(imageView, youArrayList.get(position));
For more informations how to use this library you can see examples, there is an example with grid view gridView

Categories

Resources