Android - สอบถามปัญหาเรื่อง การดึงข้อมูลไฟล์ GIF จาก SD Card มาแสดง แต่ไม่สามารถแสดงได้ทุกเครื่อง ควรแก้ปัญหาอย่างไรครับ
ผมใช้โค๊ดนี้ ซึ่งมันสามารถแสดงไฟล์ gif จาก sd card ได้กับเครื่องหนึ่งซึ่งเป็น android version 4.4.2 แต่เมื่อผมนำมารันกับเครื่องอื่นปรากฏว่าไม่สามารถแสดงไฟล์ gif ได้ อยากทราบว่าโค๊ดของผมมีปัญหาตรงส่วนไหนครับ
Code (Android-Java)
@SuppressLint("SdCardPath")
private String SrcPathConfigfileGif = "/sdcard/data/gif.txt";
private String lineGif;
private Runnable runnableGif;
private int gifIndex;
private Handler mHandlerGif;
private ArrayList<String> gifList;
private GifMovieView gmv;
@SuppressLint("SdCardPath")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gmv = (GifMovieView) findViewById(R.id.gifMovieView);
//GifMovieView gmv = (GifMovieView) findViewById(R.id.gifMovieView);
//gmv.setMovieResource(R.drawable.apple);
gifList = new ArrayList<String>();
mHandlerGif = new Handler();
// timer = new Timer();
try {
File file = new File(SrcPathConfigfileGif);
@SuppressWarnings("resource")
BufferedReader bufferRead = new BufferedReader(new FileReader(file));
while ((lineGif = bufferRead.readLine()) != null) {
String SrcPathImage = "/sdcard/data/gif/" + lineGif;
gifList.add(SrcPathImage);
}
PlayGif();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(Main.this,
"Failed! Image = " + e.getMessage(), Toast.LENGTH_LONG)
.show();
}
}
public void PlayGif() {
runnableGif = new Runnable() {
public void run() {
for (gifIndex = 0; gifIndex <= gifList.size(); gifIndex = (gifIndex + 1) % gifList.size()) {
mHandlerGif.post(new Runnable() {
public void run() {
String srcTimePeriod = gifList.get(gifIndex
% gifList.size());
gmv.setMoviePathfile(srcTimePeriod);
}
});
SystemClock.sleep(10000);
}
}
};
new Thread(runnableGif).start();
}
}
ส่วนอันนี้เป็นคลาสที่ไว้ใช้ทำงานแสดง Gif ครับ
Code (Android-Java)
public class GifMovieView extends View {
private static final int DEFAULT_MOVIEW_DURATION = 1000;
private int mMovieResourceId;
private Movie mMovie;
private long mMovieStart;
private int mCurrentAnimationTime = 0;
/**
* Position for drawing animation frames in the center of the view.
*/
private float mLeft;
private float mTop;
/**
* Scaling factor to fit the animation within view bounds.
*/
private float mScale;
/**
* Scaled movie frames width and height.
*/
private int mMeasuredMovieWidth;
private int mMeasuredMovieHeight;
private volatile boolean mPaused = false;
private boolean mVisible = true;
public GifMovieView(Context context) {
this(context, null);
}
public GifMovieView(Context context, AttributeSet attrs) {
this(context, attrs, R.styleable.CustomTheme_gifMoviewViewStyle);
}
public GifMovieView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setViewAttributes(context, attrs, defStyle);
}
@SuppressLint("NewApi")
private void setViewAttributes(Context context, AttributeSet attrs, int defStyle) {
/**
* Starting from HONEYCOMB have to turn off HW acceleration to draw
* Movie on Canvas.
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifMoviewView, defStyle,
R.style.Widget_GifMoviewView);
mMovieResourceId = array.getResourceId(R.styleable.GifMoviewView_gif, -1);
mPaused = array.getBoolean(R.styleable.GifMoviewView_paused, false);
array.recycle();
if (mMovieResourceId != -1) {
mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
}
}
public void setMovieResource(int movieResId) {
this.mMovieResourceId = movieResId;
mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
requestLayout();
}
public void setMoviePathfile(String pathfile){
mMovie = Movie.decodeFile(pathfile);
requestLayout();
}
public void setMovie(Movie movie) {
this.mMovie = movie;
requestLayout();
}
public Movie getMovie() {
return mMovie;
}
public void setMovieTime(int time) {
mCurrentAnimationTime = time;
invalidate();
}
public void setPaused(boolean paused) {
this.mPaused = paused;
/**
* Calculate new movie start time, so that it resumes from the same
* frame.
*/
if (!paused) {
mMovieStart = android.os.SystemClock.uptimeMillis() - mCurrentAnimationTime;
}
invalidate();
}
public boolean isPaused() {
return this.mPaused;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mMovie != null) {
int movieWidth = mMovie.width();
int movieHeight = mMovie.height();
/*
* Calculate horizontal scaling
*/
float scaleH = 1f;
int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);
if (measureModeWidth != MeasureSpec.UNSPECIFIED) {
int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
if (movieWidth > maximumWidth) {
scaleH = (float) movieWidth / (float) maximumWidth;
}
}
/*
* calculate vertical scaling
*/
float scaleW = 1f;
int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);
if (measureModeHeight != MeasureSpec.UNSPECIFIED) {
int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);
if (movieHeight > maximumHeight) {
scaleW = (float) movieHeight / (float) maximumHeight;
}
}
/*
* calculate overall scale
*/
mScale = 1f / Math.max(scaleH, scaleW);
mMeasuredMovieWidth = (int) (movieWidth * mScale);
mMeasuredMovieHeight = (int) (movieHeight * mScale);
setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);
} else {
/*
* No movie set, just set minimum available size.
*/
setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
/*
* Calculate left / top for drawing in center
*/
mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;
mTop = (getHeight() - mMeasuredMovieHeight) / 2f;
mVisible = getVisibility() == View.VISIBLE;
}
@Override
protected void onDraw(Canvas canvas) {
if (mMovie != null) {
if (!mPaused) {
updateAnimationTime();
drawMovieFrame(canvas);
invalidateView();
} else {
drawMovieFrame(canvas);
}
}
}
/**
* Invalidates view only if it is visible.
* <br>
* {@link #postInvalidateOnAnimation()} is used for Jelly Bean and higher.
*
*/
@SuppressLint("NewApi")
private void invalidateView() {
if(mVisible) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
postInvalidateOnAnimation();
} else {
invalidate();
}
}
}
/**
* Calculate current animation time
*/
private void updateAnimationTime() {
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) {
mMovieStart = now;
}
int dur = mMovie.duration();
if (dur == 0) {
dur = DEFAULT_MOVIEW_DURATION;
}
mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
}
/**
* Draw current GIF frame
*/
private void drawMovieFrame(Canvas canvas) {
mMovie.setTime(mCurrentAnimationTime);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScale, mScale);
mMovie.draw(canvas, mLeft / mScale, mTop / mScale);
canvas.restore();
}
@SuppressLint("NewApi")
@Override
public void onScreenStateChanged(int screenState) {
super.onScreenStateChanged(screenState);
mVisible = screenState == SCREEN_STATE_ON;
invalidateView();
}
@SuppressLint("NewApi")
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
mVisible = visibility == View.VISIBLE;
invalidateView();
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
mVisible = visibility == View.VISIBLE;
invalidateView();
}
}
โดยตัวอย่างนี้ผมนำมาจาก http://www.akexorcist.com/2013/07/android-code-gif-animation.htmlTag : Mobile, Android
Date :
2014-04-19 20:52:24
By :
KIT
View :
1206
Reply :
3
ผมตรวจสอบไม่ได้ครับ
Date :
2014-04-20 15:19:49
By :
mr.win
Load balance : Server 01