Android 保存多媒体文件至sdCard(兼容Android10以上及以下)

本demo的功能是将assets文件夹中的图片、音频、视频保存至sd card中,对android 10 以上和以下均作了处理。
在这里插入图片描述

1、基础配置

权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

layout

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!--    图片    -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/id_btn_save_image"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="save image"
                android:textColor="@color/white"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/id_btn_show_image"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="show image"
                android:textColor="@color/white"
                android:textSize="30dp" />

        </LinearLayout>

        <ImageView
            android:id="@+id/id_image"
            android:layout_width="180dp"
            android:layout_height="140dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="10dp"
            android:background="@color/gray" />

        <View
            android:layout_width="match_parent"
            android:layout_marginTop="10dp"
            android:layout_height="2dp"
            android:background="@color/gray"/>


        <!--    音频    -->
        <TextView
            android:id="@+id/id_btn_save_music"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="10dp"
            android:background="@color/black"
            android:gravity="center_horizontal"
            android:paddingTop="10dp"
            android:paddingBottom="10dp"
            android:text="save music"
            android:textColor="@color/white"
            android:textSize="30dp" />


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/id_btn_play_music"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="play music"
                android:textColor="@color/white"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/id_btn_pause_music"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="pause music"
                android:textColor="@color/white"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/id_btn_stop_music"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="stop music"
                android:textColor="@color/white"
                android:textSize="30dp" />

        </LinearLayout>

        <View
            android:layout_width="match_parent"
            android:layout_marginTop="10dp"
            android:layout_height="2dp"
            android:background="@color/gray"/>

        <!--    视频   -->
        <TextView
            android:id="@+id/id_btn_save_video"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="10dp"
            android:background="@color/black"
            android:gravity="center_horizontal"
            android:paddingTop="10dp"
            android:paddingBottom="10dp"
            android:text="save video"
            android:textColor="@color/white"
            android:textSize="30dp" />


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/id_btn_play_video"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="play video"
                android:textColor="@color/white"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/id_btn_pause_video"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="pause video"
                android:textColor="@color/white"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/id_btn_stop_video"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:layout_weight="1"
                android:background="@color/black"
                android:gravity="center_horizontal"
                android:paddingTop="10dp"
                android:paddingBottom="10dp"
                android:text="stop video"
                android:textColor="@color/white"
                android:textSize="30dp" />

        </LinearLayout>


        <VideoView
            android:id="@+id/id_video_view"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            android:layout_gravity="center_horizontal" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp" />
    </LinearLayout>

</ScrollView>

BaseActivity

abstract public class BaseActivity extends AppCompatActivity {


    @BindView(R.id.id_image)
    ImageView imageView;
    @BindView(R.id.id_btn_save_image)
    protected TextView btnSaveImage;
    @BindView(R.id.id_btn_show_image)
    protected TextView btnShowImage;

    @BindView(R.id.id_btn_save_music)
    protected TextView btnSaveMusic;
    @BindView(R.id.id_btn_play_music)
    protected TextView btnPlayMusic;
    @BindView(R.id.id_btn_pause_music)
    protected TextView btnPauseMusic;
    @BindView(R.id.id_btn_stop_music)
    protected TextView btnStopMusic;

    @BindView(R.id.id_video_view)
    VideoView videoView;
    @BindView(R.id.id_btn_save_video)
    protected TextView btnSaveVideo;
    @BindView(R.id.id_btn_play_video)
    protected TextView btnPlayVideo;
    @BindView(R.id.id_btn_pause_video)
    protected TextView btnPauseVideo;
    @BindView(R.id.id_btn_stop_video)
    protected TextView btnStopVideo;

	private Unbinder unbinder = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_base);
        unbinder = ButterKnife.bind(this);
        initView();
    }

	@Override
    protected void onDestroy() {
        super.onDestroy();
        if (unbinder != null) {
            unbinder.unbind();
        }
    }

    /**
     * 初始化界面
     */
    abstract protected void initView();

    /**
     * 获取 Activity
     *
     * @return
     */
    protected BaseActivity getActivity() {
        return this;
    }

    /**
     * 提示信息
     *
     * @param tips
     */
    protected void disPlayTips(String tips) {
        Toast.makeText(getActivity(), tips, Toast.LENGTH_SHORT).show();
    }
}

2、代码示例

Activity

public class SdCardActivity extends BaseActivity {

    public static final String TAG = "SdCardActivity";

    public static final int PERMISSION_REQUEST_CODE = 1;

    private SdCardManager imageSdCardManager = null;
    private SdCardManager musicSdCardManager = null;
    private SdCardManager videoSdCardManager = null;
    private MediaPlayer musicMediaPlayer = null;

