AssetFileDescriptor des = getAssets().openFd("GPSResp.dat");报错

本文介绍了解决Android应用程序中遇到的特定资产文件读取错误的方法。通过更改文件扩展名或使用不同的输入流方式,可以避免因文件压缩而导致的问题。

以下代码:

public void readAsset(View view){
		String result="";
    	try{
    		
    		AssetFileDescriptor des = getAssets().openFd("GPSResp.dat");
    		FileInputStream in = des.createInputStream();
    		
    		int length = in.available();
        	byte [] buffer = new byte[length];
        	in.read(buffer);
        	result = new String(buffer, "UTF-8");
        	System.out.println("result:" + result);
    	}
    	catch(IOException e){
    		e.printStackTrace();
    	}
    	catch(Exception e){
    		e.printStackTrace();
    	}
	}

会报如下错误:

08-01 18:38:52.785: W/System.err(3361): java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
08-01 18:38:52.786: W/System.err(3361): 	at android.content.res.AssetManager.openAssetFd(Native Method)
08-01 18:38:52.787: W/System.err(3361): 	at android.content.res.AssetManager.openFd(AssetManager.java:331)
08-01 18:38:52.788: W/System.err(3361): 	at com.example.testasset.MainActivity.readAsset(MainActivity.java:29)
08-01 18:38:52.789: W/System.err(3361): 	at java.lang.reflect.Method.invokeNative(Native Method)
08-01 18:38:52.789: W/System.err(3361): 	at java.lang.reflect.Method.invoke(Method.java:511)
08-01 18:38:52.790: W/System.err(3361): 	at android.view.View$1.onClick(View.java:3599)
08-01 18:38:52.791: W/System.err(3361): 	at android.view.View.performClick(View.java:4209)
08-01 18:38:52.792: W/System.err(3361): 	at android.view.View$PerformClick.run(View.java:17431)
08-01 18:38:52.793: W/System.err(3361): 	at android.os.Handler.handleCallback(Handler.java:725)
08-01 18:38:52.793: W/System.err(3361): 	at android.os.Handler.dispatchMessage(Handler.java:92)
08-01 18:38:52.794: W/System.err(3361): 	at android.os.Looper.loop(Looper.java:153)
08-01 18:38:52.795: W/System.err(3361): 	at android.app.ActivityThread.main(ActivityThread.java:5297)
08-01 18:38:52.796: W/System.err(3361): 	at java.lang.reflect.Method.invokeNative(Native Method)
08-01 18:38:52.797: W/System.err(3361): 	at java.lang.reflect.Method.invoke(Method.java:511)
08-01 18:38:52.797: W/System.err(3361): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
08-01 18:38:52.798: W/System.err(3361): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
08-01 18:38:52.799: W/System.err(3361): 	at dalvik.system.NativeStart.main(Native Method)

解决方案:


1.把

AssetFileDescriptor des = getAssets().openFd("GPSResp.dat");
    		FileInputStream in = des.createInputStream();
替换为

InputStream in = getResources().getAssets().open("GPSResp.dat");	

2.把扩展名改为mp3。


原因:参见http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/


担心网站某天不能访问了,文章抄录如下:

Dealing with Asset Compression in Android Apps


When developing an Android app, any data file, image or XML file (that is, any Resource or Asset) you use is bundled into your application package (APK) for distribution. The Android Asset Packaging Tool, or aapt, is responsible for creating this bundle, which you can think of as a ZIP file with a particular layout that the Android OS can understand. When your application is installed, whether in development mode or by an end user, this APK file is simply dropped into a special location on the device’s (or emulator’s) filesystem.

As part of preparing your APK, aapt selectively compresses various assets to save space on the device. The way aapt determines which assets need compression is by their file extension. The following code, taken from Package.cpp in the aaptsource code, sheds some light on which types of files are not compressed by default:

/* these formats are already compressed, or don't compress well */
static const char* kNoCompressExt[] = {
    ".jpg", ".jpeg", ".png", ".gif",
    ".wav", ".mp2", ".mp3", ".ogg", ".aac",
    ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
    ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
    ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
    ".amr", ".awb", ".wma", ".wmv"
};

