【小王的安卓之路】下载网络资源并存储到本地

下载网络资源并存储到本地

一.知识要求

二.功能设计

三.代码实现

四.注意事项

一.知识要求:

handler基础,网络请求基础,文件操作基础

二.功能设计:
我们要设计一个能下载特定网络文件的小程序,并且能将加载进度实时显示在屏幕上。
功能:
网络请求->下载文件->实时显示->本地文件存储

三.代码实现:
3.1布局文件:
直接拖拽的,比较简陋的一个布局。

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".downLoadActivity">

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:max="100"
        app:layout_constraintBottom_toTopOf="@+id/button2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

3.2java文件

public class downLoadActivity extends AppCompatActivity {
    private Handler handler;

    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_down_load);
        
      /*获取控件实例*/
        Button button= findViewById(R.id.button2);
        final ProgressBar progressBar = findViewById(R.id.progressBar);
        
        /*动态请求本地文件读写权限*/
        ActivityCompat.requestPermissions(downLoadActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        /*设置点击事件*/
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        downLoad("填写你的下载URL");
                    }
                }).start();

            }
        });
        
        /*处理子线程返回的消息*/
        handler = new Handler()
        {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what)
                {
                    case 1001:
                    {
                        progressBar.setProgress((Integer) msg.obj);
                        break;
                    }
                    case 1002:
                    {
                        Toast.makeText(downLoadActivity.this, "下载失败!", Toast.LENGTH_SHORT).show();
                    }

                }
            }
        };
    }

    private void downLoad(String url)
    {
        try {
        /*获取网络连接*/
            URL url1 = new URL(url);
            URLConnection urlConnection = url1.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            int contentLength = urlConnection.getContentLength();
            
	/*设置本地存储路径*/
            String downloadFolderName = Environment.getExternalStorageDirectory()
                    + File.separator+"file"+File.separator;

            File file = new File(downloadFolderName);
            if (!file.exists()){
                file.mkdir();
            }
            /*设置下载文件名*/

            String fileName = downloadFolderName + your"FileName";

            File apkFile = new File(fileName);

            if (apkFile.exists()){
                apkFile.delete();
            }
            /*设置下载单元大小*/

            int downloadSize=0;
            byte[] bytes = new byte[1024];
            int length=0;

            OutputStream outputStream = new FileOutputStream(fileName);
            while((length=inputStream.read(bytes))!=-1)
            {
                outputStream.write(bytes,0,length);
                downloadSize+=length;
                /*通知主线程更新进度条*/

                Message message = Message.obtain();
                message.obj=downloadSize*100/contentLength;
                message.what=1001;
                handler.sendMessage(message);


            }
            inputStream.close();;
            outputStream.close();
        } catch (MalformedURLException e) {
            noticeDownlLoadFaile();
            e.printStackTrace();
        } catch (IOException e) {
            noticeDownlLoadFaile();
            e.printStackTrace();
        }

    }
/*下载失败调用*/
    private void noticeDownlLoadFaile() {
        Message message = Message.obtain();
        message.what=1002;
        handler.sendMessage(message);
    }
}

四.注意事项:

  1. 在布局文件中要设置进度条的总长度
  2. 在安卓6.0以后的系统中,不仅要在ManiFest文件内写入你要请求的数据,而且要在代码里动态请求权限
  3. 在安卓9.0系统中,进行url开头是http而非https的网络请求需要配置
  4. 要在子线程进行下载任务,主线程更新进度条
  5. 下载结束后要关闭输入输出流,否则可能会造成OOM

效果:
在这里插入图片描述
如果有什么错误,恳请指正。

发布了47 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41525021/article/details/98447566