Android下载图片到相册

2018-12-11 10:20:40

原理 一     整体代码再后面

github地址:(完整demo,欢迎下载)
https://github.com/zhouxu88/SaveImgToGallery/tree/master

Adnroid中保存图片的方法可能有如下两种:

  • 第一种是调用系统提供的插入图库的方法:

MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "title", "description");

调用以上系统自带的方法会把bitmap对象保存到系统图库中,但是这种方法无法指定保存的路径和名称,上述方法的title、description参数只是插入数据库中的字段,真实的图片名称系统会自动分配。

或者

MediaStore.Images.Media.insertImage(getContentResolver(), "image path", "title", "description");

但是发现,还是不能在相册中查看已经保存到的图片,结果发现需要刷新系统图库

  • 更新系统图库的方法

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

上面那条广播是扫描整个sd卡的广播,如果你sd卡里面东西很多会扫描很久,在扫描当中我们是不能访问sd卡,所以这样子用户体现很不好,所以下面我们还有如下的方法:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("your path"))););

完整代码

  • 1、保存Bitmap到本地指定路径下

  • 2、通过广播,通知系统相册图库刷新数据

public class ImgUtils {    //保存文件到指定路径
    public static boolean saveImageToGallery(Context context, Bitmap bmp) {        // 首先保存图片
        String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dearxy";
        File appDir = new File(storePath);        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);        try {
            FileOutputStream fos = new FileOutputStream(file);            //通过io流的方式来压缩保存图片
            boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
            fos.flush();
            fos.close();            //把文件插入到系统图库
            //MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);

            //保存图片后发送广播通知更新数据库
            Uri uri = Uri.fromFile(file);
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));            if (isSuccess) {                return true;
            } else {                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }        return false;
    }
}

注意:
1、别忘了权限

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

2、如果是6.0手机,记得先申请权限,拿到权限后,再保存,不然会失败,我就是在这里被坑了



作者:唠嗑008
链接:https://www.jianshu.com/p/8cede074ba5b
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


整体代码



下载类,可以url下载,也可以本地的drawable下载到相册,记得在清单加权限,6.0代码动态加权限判断,下载图片要在子线程中下载,下载完后广播更新相册


代码下载地址:链接:https://pan.baidu.com/s/1dsjx2QCSw2SxRcUW0Z3Xqg 

                        提取码:i8j2


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

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

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

package com.example.administrator.myimageload;

 

/**

 * Created by Administrator on 2018/9/17.

 */

 

import android.app.ProgressDialog;

import android.content.Context;

import android.content.Intent;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.net.Uri;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.provider.MediaStore;

import android.text.TextUtils;

import android.util.Log;

import android.widget.Toast;

 

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.UUID;

 

/**

 * Created by vimi8 on 2017/6/9.

 */

 

public class ImgDonwloads {

 

    private static String filePath;

    private static Bitmap mBitmap;

    private static String mFileName="sshs";

    private static String mSaveMessage;

    private final static String TAG = "ImageActivity";

    private static Context context;

 

    private static ProgressDialog mSaveDialog = null;

 

    public static void donwloadImg(Context contexts,String filePaths){

        context = contexts;

        filePath = filePaths;

        mSaveDialog = ProgressDialog.show(context, "保存二维码", "二维码图片正在保存中,请稍等...", true);

 

        new Thread(saveFileRunnable).start();

    }

 

    private static Runnable saveFileRunnable = new Runnable(){

        @Override

        public void run() {

            try {

//                mBitmap = BitmapFactory.decodeStream(getImageStream(filePath));

 

                if (!TextUtils.isEmpty(filePath)) {                 //网络图片

                    //对资源链接

                    URL url=new URL(filePath);

                    //打开输入流

                    InputStream inputStream=url.openStream();

                    //对网上资源进行下载转换位图图片

                    mBitmap= BitmapFactory.decodeStream(inputStream);

                    inputStream.close();

                }

 

                Bitmap    bmp = BitmapFactory.decodeResource(context.getResources(),R.drawable.bg_guid_1 );   //本地的图片,根据自己情况

//                saveFile(mBitmap, mFileName);

                saveFile(bmp);

                mSaveMessage = "图片保存成功!";

            } catch (IOException e) {

                mSaveMessage = "图片保存失败!";

                e.printStackTrace();

            } catch (Exception e) {

                e.printStackTrace();

            }

            messageHandler.sendMessage(messageHandler.obtainMessage());

        }

    };

    private static Handler messageHandler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

            mSaveDialog.dismiss();

            Log.d(TAG, mSaveMessage);