The only way (that I’ve discovered, as of this writing) to control this behavior is by using the -0 (zero) flag to aapt on the command line. This flag, passed without any accompanying argument, will tell aapt to disable compression for all types of assets. Typically you will not want to use this exact option, because for most assets, compression is a desirable thing. Sometimes, however, you will have a specific type of asset (say, a database), that you do not want to apply compression to. In this case, you have two options.

First, you can give your asset file an extension in the list above. While this does not necessarily make sense, it can be an easy workaround if you don’t want to deal with aapt on the command line. The other option is to pass a specific extension to the -0 flag, such as -0 db, to disable compression for assets with that extension. You can pass the -0 flag multiple times, and each time with a separate extension, if you need more than one type to be uncompressed.

Currently, there is no way to pass these extra flags to aapt when using the ADT within Eclipse, so if you don’t want to sacrifice the ease of use of the GUI tools, you will have to go with the first option, and rename your file’s extension.

So, Why Disable Compression Anyway?

For most types of assets, you shouldn’t need to be concerned with how they are packaged. Given the list of extensions above, Android will do the right thing for a large subset of the files you’ll use. If you have a type of asset that is already compressed by nature of the file type, but doesn’t have one of the sanctioned extensions, you can typically ignore that inconsistency and just allow aapt to try to compress it. It will not be very much, if at all, smaller in the final APK, but the performance hit should be relatively minimal unless you just have tons of these files.

This begs the question, why even bother disabling compression? The not-so-obvious answer is that prior to Android 2.3, any compressed asset file with an uncompressed size of over 1 MB cannot be read from the APK. This could come into play if your asset needed to be copied out of the APK and into the app’s writable files area, for example to provide a pre-populated database in your app. When you try to use the various AssetManager or Resources classes’ methods to get an InputStream to the file, it will throw an exception and display a LogCat message like this:

DEBUG/asset(725): Data exceeds UNCOMPRESS_DATA_MAX (1662976 vs 1048576)

The only way around this type of issue is to disable compression for assets that exceed the 1 MB limit. If your file format supports it, you can choose to split the asset into several smaller files that have an uncompressed size of less than 1 MB each, but this can be a real annoyance.

Hopefully the knowledge in this post can help you avoid the headaches I went through to learn it!

Update March 1, 2011: The limit on the uncompressed size of compressed assets was removed in Android 2.3. So someday in the future, when you don’t have to worry about Android versions lower than 2.3, you can avoid this heartache.

This entry was posted in android. Bookmark the  permalinkPost a comment or leave a trackback:  Trackback URL.
另外一篇文章的连接地址: http://gossipcoder.com/?p=858

疑问:我的asset文件夹中的文件未超过1M,为什么还会报错?但是把扩展名改为.mp3后确实解决了问题。







