textview提示:下载失败,已经手动申请权限,xml中也添加了三个相关权限申请

textview提示:下载失败,已经手动申请权限,xml中也添加了三个相关权限申请

package com.example.handler;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class DownloadActivity extends AppCompatActivity {
   public static final int DOWNLOAD_MESSAGE_CODE = 100001;
   public static final String DONWLOAD_URL = "http://downlaod.sj.qq.com/upload/connAssistantDownload/upload/MobileAssistant_1.apk";
   private static final int MY_PERMISSION_REQUEST_CODE = 10000;
   private Handler myhandler;
   public TextView textView;
   public static final int DOWNLOAD_MESSAGE_FAILCODE = 100002;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_download);
       /*完成功能:点击按钮,下载网络数据,在progressbar中显示下载进度
        *(1) 主线程-->start
        *(2) 点击按钮
        *(3)发起下载
        *(4) 开启子线程下载
        *(5)子线程下载过程中通知主线程-->主线程更新进度条*/
       final ProgressBar progressBar = findViewById(R.id.progressbar_donwload);
       textView = findViewById(R.id.tv_download);
       findViewById(R.id.bt_donwload).setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               //开辟子线程,进行下载
               new Thread(new Runnable() {
                   @Override
                   public void run() {
                      download(DONWLOAD_URL);
                   }
               }).start();
           }
       });

       myhandler = new Handler() {
           @Override
           public void handleMessage(Message msg) {
               super.handleMessage(msg);
               switch (msg.what)//对传来的信息作一个判断,并作出相关响应
               {
                   case DOWNLOAD_MESSAGE_CODE:
                       progressBar.setProgress( msg.arg1);
                       if ( msg.arg1 == 100) {
                           textView.setText(msg.obj+"下载完成");
                       } else
                           textView.setText("下载中……");
                       break;

                   case DOWNLOAD_MESSAGE_FAILCODE:
                       textView.setText("下载失败");
                       break;
               }
           }
       };

   }
   private void download(String downloadUrl) {
       //第一步:检查是否有相的权限
       boolean isAllGranted=checkPermissionAllGranted(
               new String[]{
                       Manifest.permission.INTERNET,
                       Manifest.permission.READ_EXTERNAL_STORAGE,
                       Manifest.permission.WRITE_EXTERNAL_STORAGE
               });
       if(isAllGranted){
           doDownload(downloadUrl);//已经得到所有授权的话,直接下载
           return;
       }
      //第2步:请求权限,一次性请求多个权限,如果其它权限已经授予的将会自动忽略掉
       ActivityCompat.requestPermissions(
               this,
               new String[]{
                       Manifest.permission.INTERNET,
                       Manifest.permission.READ_EXTERNAL_STORAGE,
                       Manifest.permission.WRITE_EXTERNAL_STORAGE
               },
               MY_PERMISSION_REQUEST_CODE
       );
   }
/*检查是否拥有指定的所有权限*/
   private boolean checkPermissionAllGranted(String[] permissions) {
       for(String permission:permissions){
           if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED)
           {//只要有一个权限没有被授予,直接返回false
               return false;
           }
       }
           return true;
   }