    @Override
    protected void initView() {

        imageSdCardManager = new SdCardManager(getActivity(), "test_image.png", SdCardManager.TYPE_IMAGE);
        musicSdCardManager = new SdCardManager(getActivity(), "test_music.mp3", SdCardManager.TYPE_AUDIO);
        videoSdCardManager = new SdCardManager(getActivity(), "test_video.mp4", SdCardManager.TYPE_VIDEO);


        //权限申请
        ActivityCompat.requestPermissions(this, new String[]{READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);

        //保存图片
        btnSaveImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                imageSdCardManager.saveMediaToSdCard();
                if (imageSdCardManager.getMediaUriFromSdCard() != null) {
                    disPlayTips("图片保存成功");
                }
            }
        });

        //展示图片
        btnShowImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Uri imageUri = imageSdCardManager.getMediaUriFromSdCard();
                    ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(imageUri, "r");
                    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
                    Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
                    parcelFileDescriptor.close();
                    imageView.setImageBitmap(bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(TAG, "------ show picture Exception : " + e.getMessage());
                }
            }
        });

        //保存音乐
        btnSaveMusic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                musicSdCardManager.saveMediaToSdCard();
                Uri musicUri = musicSdCardManager.getMediaUriFromSdCard();
                if (musicUri != null) {
                    musicMediaPlayer = MediaPlayer.create(getActivity(), musicUri);
                    disPlayTips("音乐保存成功");
                }
            }
        });

        //播放音乐
        btnPlayMusic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (musicMediaPlayer != null) {
                    musicMediaPlayer.start();
                }
            }
        });

        //暂停音乐
        btnPauseMusic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (musicMediaPlayer != null) {
                    musicMediaPlayer.pause();
                }
            }
        });

        //停止音乐
        btnStopMusic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (musicMediaPlayer != null) {
                    musicMediaPlayer.stop();
                }
            }
        });

        //保存视频
        btnSaveVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                videoSdCardManager.saveMediaToSdCard();
                Uri videoUri = videoSdCardManager.getMediaUriFromSdCard();
                if (videoUri != null) {
                    disPlayTips("视频保存成功");
                    videoView.setVideoURI(videoUri);
                }
            }
        });

        //播放视频
        btnPlayVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoSdCardManager.getMediaUriFromSdCard() != null) {
                    videoView.start();
                }
            }
        });

        //暂停视频
        btnPauseVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoSdCardManager.getMediaUriFromSdCard() != null) {
                    videoView.pause();
                }
            }
        });

        //停止视频
        btnStopVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoSdCardManager.getMediaUriFromSdCard() != null) {
                    videoView.stopPlayback();
                }
            }
        });


    }
}

SdCardManager

public class SdCardManager {

    public static final String TAG = "SdCardManager";

    /**
     * BUFFER_SIZE  缓存区大小
     */
    public static final int BUFFER_SIZE = 4096;

    /**
     * TYPE_IMAGE  图片
     * TYPE_AUDIO  音频
     * TYPE_VIDEO  视频
     */
    public static final String TYPE_IMAGE = "image/jpeg";
    public static final String TYPE_AUDIO = "audio/mpeg";
    public static final String TYPE_VIDEO = "video/mp4";

    /**
     * mediaUri  Android 10 及以上 多媒体文件 uri
     */
    private Uri mediaUri = null;


    /**
     * Android 10 以下 多媒体文件保存路径
     * <p>
     * SAVE_PATH_IMAGE  图片路径
     * SAVE_PATH_AUDIO  音频路径
     * SAVE_PATH_VIDEO  视频路径
     */
    public static final String SAVE_PATH_IMAGE = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Image";
    public static final String SAVE_PATH_AUDIO = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Music";
    public static final String SAVE_PATH_VIDEO = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Video";


    /**
     * 需要的参数
     */
    private Context context = null;
    private String fileName = null;
    private String miniType = null;

    /**
     * 构造函数
     *
     * @param context
     * @param fileName
     * @param miniType
     */
    public SdCardManager(Context context, String fileName, String miniType) {
        this.context = context;
        this.fileName = fileName;
        this.miniType = miniType;
    }

    /**
     * 获取 assets 中的文件
     *
     * @return
     * @throws IOException
     */
    private InputStream getInputStreamFromAssets() throws IOException {
        return context.getResources().getAssets().open(fileName);
    }


