map = System.getenv();
String[] values = new String[map.values().size()];
map.values().toArray(values);
String path = values[values.length - 1];
Log.e("nmbb", "FileUtils.getExternalStorageDirectory : " + path);
if (path.startsWith("/mnt/")
&& !Environment.getExternalStorageDirectory().getAbsolutePath()
.equals(path))
return path;
else
return null;
}
public static String getCanonical(File f) {
if (f == null)
return null;
try {
return f.getCanonicalPath();
} catch (IOException e) {
return f.getAbsolutePath();
}
}
public static boolean sdAvailable() {
return Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment
.getExternalStorageState())
|| Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState());
}
}
================================================
FILE: src/com/nmbb/oplayer/util/FractionalTouchDelegate.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nmbb.oplayer.util;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
/**
* {@link TouchDelegate} that gates {@link MotionEvent} instances by comparing
* then against fractional dimensions of the source view.
*
* This is particularly useful when you want to define a rectangle in terms of
* the source dimensions, but when those dimensions might change due to pending
* or future layout passes.
*
* One example is catching touches that occur in the top-right quadrant of
* {@code sourceParent}, and relaying them to {@code targetChild}. This could be
* done with:
* FractionalTouchDelegate.setupDelegate(sourceParent, targetChild, new RectF(0.5f, 0f, 1f, 0.5f));
*
*/
public class FractionalTouchDelegate extends TouchDelegate {
private View mSource;
private View mTarget;
private RectF mSourceFraction;
private Rect mScrap = new Rect();
/** Cached full dimensions of {@link #mSource}. */
private Rect mSourceFull = new Rect();
/** Cached projection of {@link #mSourceFraction} onto {@link #mSource}. */
private Rect mSourcePartial = new Rect();
private boolean mDelegateTargeted;
public FractionalTouchDelegate(View source, View target, RectF sourceFraction) {
super(new Rect(0, 0, 0, 0), target);
mSource = source;
mTarget = target;
mSourceFraction = sourceFraction;
}
/**
* Helper to create and setup a {@link FractionalTouchDelegate} between the
* given {@link View}.
*
* @param source Larger source {@link View}, usually a parent, that will be
* assigned {@link View#setTouchDelegate(TouchDelegate)}.
* @param target Smaller target {@link View} which will receive
* {@link MotionEvent} that land in requested fractional area.
* @param sourceFraction Fractional area projected onto source {@link View}
* which determines when {@link MotionEvent} will be passed to
* target {@link View}.
*/
public static void setupDelegate(View source, View target, RectF sourceFraction) {
source.setTouchDelegate(new FractionalTouchDelegate(source, target, sourceFraction));
}
/**
* Consider updating {@link #mSourcePartial} when {@link #mSource}
* dimensions have changed.
*/
private void updateSourcePartial() {
mSource.getHitRect(mScrap);
if (!mScrap.equals(mSourceFull)) {
// Copy over and calculate fractional rectangle
mSourceFull.set(mScrap);
final int width = mSourceFull.width();
final int height = mSourceFull.height();
mSourcePartial.left = (int) (mSourceFraction.left * width);
mSourcePartial.top = (int) (mSourceFraction.top * height);
mSourcePartial.right = (int) (mSourceFraction.right * width);
mSourcePartial.bottom = (int) (mSourceFraction.bottom * height);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
updateSourcePartial();
// The logic below is mostly copied from the parent class, since we
// can't update private mBounds variable.
// http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;
// f=core/java/android/view/TouchDelegate.java;hb=eclair#l98
final Rect sourcePartial = mSourcePartial;
final View target = mTarget;
int x = (int)event.getX();
int y = (int)event.getY();
boolean sendToDelegate = false;
boolean hit = true;
boolean handled = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (sourcePartial.contains(x, y)) {
mDelegateTargeted = true;
sendToDelegate = true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
sendToDelegate = mDelegateTargeted;
if (sendToDelegate) {
if (!sourcePartial.contains(x, y)) {
hit = false;
}
}
break;
case MotionEvent.ACTION_CANCEL:
sendToDelegate = mDelegateTargeted;
mDelegateTargeted = false;
break;
}
if (sendToDelegate) {
if (hit) {
event.setLocation(target.getWidth() / 2, target.getHeight() / 2);
} else {
event.setLocation(-1, -1);
}
handled = target.dispatchTouchEvent(event);
}
return handled;
}
}
================================================
FILE: src/com/nmbb/oplayer/util/ImageUtils.java
================================================
package com.nmbb.oplayer.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import com.nmbb.oplayer.exception.Logger;
public class ImageUtils {
// http://zhuixinjian.javaeye.com/blog/743672
// 图片圆角
// 图片叠加
// 图片缩放
// 图片旋转
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public static int getBitmapSize(Bitmap bitmap) {
if (DeviceUtils.hasHoneycombMR1()) {
return bitmap.getByteCount();
}
// Pre HC-MR1
return bitmap.getRowBytes() * bitmap.getHeight();
}
/** 旋转图片 */
public static Bitmap rotate(Bitmap b, int degrees) {
if (degrees != 0 && b != null) {
Matrix m = new Matrix();
m.setRotate(degrees, (float) b.getWidth() / 2,
(float) b.getHeight() / 2);
try {
Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
b.getHeight(), m, true);
if (b != b2) {
b.recycle();
b = b2;
}
} catch (OutOfMemoryError ex) {
Logger.e(ex);
} catch (Exception ex) {
Logger.e(ex);
}
}
return b;
}
/**
* Decode and sample down a bitmap from a file to the requested width and
* height.
*
* @param filename
* The full path of the file to decode
* @param reqWidth
* The requested width of the resulting bitmap
* @param reqHeight
* The requested height of the resulting bitmap
* @return A bitmap sampled down from the original with the same aspect
* ratio and dimensions that are equal to or greater than the
* requested width and height
*/
public static synchronized Bitmap decodeSampledBitmapFromFile(
String filename, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
/**
* Calculate an inSampleSize for use in a
* {@link android.graphics.BitmapFactory.Options} object when decoding
* bitmaps using the decode* methods from {@link BitmapFactory}. This
* implementation calculates the closest inSampleSize that will result in
* the final decoded bitmap having a width and height equal to or larger
* than the requested width and height. This implementation does not ensure
* a power of 2 is returned for inSampleSize which can be faster when
* decoding but results in a larger bitmap which isn't as useful for caching
* purposes.
*
* @param options
* An options object with out* params already populated (run
* through a decode* method with inJustDecodeBounds==true
* @param reqWidth
* The requested width of the resulting bitmap
* @param reqHeight
* The requested height of the resulting bitmap
* @return The value to be used for inSampleSize
*/
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
// This offers some additional logic in case the image has a strange
// aspect ratio. For example, a panorama may have a much larger
// width than height. In these cases the total pixels might still
// end up being too large to fit comfortably in memory, so we should
// be more aggressive with sample down the image (=larger
// inSampleSize).
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down
// further.
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
public static boolean saveBitmap(String path, Bitmap bitmap) {
return saveBitmap(new File(path), bitmap);
}
/** 保存图片到文件 */
public static boolean saveBitmap(File f, Bitmap bitmap) {
if (bitmap == null || bitmap.isRecycled())
return false;
FileOutputStream fOut = null;
try {
if (f.exists())
f.createNewFile();
fOut = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
return true;
} catch (FileNotFoundException e) {
Logger.e(e);
} catch (IOException e) {
Logger.e(e);
} catch (Exception e) {
Logger.e(e);
} finally {
if (fOut != null) {
try {
fOut.close();
} catch (IOException e) {
Logger.e(e);
}
}
}
return false;
}
public static Bitmap decodeUriAsBitmap(Context ctx, Uri uri) {
Bitmap bitmap = null;
try {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// options.outWidth = reqWidth;
// options.outHeight = reqHeight;
BitmapFactory.decodeStream(ctx.getContentResolver()
.openInputStream(uri), null, options);
Logger.i("orgi:" + options.outWidth + "x" + options.outHeight);
int be = (int) (options.outHeight / (float) 350);
if (be <= 0)
be = 1;
options.inSampleSize = be;// calculateInSampleSize(options,
// reqWidth, reqHeight);
Logger.i("inSampleSize:" + options.inSampleSize);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(ctx.getContentResolver()
.openInputStream(uri), null, options);
} catch (FileNotFoundException e) {
Logger.e(e);
} catch (OutOfMemoryError e) {
Logger.e(e);
}
return bitmap;
}
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
matrix, true);
return newbmp;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
/**
* 获取图片圆角
*
* @param bitmap
* @param roundPx
* 圆角度数
* @return
*/
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
/**
* 转行Drawable为Bitmap对象
*
* @param drawable
* @return
*/
public static Bitmap toBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
/**
* 缩放图片
*
* @param src
* 缩放原图
* @param dstWidth
* 缩放后宽
* @param dstHeight
* 缩放后高
* @return
*/
public static Bitmap scaledBitmap(Bitmap src, int dstWidth, int dstHeight) {
// 原图不能为空也不能已经被回收掉了
Bitmap result = null;
if (src != null && !src.isRecycled()) {
if (src.getWidth() == dstWidth && src.getHeight() == dstHeight) {
result = src;
} else {
result = Bitmap.createScaledBitmap(src, dstWidth, dstHeight,
true);
}
}
// ThumbnailUtils.extractThumbnail(source, width, height)
return result;
}
/**
* 按比例缩放图片
*
* @param src
* @param scale
* 例如2 就是二分之一
* @return
*/
public static Bitmap scaledBitmap(Bitmap src, int scale) {
if (src == null || src.isRecycled()) {
return null;
}
int dstWidth = src.getWidth() / scale;
int dstHeight = src.getHeight() / scale;
return Bitmap.createScaledBitmap(src, dstWidth, dstHeight, true);
}
/**
* 将图片转换成字节数组
*
* @param bitmap
* @return
*/
public static byte[] toBytes(Bitmap bitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
return outputStream.toByteArray();
}
}
================================================
FILE: src/com/nmbb/oplayer/util/IntentHelper.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nmbb.oplayer.util;
import io.vov.vitamio.utils.Log;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Parcelable;
import android.text.Html;
public final class IntentHelper {
public static final String MEDIA_PATTERN = "(http[s]?://)+([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?";
private static final Pattern mMediaPattern;
static {
mMediaPattern = Pattern.compile(MEDIA_PATTERN);
}
public static Uri getIntentUri(Intent intent) {
Uri result = null;
if (intent != null) {
result = intent.getData();
if (result == null) {
final String type = intent.getType();
String sharedUrl = intent.getStringExtra(Intent.EXTRA_TEXT);
if (!StringUtils.isEmpty(sharedUrl)) {
if ("text/plain".equals(type) && sharedUrl != null) {
result = getTextUri(sharedUrl);
} else if ("text/html".equals(type) && sharedUrl != null) {
result = getTextUri(Html.fromHtml(sharedUrl).toString());
}
} else {
Parcelable parce = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (parce != null)
result = (Uri) parce;
}
}
}
return result;
}
private static Uri getTextUri(String sharedUrl) {
Matcher matcher = mMediaPattern.matcher(sharedUrl);
if (matcher.find()) {
sharedUrl = matcher.group();
if (!StringUtils.isEmpty(sharedUrl)) {
return Uri.parse(sharedUrl);
}
}
return null;
}
public static boolean existPackage(final Context ctx, String packageName) {
if (!StringUtils.isEmpty(packageName)) {
for (PackageInfo p : ctx.getPackageManager().getInstalledPackages(0)) {
if (packageName.equals(p.packageName))
return true;
}
}
return false;
}
public static void startApkActivity(final Context ctx, String packageName) {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(packageName, 0);
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.setPackage(pi.packageName);
List apps = pm.queryIntentActivities(intent, 0);
ResolveInfo ri = apps.iterator().next();
if (ri != null) {
String className = ri.activityInfo.name;
intent.setComponent(new ComponentName(packageName, className));
ctx.startActivity(intent);
}
} catch (NameNotFoundException e) {
Log.e("startActivity", e);
}
}
}
================================================
FILE: src/com/nmbb/oplayer/util/MediaUtils.java
================================================
/*
* Copyright (C) 2012 YIXIA.COM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nmbb.oplayer.util;
import java.io.File;
import java.util.regex.Pattern;
import android.net.Uri;
public final class MediaUtils {
public static final String[] EXTENSIONS;
// http://www.fileinfo.com/filetypes/video
public static final String[] VIDEO_EXTENSIONS = { "\\.264", "\\.3g2", "\\.3gp", "\\.3gp2", "\\.3gpp", "\\.3gpp2", "\\.3mm", "\\.3p2", "\\.60d", "\\.aep", "\\.ajp", "\\.amv", "\\.amx", "\\.arf", "\\.asf", "\\.asx", "\\.avb", "\\.avd", "\\.avi", "\\.avs", "\\.avs", "\\.axm", "\\.bdm", "\\.bdmv", "\\.bik", "\\.bin", "\\.bix", "\\.bmk", "\\.box", "\\.bs4", "\\.bsf", "\\.byu", "\\.camre", "\\.clpi", "\\.cpi", "\\.cvc", "\\.d2v", "\\.d3v", "\\.dat", "\\.dav", "\\.dce", "\\.dck", "\\.ddat", "\\.dif", "\\.dir", "\\.divx", "\\.dlx", "\\.dmb", "\\.dmsm", "\\.dmss", "\\.dnc", "\\.dpg", "\\.dream", "\\.dsy", "\\.dv", "\\.dv-avi", "\\.dv4", "\\.dvdmedia", "\\.dvr-ms", "\\.dvx", "\\.dxr", "\\.dzm", "\\.dzp", "\\.dzt", "\\.evo", "\\.eye", "\\.f4p", "\\.f4v", "\\.fbr", "\\.fbr", "\\.fbz", "\\.fcp", "\\.flc", "\\.flh", "\\.fli", "\\.flv", "\\.flx", "\\.gl", "\\.grasp", "\\.gts", "\\.gvi", "\\.gvp", "\\.hdmov", "\\.hkm", "\\.ifo", "\\.imovi", "\\.imovi", "\\.iva", "\\.ivf", "\\.ivr", "\\.ivs", "\\.izz", "\\.izzy", "\\.jts", "\\.lsf", "\\.lsx", "\\.m15", "\\.m1pg", "\\.m1v", "\\.m21", "\\.m21", "\\.m2a", "\\.m2p", "\\.m2t", "\\.m2ts", "\\.m2v", "\\.m4e", "\\.m4u", "\\.m4v", "\\.m75", "\\.meta", "\\.mgv", "\\.mj2", "\\.mjp", "\\.mjpg", "\\.mkv", "\\.mmv", "\\.mnv", "\\.mod", "\\.modd", "\\.moff", "\\.moi", "\\.moov", "\\.mov", "\\.movie", "\\.mp21", "\\.mp21", "\\.mp2v", "\\.mp4", "\\.mp4v", "\\.mpe", "\\.mpeg", "\\.mpeg4", "\\.mpf", "\\.mpg", "\\.mpg2", "\\.mpgin", "\\.mpl", "\\.mpls", "\\.mpv", "\\.mpv2", "\\.mqv", "\\.msdvd", "\\.msh", "\\.mswmm", "\\.mts", "\\.mtv", "\\.mvb", "\\.mvc", "\\.mvd", "\\.mve", "\\.mvp", "\\.mxf", "\\.mys", "\\.ncor", "\\.nsv", "\\.nvc", "\\.ogm", "\\.ogv", "\\.ogx", "\\.osp", "\\.par", "\\.pds", "\\.pgi", "\\.piv", "\\.playlist", "\\.pmf", "\\.prel", "\\.pro", "\\.prproj", "\\.psh", "\\.pva", "\\.pvr", "\\.pxv", "\\.qt", "\\.qtch", "\\.qtl", "\\.qtm", "\\.qtz", "\\.rcproject", "\\.rdb", "\\.rec", "\\.rm", "\\.rmd", "\\.rmp", "\\.rms", "\\.rmvb", "\\.roq", "\\.rp", "\\.rts", "\\.rts", "\\.rum", "\\.rv", "\\.sbk", "\\.sbt", "\\.scm", "\\.scm", "\\.scn", "\\.sec", "\\.seq", "\\.sfvidcap", "\\.smil", "\\.smk", "\\.sml", "\\.smv", "\\.spl", "\\.ssm", "\\.str", "\\.stx", "\\.svi", "\\.swf", "\\.swi", "\\.swt", "\\.tda3mt", "\\.tivo", "\\.tix", "\\.tod", "\\.tp", "\\.tp0", "\\.tpd", "\\.tpr", "\\.trp", "\\.ts", "\\.tvs", "\\.vc1", "\\.vcr", "\\.vcv", "\\.vdo", "\\.vdr", "\\.veg", "\\.vem", "\\.vf", "\\.vfw", "\\.vfz", "\\.vgz", "\\.vid", "\\.viewlet", "\\.viv", "\\.vivo", "\\.vlab", "\\.vob", "\\.vp3", "\\.vp6", "\\.vp7", "\\.vpj", "\\.vro", "\\.vsp", "\\.w32", "\\.wcp", "\\.webm", "\\.wm", "\\.wmd", "\\.wmmp", "\\.wmv", "\\.wmx", "\\.wp3", "\\.wpl", "\\.wtv", "\\.wvx", "\\.xfl", "\\.xvid", "\\.yuv", "\\.zm1", "\\.zm2", "\\.zm3", "\\.zmv" };
// http://www.fileinfo.com/filetypes/audio
public static final String[] AUDIO_EXTENSIONS = { "\\.4mp", "\\.669", "\\.6cm", "\\.8cm", "\\.8med", "\\.8svx", "\\.a2m", "\\.aa", "\\.aa3", "\\.aac", "\\.aax", "\\.abc", "\\.abm", "\\.ac3", "\\.acd", "\\.acd-bak", "\\.acd-zip", "\\.acm", "\\.act", "\\.adg", "\\.afc", "\\.agm", "\\.ahx", "\\.aif", "\\.aifc", "\\.aiff", "\\.ais", "\\.akp", "\\.al", "\\.alaw", "\\.all", "\\.amf", "\\.amr", "\\.ams", "\\.ams", "\\.aob", "\\.ape", "\\.apf", "\\.apl", "\\.ase", "\\.at3", "\\.atrac", "\\.au", "\\.aud", "\\.aup", "\\.avr", "\\.awb", "\\.band", "\\.bap", "\\.bdd", "\\.box", "\\.bun", "\\.bwf", "\\.c01", "\\.caf", "\\.cda", "\\.cdda", "\\.cdr", "\\.cel", "\\.cfa", "\\.cidb", "\\.cmf", "\\.copy", "\\.cpr", "\\.cpt", "\\.csh", "\\.cwp", "\\.d00", "\\.d01", "\\.dcf", "\\.dcm", "\\.dct", "\\.ddt", "\\.dewf", "\\.df2", "\\.dfc", "\\.dig", "\\.dig", "\\.dls", "\\.dm", "\\.dmf", "\\.dmsa", "\\.dmse", "\\.drg", "\\.dsf", "\\.dsm", "\\.dsp", "\\.dss", "\\.dtm", "\\.dts", "\\.dtshd", "\\.dvf", "\\.dwd", "\\.ear", "\\.efa", "\\.efe", "\\.efk", "\\.efq", "\\.efs", "\\.efv", "\\.emd", "\\.emp", "\\.emx", "\\.esps", "\\.f2r", "\\.f32", "\\.f3r", "\\.f4a", "\\.f64", "\\.far", "\\.fff", "\\.flac", "\\.flp", "\\.fls", "\\.frg", "\\.fsm", "\\.fzb", "\\.fzf", "\\.fzv", "\\.g721", "\\.g723", "\\.g726", "\\.gig", "\\.gp5", "\\.gpk", "\\.gsm", "\\.gsm", "\\.h0", "\\.hdp", "\\.hma", "\\.hsb", "\\.ics", "\\.iff", "\\.imf", "\\.imp", "\\.ins", "\\.ins", "\\.it", "\\.iti", "\\.its", "\\.jam", "\\.k25", "\\.k26", "\\.kar", "\\.kin", "\\.kit", "\\.kmp", "\\.koz", "\\.koz", "\\.kpl", "\\.krz", "\\.ksc", "\\.ksf", "\\.kt2", "\\.kt3", "\\.ktp", "\\.l", "\\.la", "\\.lqt", "\\.lso", "\\.lvp", "\\.lwv", "\\.m1a", "\\.m3u", "\\.m4a", "\\.m4b", "\\.m4p", "\\.m4r", "\\.ma1", "\\.mdl", "\\.med", "\\.mgv", "\\.mid", "\\.midi", "\\.miniusf", "\\.mka", "\\.mlp", "\\.mmf", "\\.mmm", "\\.mmp", "\\.mo3", "\\.mod", "\\.mp1", "\\.mp2", "\\.mp3", "\\.mpa", "\\.mpc", "\\.mpga", "\\.mpu", "\\.mp_", "\\.mscx", "\\.mscz", "\\.msv", "\\.mt2", "\\.mt9", "\\.mte", "\\.mti", "\\.mtm", "\\.mtp", "\\.mts", "\\.mus", "\\.mws", "\\.mxl", "\\.mzp", "\\.nap", "\\.nki", "\\.nra", "\\.nrt", "\\.nsa", "\\.nsf", "\\.nst", "\\.ntn", "\\.nvf", "\\.nwc", "\\.odm", "\\.oga", "\\.ogg", "\\.okt", "\\.oma", "\\.omf", "\\.omg", "\\.omx", "\\.ots", "\\.ove", "\\.ovw", "\\.pac", "\\.pat", "\\.pbf", "\\.pca", "\\.pcast", "\\.pcg", "\\.pcm", "\\.peak", "\\.phy", "\\.pk", "\\.pla", "\\.pls", "\\.pna", "\\.ppc", "\\.ppcx", "\\.prg", "\\.prg", "\\.psf", "\\.psm", "\\.ptf", "\\.ptm", "\\.pts", "\\.pvc", "\\.qcp", "\\.r", "\\.r1m", "\\.ra", "\\.ram", "\\.raw", "\\.rax", "\\.rbs", "\\.rcy", "\\.rex", "\\.rfl", "\\.rmf", "\\.rmi", "\\.rmj", "\\.rmm", "\\.rmx", "\\.rng", "\\.rns", "\\.rol", "\\.rsn", "\\.rso", "\\.rti", "\\.rtm", "\\.rts", "\\.rvx", "\\.rx2", "\\.s3i", "\\.s3m", "\\.s3z", "\\.saf", "\\.sam", "\\.sb", "\\.sbg", "\\.sbi", "\\.sbk", "\\.sc2", "\\.sd", "\\.sd", "\\.sd2", "\\.sd2f", "\\.sdat", "\\.sdii", "\\.sds", "\\.sdt", "\\.sdx", "\\.seg", "\\.seq", "\\.ses", "\\.sf", "\\.sf2", "\\.sfk", "\\.sfl", "\\.shn", "\\.sib", "\\.sid", "\\.sid", "\\.smf", "\\.smp", "\\.snd", "\\.snd", "\\.snd", "\\.sng", "\\.sng", "\\.sou", "\\.sppack", "\\.sprg", "\\.spx", "\\.sseq", "\\.sseq", "\\.ssnd", "\\.stm", "\\.stx", "\\.sty", "\\.svx", "\\.sw", "\\.swa", "\\.syh", "\\.syw", "\\.syx", "\\.td0", "\\.tfmx", "\\.thx", "\\.toc", "\\.tsp", "\\.txw", "\\.u", "\\.ub", "\\.ulaw", "\\.ult", "\\.ulw", "\\.uni", "\\.usf", "\\.usflib", "\\.uw", "\\.uwf", "\\.vag", "\\.val", "\\.vc3", "\\.vmd", "\\.vmf", "\\.vmf", "\\.voc", "\\.voi", "\\.vox", "\\.vpm", "\\.vqf", "\\.vrf", "\\.vyf", "\\.w01", "\\.wav", "\\.wav", "\\.wave", "\\.wax", "\\.wfb", "\\.wfd", "\\.wfp", "\\.wma", "\\.wow", "\\.wpk", "\\.wproj", "\\.wrk", "\\.wus", "\\.wut", "\\.wv", "\\.wvc", "\\.wve", "\\.wwu", "\\.xa", "\\.xa", "\\.xfs", "\\.xi", "\\.xm", "\\.xmf", "\\.xmi", "\\.xmz", "\\.xp", "\\.xrns", "\\.xsb", "\\.xspf", "\\.xt", "\\.xwb", "\\.ym", "\\.zvd", "\\.zvr" };
public static final String[] SUBTRACK_EXTENSIONS = { ".srt", ".ssa", ".smi", ".txt", ".sub", ".ass" };
public static final Pattern VIDEO_EXTENSIONS_PATTERN;
public static final Pattern AUDIO_EXTENSIONS_PATTERN;
public static final Pattern EXTENSIONS_PATTERN;
public static final Pattern SUBTRACK_EXTENSIONS_PATTERN;
static {
EXTENSIONS = ArrayUtils.concat(VIDEO_EXTENSIONS, AUDIO_EXTENSIONS);
EXTENSIONS_PATTERN = generatePattern(EXTENSIONS);
VIDEO_EXTENSIONS_PATTERN = generatePattern(VIDEO_EXTENSIONS);
AUDIO_EXTENSIONS_PATTERN = generatePattern(AUDIO_EXTENSIONS);
SUBTRACK_EXTENSIONS_PATTERN = generatePattern(SUBTRACK_EXTENSIONS);
}
public static boolean isVideoOrAudio(String url) {
return EXTENSIONS_PATTERN.matcher(url.trim()).find();
}
public static boolean isVideoOrAudio(File file) {
return EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isVideo(String url) {
return VIDEO_EXTENSIONS_PATTERN.matcher(url.trim()).find();
}
public static boolean isVideo(File file) {
return VIDEO_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isAudio(String url) {
return AUDIO_EXTENSIONS_PATTERN.matcher(url.trim()).find();
}
public static boolean isAudio(File file) {
return AUDIO_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isSubTrack(File file) {
return SUBTRACK_EXTENSIONS_PATTERN.matcher(file.getName().trim()).find();
}
public static boolean isNative(String uri) {
uri = Uri.decode(uri);
return uri != null && (uri.startsWith("/") || uri.startsWith("content:") || uri.startsWith("file:"));
}
private static Pattern generatePattern(String[] args) {
StringBuffer sb = new StringBuffer();
for (String ext : args) {
if (sb.length() > 0)
sb.append("|");
sb.append(ext);
}
return Pattern.compile("(" + sb.toString() + ")$", Pattern.CASE_INSENSITIVE);
}
}
================================================
FILE: src/com/nmbb/oplayer/util/PinyinUtils.java
================================================
package com.nmbb.oplayer.util;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public final class PinyinUtils {
private static HanyuPinyinOutputFormat spellFormat = new HanyuPinyinOutputFormat();
static {
spellFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
spellFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
//spellFormat.setVCharType(HanyuPinyinVCharType.WITH_V);
}
public static String chineneToSpell(String chineseStr) throws BadHanyuPinyinOutputFormatCombination {
StringBuffer result = new StringBuffer();
for (char c : chineseStr.toCharArray()) {
if (c > 128) {
String[] array = PinyinHelper.toHanyuPinyinStringArray(c, spellFormat);
if (array != null && array.length > 0)
result.append(array[0]);
else
result.append(" ");
} else
result.append(c);
}
return result.toString();
}
}
================================================
FILE: src/com/nmbb/oplayer/util/StringUtils.java
================================================
package com.nmbb.oplayer.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;
import android.text.TextPaint;
import com.nmbb.oplayer.exception.Logger;
/**
* 字符串工具类
*
* @author tangjun
*
*/
public class StringUtils {
public static final String EMPTY = "";
private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
private static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd hh:mm:ss";
/** 用于生成文件 */
private static final String DEFAULT_FILE_PATTERN = "yyyy-MM-dd-HH-mm-ss";
private static final double KB = 1024.0;
private static final double MB = 1048576.0;
private static final double GB = 1073741824.0;
public static final SimpleDateFormat DATE_FORMAT_PART = new SimpleDateFormat(
"HH:mm");
public static String currentTimeString() {
return DATE_FORMAT_PART.format(Calendar.getInstance().getTime());
}
public static char chatAt(String pinyin, int index) {
if (pinyin != null && pinyin.length() > 0)
return pinyin.charAt(index);
return ' ';
}
/** 获取字符串宽度 */
public static float GetTextWidth(String Sentence, float Size) {
if (isEmpty(Sentence))
return 0;
TextPaint FontPaint = new TextPaint();
FontPaint.setTextSize(Size);
return FontPaint.measureText(Sentence.trim()) + (int) (Size * 0.1); // 留点余地
}
/**
* 格式化日期字符串
*
* @param date
* @param pattern
* @return
*/
public static String formatDate(Date date, String pattern) {
SimpleDateFormat format = new SimpleDateFormat(pattern);
return format.format(date);
}
/**
* 格式化日期字符串
*
* @param date
* @return 例如2011-3-24
*/
public static String formatDate(Date date) {
return formatDate(date, DEFAULT_DATE_PATTERN);
}
public static String formatDate(long date) {
return formatDate(new Date(date), DEFAULT_DATE_PATTERN);
}
/**
* 获取当前时间 格式为yyyy-MM-dd 例如2011-07-08
*
* @return
*/
public static String getDate() {
return formatDate(new Date(), DEFAULT_DATE_PATTERN);
}
/** 生成一个文件名,不含后缀 */
public static String createFileName() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat format = new SimpleDateFormat(DEFAULT_FILE_PATTERN);
return format.format(date);
}
/**
* 获取当前时间
*
* @return
*/
public static String getDateTime() {
return formatDate(new Date(), DEFAULT_DATETIME_PATTERN);
}
/**
* 格式化日期时间字符串
*
* @param date
* @return 例如2011-11-30 16:06:54
*/
public static String formatDateTime(Date date) {
return formatDate(date, DEFAULT_DATETIME_PATTERN);
}
public static String formatDateTime(long date) {
return formatDate(new Date(date), DEFAULT_DATETIME_PATTERN);
}
/**
* 格林威时间转换
*
* @param gmt
* @return
*/
public static String formatGMTDate(String gmt) {
TimeZone timeZoneLondon = TimeZone.getTimeZone(gmt);
return formatDate(Calendar.getInstance(timeZoneLondon)
.getTimeInMillis());
}
/**
* 拼接数组
*
* @param array
* @param separator
* @return
*/
public static String join(final ArrayList array,
final String separator) {
StringBuffer result = new StringBuffer();
if (array != null && array.size() > 0) {
for (String str : array) {
result.append(str);
result.append(separator);
}
result.delete(result.length() - 1, result.length());
}
return result.toString();
}
public static String join(final Iterator iter,
final String separator) {
StringBuffer result = new StringBuffer();
if (iter != null) {
while (iter.hasNext()) {
String key = iter.next();
result.append(key);
result.append(separator);
}
if (result.length() > 0)
result.delete(result.length() - 1, result.length());
}
return result.toString();
}
/**
* 判断字符串是否为空
*
* @param str
* @return
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
*
* @param str
* @return
*/
public static String trim(String str) {
return str == null ? EMPTY : str.trim();
}
/**
* 转换时间显示
*
* @param time
* 毫秒
* @return
*/
public static String generateTime(long time) {
int totalSeconds = (int) (time / 1000);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes,
seconds) : String.format("%02d:%02d", minutes, seconds);
}
/** 根据秒速获取时间格式 */
public static String gennerTime(int totalSeconds) {
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
return String.format("%02d:%02d", minutes, seconds);
}
/**
* 转换文件大小
*
* @param size
* @return
*/
public static String generateFileSize(long size) {
String fileSize;
if (size < KB)
fileSize = size + "B";
else if (size < MB)
fileSize = String.format("%.1f", size / KB) + "KB";
else if (size < GB)
fileSize = String.format("%.1f", size / MB) + "MB";
else
fileSize = String.format("%.1f", size / GB) + "GB";
return fileSize;
}
public static String getTimeDiff(long time) {
// Calendar cal = Calendar.getInstance();
long diff = 0;
// Date dnow = cal.getTime();
String str = "";
diff = System.currentTimeMillis() - time;
if (diff > 2592000000L) {// 30 * 24 * 60 * 60 * 1000=2592000000 毫秒
str = "1个月前";
} else if (diff > 1814400000) {// 21 * 24 * 60 * 60 * 1000=1814400000 毫秒
str = "3周前";
} else if (diff > 1209600000) {// 14 * 24 * 60 * 60 * 1000=1209600000 毫秒
str = "2周前";
} else if (diff > 604800000) {// 7 * 24 * 60 * 60 * 1000=604800000 毫秒
str = "1周前";
} else if (diff > 86400000) { // 24 * 60 * 60 * 1000=86400000 毫秒
// System.out.println("X天前");
str = (int) Math.floor(diff / 86400000f) + "天前";
} else if (diff > 18000000) {// 5 * 60 * 60 * 1000=18000000 毫秒
// System.out.println("X小时前");
str = (int) Math.floor(diff / 18000000f) + "小时前";
} else if (diff > 60000) {// 1 * 60 * 1000=60000 毫秒
// System.out.println("X分钟前");
str = (int) Math.floor(diff / 60000) + "分钟前";
} else {
str = (int) Math.floor(diff / 1000) + "秒前";
}
return str;
}
/**
* 截取字符串
*
* @param search
* 待搜索的字符串
* @param start
* 起始字符串 例如:
* @param end
* 结束字符串 例如:
* @param defaultValue
* @return
*/
public static String substring(String search, String start, String end,
String defaultValue) {
int start_len = start.length();
int start_pos = StringUtils.isEmpty(start) ? 0 : search.indexOf(start);
if (start_pos > -1) {
int end_pos = StringUtils.isEmpty(end) ? -1 : search.indexOf(end,
start_pos + start_len);
if (end_pos > -1)
return search.substring(start_pos + start.length(), end_pos);
else
return search.substring(start_pos + start.length());
}
return defaultValue;
}
/**
* 截取字符串
*
* @param search
* 待搜索的字符串
* @param start
* 起始字符串 例如:
* @param end
* 结束字符串 例如:
* @return
*/
public static String substring(String search, String start, String end) {
return substring(search, start, end, "");
}
/**
* 拼接字符串
*
* @param strs
* @return
*/
public static String concat(String... strs) {
StringBuffer result = new StringBuffer();
if (strs != null) {
for (String str : strs) {
if (str != null)
result.append(str);
}
}
return result.toString();
}
/** 获取中文字符个数 */
public static int getChineseCharCount(String str) {
String tempStr;
int count = 0;
for (int i = 0; i < str.length(); i++) {
tempStr = String.valueOf(str.charAt(i));
if (tempStr.getBytes().length == 3) {
count++;
}
}
return count;
}
/** 获取英文字符个数 */
public static int getEnglishCount(String str) {
String tempStr;
int count = 0;
for (int i = 0; i < str.length(); i++) {
tempStr = String.valueOf(str.charAt(i));
if (!(tempStr.getBytes().length == 3)) {
count++;
}
}
return count;
}
public static String encode(String url) {
try {
return URLEncoder.encode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
Logger.e(e);
}
return url;
}
}
================================================
FILE: src/com/nmbb/oplayer/util/ToastUtils.java
================================================
package com.nmbb.oplayer.util;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.Toast;
import com.nmbb.oplayer.OPlayerApplication;
import com.nmbb.oplayer.R;
public class ToastUtils {
public static void showToast(int resID) {
showToast(OPlayerApplication.getContext(), Toast.LENGTH_SHORT, resID);
}
public static void showToast(String text) {
showToast(OPlayerApplication.getContext(), Toast.LENGTH_SHORT, text);
}
public static void showToast(Context ctx, int resID) {
showToast(ctx, Toast.LENGTH_SHORT, resID);
}
public static void showToast(Context ctx, String text) {
showToast(ctx, Toast.LENGTH_SHORT, text);
}
public static void showLongToast(Context ctx, int resID) {
showToast(ctx, Toast.LENGTH_LONG, resID);
}
public static void showLongToast(int resID) {
showToast(OPlayerApplication.getContext(), Toast.LENGTH_LONG, resID);
}
public static void showLongToast(Context ctx, String text) {
showToast(ctx, Toast.LENGTH_LONG, text);
}
public static void showLongToast(String text) {
showToast(OPlayerApplication.getContext(), Toast.LENGTH_LONG, text);
}
public static void showToast(Context ctx, int duration, int resID) {
showToast(ctx, duration, ctx.getString(resID));
}
public static void showToast(Context ctx, int duration, String text) {
Toast toast = Toast.makeText(ctx, text, duration);
View mNextView = toast.getView();
if (mNextView != null)
mNextView.setBackgroundResource(R.drawable.toast_frame);
toast.show();
// Toast.makeText(ctx, text, duration).show();
}
// public static void showToastOnUiThread(final String text) {
// showToastOnUiThread(FSAppliction.getCurrentActivity(), text);
// }
/** 在UI线程运行弹出 */
public static void showToastOnUiThread(final Activity ctx, final String text) {
if (ctx != null) {
ctx.runOnUiThread(new Runnable() {
@Override
public void run() {
showToast(ctx, text);
}
});
}
}
}
================================================
FILE: src/com/nmbb/oplayer/video/VideoThumbnailUtils.java
================================================
package com.nmbb.oplayer.video;
import android.graphics.Bitmap;
public final class VideoThumbnailUtils {
/** 获取视频的缩略图 */
public static Bitmap createVideoThumbnail() {
return null;
}
/** 获取视频的时长 */
public int getDuration() {
return 1;
}
/** 获取视频的高度 */
public int getVideoHeight() {
return 1;
}
/** 获取视频的宽度 */
public int getVideoWidth() {
return 1;
}
}