/*第3步:申请权限结果返回处理*/
   @Override
   public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
       if(requestCode==MY_PERMISSION_REQUEST_CODE){
           boolean isAllGranted=true;
           //判断是否所有权限都已经授权了
           for(int grant:grantResults){
               if(grant!=PackageManager.PERMISSION_GRANTED){
                   isAllGranted=false;
                   break;
               }
           }
           if(isAllGranted){
               //如果所有的权限都授予了,则执行下载任务
               doDownload(DONWLOAD_URL);
           }
       }
   }

   private void doDownload(String appUrl) {
       try {
           /*
            * (1)获取网络下载文件总长度
            * (2)获取存储文件目录地址(手机等移动设备)
            *(3)用输入输出流把网络下载数据写入本地文件
            *(4)同时统计下载数据长度,通过handler.sendmessage传给主线程,告知下载进度
            *  */
           URL url = new URL(appUrl);//根据网络地址参数appUrl新建URL对象
           URLConnection urlConnection = url.openConnection();//建立url连接
           InputStream inputStream = urlConnection.getInputStream();//新建输入流读取网络数据
           int contentLength = urlConnection.getContentLength();
           String downloadFolderName = Environment.getExternalStorageDirectory()
                   + File.separator + "imooc" + File.separator;
           File file = new File(downloadFolderName);//新建文件夹对象
           if (!file.exists()) {
               file.mkdir();//创建文件夹
           }
           String fileName = downloadFolderName + "imooc.apk";//完整的对象目录+文件名
           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);
               //   outputStream.flush();
               downloadSize += length;
               /*updateUI*/
               Message message = Message.obtain();
               message.obj = fileName;//传递文件名及所在位置
               message.arg1 = downloadSize * 100 / contentLength;//进度条数值
               message.what = DOWNLOAD_MESSAGE_CODE;
               myhandler.sendMessage(message);
           }
           inputStream.close();
           outputStream.close();
       } catch (MalformedURLException e) {
           /*updateUI*/
           notifyDownloadFailed();//通知主线程,下载失败
           e.printStackTrace();
       } catch (IOException e) {
           notifyDownloadFailed();
           e.printStackTrace();
       }
   }

   private void notifyDownloadFailed() {
       Message message = Message.obtain();
       message.what = DOWNLOAD_MESSAGE_FAILCODE;//设置下载失败代码10002
       myhandler.sendMessage(message);
   }
}

正在回答

登陆购买课程后可参与讨论,去登陆

6回答

你的download拼写错了

http://img1.sycdn.imooc.com//climg/5bfba8740001337308990102.jpg

  • 慕运维0750787 提问者 #1
    谢谢你, 修改成正确的网址了,但依然提示:下载失败
    2018-11-27 09:58:17
提问者 慕运维0750787 2018-11-27 10:00:13

修改成正确的网址,真机运行依然提示:下载失败,错误提示:http://img1.sycdn.imooc.com//climg/5bfca51d000197dd12801024.jpg

提问者 慕运维0750787 2018-11-26 15:53:27
irista23 2018-11-26 15:51:49

你这句报的是联网错误丫,或者你把错误信息完整贴出来,便于老师帮你分析解决

http://img1.sycdn.imooc.com//climg/5bfba5fa0001731910170247.jpg

  • 提问者 慕运维0750787 #1
    已经完整贴出来了,我用了另外API18的真机调试,也是一样的错误,手机本身都是能上网的
    2018-11-26 15:59:45
提问者 慕运维0750787 2018-11-26 15:10:51
  • 你检查下真机网络状态是否正常,另外看一下清单文件里面有没有添加<uses-permission android:name="android.permission.INTERNET"/>权限
    2018-11-26 15:30:41
  • 提问者 慕运维0750787 回复 irista23 #2
    已经添加,真机能上网,只是有点慢
    2018-11-26 15:53:13
irista23 2018-11-26 11:58:56

建议你把报错截图贴出来,方便老师帮你快速找到问题。另外你可以先把权限部分注释掉,把目标平台改成23以下版本,看是否可以下载成功,如果可以,问题就处在权限代码这块。

另外, Manifest.permission.INTERNET属于普通权限,直接申请在清单文件即可,不需要添加到运行时权限里。

  • 提问者 慕运维0750787 #1
    我的真机API19,权限在Activity添加之前也是下载失败
    2018-11-26 15:10:22
  • 提问者 慕运维0750787 #2
    根据错误提示,应该不是权限部分原因,错误指出这几句代码,根源是这一句:InputStream inputStream = urlConnection.getInputStream();//新建输入流读取网络数据
    2018-11-26 15:49:34
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
Android网络操作与数据存储2018版
  • 参与学习           人
  • 提交作业       307    份
  • 解答问题       1613    个

本专题是联网及数据处理的必备技能。课程从网络基础知识到线程间协同工作、异步下载处理。介绍了Android内外部文件存储、轻量级数据库SQLite的使用。利用屏幕适配、状态保持、百度地图解决实际问题。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师