    /**
     * 根据 miniType 获取 ContentValues
     *
     * @return
     */
    private ContentValues getContentValuesByMiniType() {
        if (miniType.equals(TYPE_IMAGE)) {
            //图片
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
            contentValues.put(MediaStore.Images.Media.MIME_TYPE, miniType);
            contentValues.put(MediaStore.Images.Media.DESCRIPTION, "This is a picture");
            contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM);
            return contentValues;
        } else if (miniType.equals(TYPE_AUDIO)) {
            //音频
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, fileName);
            contentValues.put(MediaStore.Audio.Media.MIME_TYPE, miniType);
            contentValues.put(MediaStore.Audio.Media.RELATIVE_PATH, Environment.DIRECTORY_MUSIC);
            return contentValues;
        } else if (miniType.equals(TYPE_VIDEO)) {
            //视频
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.Video.Media.DISPLAY_NAME, fileName);
            contentValues.put(MediaStore.Video.Media.MIME_TYPE, miniType);
            contentValues.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES);
            return contentValues;
        } else {
            return null;
        }
    }


    /**
     * 通过 miniType 获取媒体库的 uri
     *
     * @return
     */
    private Uri getUriByMiniType() {
        if (miniType.equals(TYPE_IMAGE)) {
            //图片
            return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if (miniType.equals(TYPE_AUDIO)) {
            //音频
            return MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        } else if (miniType.equals(TYPE_VIDEO)) {
            //视频
            return MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        }
        return null;
    }


    /**
     * 根据 uri 删除旧的文件
     */
    private void deleteFileByMiniType() {
        if (miniType.equals(TYPE_IMAGE)) {
            //图片
            context.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.DISPLAY_NAME + "=?", new String[]{fileName});
        } else if (miniType.equals(TYPE_AUDIO)) {
            //音频
            context.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MediaStore.Audio.Media.DISPLAY_NAME + "=?", new String[]{fileName});
        } else if (miniType.equals(TYPE_VIDEO)) {
            //视频
            context.getContentResolver().delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, MediaStore.Video.Media.DISPLAY_NAME + "=?", new String[]{fileName});
        }
    }


    /**
     * 保存多媒体文件到 sdCard
     *
     * @return
     */
    public void saveMediaToSdCard() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //Android 10 及以上
                ContentValues contentValues = getContentValuesByMiniType();
                ContentResolver contentResolver = context.getContentResolver();
                deleteFileByMiniType();
                mediaUri = contentResolver.insert(getUriByMiniType(), contentValues);
                if (mediaUri != null) {
                    ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(mediaUri, "w");
                    FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
                    InputStream inputStream = getInputStreamFromAssets();
                    byte[] buffer = new byte[BUFFER_SIZE];
                    while (true) {
                        int numRead = inputStream.read(buffer);
                        if (numRead == -1) {
                            break;
                        }
                        fileOutputStream.write(buffer, 0, numRead);
                    }
                    fileOutputStream.flush();
                    fileOutputStream.close();
                    parcelFileDescriptor.close();
                }
            } else {
                //Android 10 以下
                String savePath = getSavePathByMiniType();
                File dir = new File(savePath);
                if (!dir.exists()) {
                    dir.mkdir();
                }
                File file = new File(dir, fileName);
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                InputStream inputStream = getInputStreamFromAssets();
                byte[] buffer = new byte[BUFFER_SIZE];
                while (true) {
                    int numRead = inputStream.read(buffer);
                    if (numRead == -1) {
                        break;
                    }
                    fileOutputStream.write(buffer, 0, numRead);
                }
                fileOutputStream.flush();
                //保存后发送广播通知更新数据库
                Uri uri = Uri.fromFile(file);
                context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
                fileOutputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "------ save Exception : " + e.getMessage());
        }
    }


    /**
     * Android10以下,获取文件保存路径
     *
     * @return
     */
    private String getSavePathByMiniType() {
        String savePath = "";
        if (miniType.equals(TYPE_IMAGE)) {
            //图片
            savePath = SAVE_PATH_IMAGE;
        } else if (miniType.equals(TYPE_AUDIO)) {
            //音频
            savePath = SAVE_PATH_AUDIO;
        } else if (miniType.equals(TYPE_VIDEO)) {
            //视频
            savePath = SAVE_PATH_VIDEO;
        }
        return savePath;
    }


    /**
     * 获取 sd card 中媒体文件的 uri
     *
     * @return
     */
    public Uri getMediaUriFromSdCard() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            //Android 10 及以上
            return mediaUri;
        } else {
            //Android 10 以下
            File dir = new File(getSavePathByMiniType());
            File file = new File(dir, fileName);
            return Uri.fromFile(file);
        }
    }
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KillerNoBlood

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值