package com.weixxkjsd.singkingcgzw.fragment.Adapter; import android.content.Context; import android.content.res.AssetFileDescriptor; import android.graphics.Color; import android.media.MediaPlayer; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.hfd.common.util.DensityUtil; import com.hw.lrcviewlib.LrcDataBuilder; import com.hw.lrcviewlib.LrcRow; import com.hw.lrcviewlib.LrcView; import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundLinearLayout; import com.weixxkjsd.singkingcgzw.MainActivity; import com.weixxkjsd.singkingcgzw.R; import com.weixxkjsd.singkingcgzw.bean.SongBean; import java.io.IOException; import java.util.List; public class MusicPagerAdapter extends RecyclerView.Adapter<MusicPagerAdapter.MusicViewHolder> { private Context context; private List<SongBean> musicList; List<LrcRow> lrcRows; private MediaPlayer mediaPlayer; public MusicPagerAdapter(Context context, List<SongBean> musicList) { this.context = context; this.musicList = musicList; } @NonNull @Override public MusicViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_music, parent, false); return new MusicViewHolder(view); } @Override public void onBindViewHolder(@NonNull MusicViewHolder holder, int position) { SongBean songBean = musicList.get(position); lrcRows = new LrcDataBuilder().BuiltFromAssets(context, songBean.getLrcPath()); holder.lyricView.getLrcSetting() .setTimeTextSize(40)//时间字体大小 .setSelectLineColor(Color.parseColor("#ff0000"))//选中线颜色 .setSelectLineTextSize(25)//选中线大小 .setNormalRowColor(Color.parseColor("#919191")) .setHeightRowColor(Color.parseColor("#ff0000"))//高亮字体颜色 .setNormalRowTextSize(DensityUtil.sp2px(context, 17))//正常行字体大小 .setHeightLightRowTextSize(DensityUtil.sp2px(context, 17))//高亮行字体大小 .setTrySelectRowTextSize(DensityUtil.sp2px(context, 17))//尝试选中行字体大小 .setTimeTextColor(Color.parseColor("#ff0000"))//时间字体颜色 .setTrySelectRowColor(Color.parseColor("#ff0000"));//尝试选中字体颜色 holder.lyricView.commitLrcSettings(); holder.lyricView.setLrcData(lrcRows); Log.i("11111111111111111",""+songBean.getSongFilePath()); if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); } try { //mediaPlayer.setDataSource(getActivity(), Uri.parse("file:///android_asset/大悲咒.mp3")); // 从assets目录获取文件描述符 AssetFileDescriptor afd = context.getAssets().openFd(songBean.getSongFilePath()); // 设置数据源 mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mediaPlayer.prepare(); } catch (IOException e) { Log.e("MusicMetadataHelper", "Failed to get MP3 file", e); } } @Override public int getItemCount() { return musicList.size(); } public static class MusicViewHolder extends RecyclerView.ViewHolder { LrcView lyricView; QMUIRoundLinearLayout qmuiRoundLinearLayout; public MusicViewHolder(@NonNull View itemView) { super(itemView); lyricView = itemView.findViewById(R.id.lyricView); qmuiRoundLinearLayout = itemView.findViewById(R.id.qmButton_start); } } } 如上代码,我在适配器获取 从assets目录获取文件描述符一直报错,怎么修改
11-13
package com.weixxkjsd.singkingcgzw.fragment.Adapter; import android.animation.ObjectAnimator; import android.content.Context; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.LinearInterpolator; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.hfd.common.util.DensityUtil; import com.hw.lrcviewlib.LrcDataBuilder; import com.hw.lrcviewlib.LrcRow; import com.hw.lrcviewlib.LrcView; import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundLinearLayout; import com.weixxkjsd.singkingcgzw.R; import com.weixxkjsd.singkingcgzw.bean.SongBean; import com.weixxkjsd.singkingcgzw.fragment.home.SingActivity; import com.weixxkjsd.singkingcgzw.utils.ImageUtils; import com.weixxkjsd.singkingcgzw.utils.OnMultiClickListener; import com.weixxkjsd.singkingcgzw.view.NonScrollableLrcView; import java.io.IOException; import java.util.List; public class MusicPagerAdapter extends RecyclerView.Adapter<MusicPagerAdapter.MusicViewHolder> { private Context context; private List<SongBean> musicList; List<LrcRow> lrcRows; private MediaPlayer mediaPlayer; private int currentPlayingPosition = 0; private ObjectAnimator recordAnimator; private boolean isPlaying = false; private Animation armUpAnimation; private Animation armDownAnimation ; public MusicPagerAdapter(Context context, List<SongBean> musicList) { this.context = context; this.musicList = musicList; } @NonNull @Override public MusicViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_music, parent, false); return new MusicViewHolder(view); } @Override public void onBindViewHolder(@NonNull MusicViewHolder holder, int position) { SongBean songBean = musicList.get(position); if (songBean.getIcon() == 1) { Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song1); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 2){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song2); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 3){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song3); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 4){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song4); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 5){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song5); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 6){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song6); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 7){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song7); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 8){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song8); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 9){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song9); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else if(songBean.getIcon() == 10){ Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song10); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); }else { Bitmap squareBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.song11); Bitmap circularBitmap = ImageUtils.getCircularBitmap(squareBitmap); holder.ivSong.setImageBitmap(circularBitmap); } lrcRows = new LrcDataBuilder().BuiltFromAssets(context, songBean.getLrcPath()); holder.lyricView.getLrcSetting() .setTimeTextSize(40)//时间字体大小 .setSelectLineColor(Color.parseColor("#ff0000"))//选中线颜色 .setSelectLineTextSize(25)//选中线大小 .setNormalRowColor(Color.parseColor("#919191")) .setHeightRowColor(Color.parseColor("#ff0000"))//高亮字体颜色 .setNormalRowTextSize(DensityUtil.sp2px(context, 17))//正常行字体大小 .setHeightLightRowTextSize(DensityUtil.sp2px(context, 17))//高亮行字体大小 .setTrySelectRowTextSize(DensityUtil.sp2px(context, 17))//尝试选中行字体大小 .setTimeTextColor(Color.parseColor("#ff0000"))//时间字体颜色 .setTrySelectRowColor(Color.parseColor("#ff0000"));//尝试选中字体颜色 holder.lyricView.commitLrcSettings(); holder.lyricView.setLrcData(lrcRows); if (position == currentPlayingPosition){ try { if (mediaPlayer != null) { mediaPlayer.release(); } mediaPlayer = new MediaPlayer(); AssetFileDescriptor afd = context.getAssets().openFd(songBean.getSongFilePath()); mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mediaPlayer.prepare(); mediaPlayer.start(); isPlaying = true; // 执行黑胶唱片机臂从 -10 度旋转到 0 度的动画 Animation armAnimation = AnimationUtils.loadAnimation(context, R.anim.arm_up); holder.ivArm.startAnimation(armAnimation); } catch (IOException e) { e.printStackTrace(); } } // 初始化唱片旋转动画 recordAnimator = ObjectAnimator.ofFloat(holder.ivSong, "rotation", 0f, 360f); recordAnimator.setDuration(5000); recordAnimator.setInterpolator(new LinearInterpolator()); recordAnimator.setRepeatCount(ObjectAnimator.INFINITE); if (isPlaying) { recordAnimator.start(); } else { recordAnimator.pause(); } if (armUpAnimation == null) { armUpAnimation = AnimationUtils.loadAnimation(context, R.anim.arm_up); armDownAnimation = AnimationUtils.loadAnimation(context, R.anim.arm_down); // 设置动画保持最终状态 armUpAnimation.setFillAfter(true); armDownAnimation.setFillAfter(true); } // 设置点击事件 holder.ivRecord.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mediaPlayer != null) { if (isPlaying) { mediaPlayer.pause(); recordAnimator.pause(); // 重置唱片机臂的旋转角度 holder.ivArm.startAnimation(armDownAnimation); } else { mediaPlayer.start(); recordAnimator.resume(); holder.ivArm.startAnimation(armUpAnimation); } isPlaying = !isPlaying; } } }); holder.qmuiRoundLinearLayout.setOnClickListener(new OnMultiClickListener() { @Override public void onMultiClick(View v) { Intent intent = new Intent(context,SingActivity.class); intent.putExtra("index", position); context.startActivity(intent); } }); } @Override public int getItemCount() { return musicList.size(); } public void pauseMusic() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); isPlaying = false; if (recordAnimator != null) { recordAnimator.pause(); } } } public void resumeMusic(int position) { currentPlayingPosition = position; notifyDataSetChanged(); } public static class MusicViewHolder extends RecyclerView.ViewHolder { LrcView lyricView; QMUIRoundLinearLayout qmuiRoundLinearLayout; ImageView ivRecord,ivArm,ivSong; public MusicViewHolder(@NonNull View itemView) { super(itemView); lyricView = itemView.findViewById(R.id.lyricView); qmuiRoundLinearLayout = itemView.findViewById(R.id.qmButton_start); ivRecord = itemView.findViewById(R.id.iv_record); ivArm = itemView.findViewById(R.id.iv_arm); ivSong = itemView.findViewById(R.id.iv_song); } } } lyricView歌词不滚动
11-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值