Today I wrote a small example of downloading an apk from the Internet by inputting the website. Record it for your own use.
Operation rendering:
Note: above Android 6.0 system, you need to dynamically apply for some dangerous permissions, that is, you need to actively pop up a dialog box to ask users whether they are willing to call the address book list, obtain storage permissions, create file permissions, etc. before Android 6.0, the permissions written in the manifest were owned by default, and you do not need to ask customers. The program I wrote today does not actively ask the customer's code (dynamic application permission), so we should pay attention to the uses SDK version in the manifest. The maximum version should be less than 23, so that the mobile phone above 6.0 will know to help you run the program in compatibility mode, otherwise it will not run out.
Manifest Code:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="22" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
XML Code:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" > <TextView android:id="@+id/tv_address" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="File storage location" /> <TextView android:id="@+id/tv_size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="SD Card space remaining" /> <Button android:id="@+id/b_click" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click download file" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <!-- android:indeterminate="false"flase It's the precise display. Start writing true No display !--> <ProgressBar android:id="@+id/pb_scheduel" style="?android:attr/progressBarStyleHorizontal" android:layout_width="200dp" android:layout_height="50dp" android:layout_centerHorizontal="true" android:indeterminate="false" android:progress="0" android:max="100"/> <TextView android:id="@+id/tv_scheduel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_toRightOf="@+id/pb_scheduel" android:textColor="#000000" android:layout_centerHorizontal="true" android:text="0%" /> </RelativeLayout> </LinearLayout>
JAVA code:
public class DownLoadFile extends FragmentActivity { private Handler handler; private TextView tv_address, tv_size, tv_scheduel; private Button b_click; private ProgressBar pb_scheduel; private URL url; private Message msg; double totalLength = 0.0; String downloadFileDirectory; InputStream stream; OutputStream output; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.download_file); tv_address = (TextView) findViewById(R.id.tv_address); tv_size = (TextView) findViewById(R.id.tv_size); b_click = (Button) findViewById(R.id.b_click); pb_scheduel = (ProgressBar) findViewById(R.id.pb_scheduel); tv_scheduel = (TextView) findViewById(R.id.tv_scheduel); pb_scheduel.setProgress(0); try { // url=new // URL("https://clfile.imooc.com/class/assist/119/4858629/Android%206.0%20%E5%8A%A8%E6%80%81%E6%9D%83%E9%99%90%E7%94%B3%E8%AF%B7.pdf"); url = new URL("https://www.imooc.com/mobile/mukewang.apk"); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } handler = new myHandler(); b_click.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Thread thread = new myThread(); thread.start(); } }); } class myHandler extends Handler { int Progress; @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if (msg.what == 555) { Progress = msg.arg1;//The handler is created in the main thread, and now the code runs in the main thread pb_scheduel.setProgress(Progress);// Set progress bar progress tv_scheduel.setText(Progress + "%");// display } else if (msg.what == 777) { tv_size.setText("SD Card space remaining:" + msg.getData().getString("sd"));// Data retrieval by bundle tv_address.setText("SD Card path:" + msg.getData().getString("a")); } } } class myThread extends Thread { @SuppressWarnings("unused") @Override public void run() { // TODO Auto-generated method stub super.run(); // Determine whether the memory card is readable and writable if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { downloadFileDirectory = Environment .getExternalStorageDirectory() + File.separator + "downSB" + File.separator + "mukewang.apk";// Download file path File file = new File(downloadFileDirectory); if (!file.exists())// Determine whether the file directory exists file.getParentFile().mkdirs();// File.getParentFile() gets the file name of the parent directory. If it does not exist, create try { file.createNewFile();// Create what.apk file } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } URLConnection connect = null; try { if (url != null) connect = url.openConnection();// Return a connection else { System.out.println("The website you provided cannot be downloaded."); return; } totalLength = connect.getContentLength();// Total length of downloaded files msg = handler.obtainMessage(777); Bundle bundle = new Bundle();// Data transfer in bundle mode bundle.putString("a", Environment .getExternalStorageDirectory().getPath()); bundle.putString("sd", SDStorage .GetSDAvailableSize(getApplicationContext())); msg.setData(bundle);// The connection between bundle and msg handler.sendMessage(msg); if (totalLength < SDStorage .GetSDAvailableSize2(getApplicationContext())) {// Wrong point, long and double can be compared int length = 0; stream = connect.getInputStream();// Return to input stream byte[] b = new byte[1024]; output = new FileOutputStream(file);// Create an output stream for output to a file int downloadSize = 0;// Length of downloaded files while ((length = stream.read(b)) != -1) {// Returns the number of bytes actually read each time read into array b output.write(b,0,length);// Get from b array and write to file downloadSize += length; msg = handler.obtainMessage(555);// 555 flag message msg.arg1 = (int) (downloadSize * 100 / totalLength);// Find progress on handler.sendMessage(msg);// Send to main thread update progress bar } stream.close(); output.close(); } else { // Toast.makeText(DownLoadFile.this, "there's not enough storage space on your phone", // 1).show(); / / toast is not displayed in the child thread and should not be written } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } else { // Toast.makeText(DownLoadFile.this, "your storage device is not allowed", // Toast.LENGTH_LONG).show(); } } } }
Calculation code of SD card remaining space:
public class SDStorage { /** * @Get the remaining free space of SD card * The storage area is divided into several blocks, some of which cannot be used */ @SuppressLint("NewApi") public static String GetSDAvailableSize(Context context){ long blockSize=0;//Single storage block size long availableBlocks;//Available storage blocks File file=Environment.getExternalStorageDirectory();//Get abstract form of external storage device, SD card StatFs statFs=new StatFs(file.getPath());//file.getPath() gets the path of the file, and statFs gets the abstraction of the usage of the storage device if(Build.VERSION.SDK_INT>Build.VERSION_CODES.JELLY_BEAN_MR2 ){//Android API version number > 18, enter the build file to see the constant name of each version blockSize=statFs.getBlockSizeLong();//Get the size of the storage block availableBlocks=statFs.getAvailableBlocksLong();//Get the storage speed that can be used }else{ blockSize=statFs.getBlockSize(); availableBlocks=statFs.getAvailableBlocks(); } return Formatter.formatFileSize(context, availableBlocks*blockSize);//Convert long bytes to string GB bytes } @SuppressLint("NewApi") public static long GetSDAvailableSize2(Context context){ long blockSize=0;//Single storage block size long availableBlocks;//Available storage blocks File file=Environment.getExternalStorageDirectory();//Get the abstract form of external storage device, SD card StatFs statFs=new StatFs(file.getPath());//file.getPath() gets the path of the file, and statFs gets the abstraction of the usage of the storage device if(Build.VERSION.SDK_INT>Build.VERSION_CODES.JELLY_BEAN_MR2 ){//Android API version number > 18, enter the build file to see the constant name of each version blockSize=statFs.getBlockSizeLong();//Get the size of the storage block availableBlocks=statFs.getAvailableBlocksLong();//Get the storage speed that can be used }else{ blockSize=statFs.getBlockSize(); availableBlocks=statFs.getAvailableBlocks(); } return blockSize*availableBlocks; } }