            Toast.makeText(context, mSaveMessage, Toast.LENGTH_SHORT).show();

        }

    };

 

 

    /**

     * Get image from newwork

     * @param path The path of image

     * @return InputStream

     * @throws Exception

     */

    public static InputStream getImageStream(String path) throws Exception{

        URL url = new URL(path);

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setConnectTimeout(5 * 1000);

        conn.setRequestMethod("GET");

        if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){

            return conn.getInputStream();

        }

        return null;

    }

    /**

     * 保存文件

     * @param bm

     * @param fileName

     * @throws IOException

     */

    public static void saveFile(Bitmap bm, String fileName) throws IOException {

        File dirFile = new File(Environment.getExternalStorageDirectory().getPath());

        if(!dirFile.exists()){

            dirFile.mkdir();

        }

        fileName = UUID.randomUUID().toString()+".jpg";

        File myCaptureFile = new File(Environment.getExternalStorageDirectory().getPath() +"/DCIM/Camera/"+ fileName);

        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));

        bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);

        bos.flush();

        bos.close();

 

        //把图片保存后声明这个广播事件通知系统相册有新图片到来

        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

        Uri uri = Uri.fromFile(myCaptureFile);

        intent.setData(uri);

        context.sendBroadcast(intent);

    }

    /**

     * 保存图片到图库

     * @param bmp

     */

    public static void saveFile( Bitmap bmp) {

        // 首先保存图片

        File appDir = new File(Environment.getExternalStorageDirectory(),

                "sshs");

        if (!appDir.exists()) {

            appDir.mkdir();

        }

        String fileName = System.currentTimeMillis() + ".jpg";

        File file = new File(appDir, fileName);

        try {

            FileOutputStream fos = new FileOutputStream(file);

            bmp.compress(Bitmap.CompressFormat.JPEG, 80, fos);

            fos.flush();

            fos.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

 

            e.printStackTrace();

        }

 

        // 其次把文件插入到系统图库

        try {

            MediaStore.Images.Media.insertImage(context.getContentResolver(),

                    file.getAbsolutePath(), fileName, null);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }

        // 最后通知图库更新

        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,

                Uri.fromFile(new File(file.getPath()))));

    }

}

MainActivity类


 

public class MainActivity extends AppCompatActivity {

    private Bitmap bitmap;

    private TextView tv ;

    String iPath = "http://i.imgur.com/DvpvklR.png";

  

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        

        tv = (TextView) findViewById(R.id.tv);

//        download() ;

        tv.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                List<String> permissionList = new ArrayList<>();

                if (ContextCompat.checkSelfPermission(MainActivity.this,

                        Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

                    permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);

                }

                if (!permissionList.isEmpty()) {

                    String[] permissions = permissionList.toArray(new String[permissionList.size()]);

                    ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);

                } else {

                    ImgDonwloads.donwloadImg(MainActivity.this,"");//iPath

                }

 

 

            }

        });

 

    }

    @Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        switch (requestCode) {

            case 1:

                if (grantResults.length > 0) {

                    for (int result : grantResults) {

                        if (result != PackageManager.PERMISSION_GRANTED) {

                            Toast.makeText(this, "拒绝了权限", Toast.LENGTH_SHORT).show();

//                            finish();

                            return;

                        }

                    }

                    ImgDonwloads.donwloadImg(MainActivity.this,"");

                } else {

                    Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();

//                    finish();

                }

                break;

            default:

        }

    }

   

 

    

}

--------------------- 

作者:code_dream_wq 

来源:CSDN 

原文:https://blog.csdn.net/code_dream_wq/article/details/82771800 

版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2020-03-19 19:15:47

    vue中methods watch和compute的区别和联系

    首先要说,methods,watch和computed都是以函数为基础的,但各自却都不同 而从作用机制和性质上看,methods和watch/computed不太一样,所以我接下来的介绍主要有两个对比: 1.methods和(watch/computed)的对比

  • 2020-03-19 19:50:31

    用vue做的跟随鼠标移动的div

    随鼠标移动的动画效果,之前一直使用angular和react,没怎么接触过vue,先做一个vue的简单例子,然后再整合。

  • 2020-03-20 13:35:55

    随便想到,群聊天的数据库简单设计

    拆分成两个表,一个是消息的流水表,一个是每个人的配置表。 记录每个群下面的这个用户的最后读取的消息last_msg_id,然后在计算消息未读数据。 这样优化之后数据将减少好多,数量是 m+n条数据。不在是成倍增长了。

  • 2020-03-20 13:39:50

    类似与微信朋友圈功能数据库如何实现

    每次发圈子的时候,给关注我的每个uuid,发一个内容id。 大概表的设计就是 uuid,idlist 这样的,idlist是按照时间顺序的。 然后定期删除idlist过多的老圈子。

  • 2020-03-21 00:11:38

    Android卡片布局(圆角阴影)的几种实现及分析

    在开发中,为了界面美观,圆角view和阴影效果是开发中经常遇到的UI场景,比如银行卡效果,卡片式itemView布局,Banner图等,开发中我们通过各种方式实现了这种效果,但是哪种方案最好呢,接下来本文将比较几种常见的圆角阴影布局实现,并从内存占用角度分析它们的优缺点.

  • 2020-03-21 12:05:24

    android 自定义组件,使用AttributeSet

    首先要在res/values目录下建立一个attrs.xml(名字可以自己定义)的文件,并在此文件中增加对控件的属性的定义.其xml文件如下所示:

  • 2020-03-21 12:09:59

    Android使用AttributeSet自定义控件的方法

    我们可以在attrs.xml中声明自己控件的属性,在布局xml文档中声明自己的命名空间,这时就可以对设置自己想要的值了,然后在AttributeSet这个属性中获取对应的值。好了不多说,我们来看下代码,一切尽在不言中:

  • 2020-03-22 21:16:07

    用vue做的跟随鼠标移动的div

    最近接到一个任务,就是在既存用electron-vue开发的桌面端程序上追加随鼠标移动的动画效果,之前一直使用angular和react,没怎么接触过vue,先做一个vue的简单例子,然后再整合。