简体   繁体   English

在 Android 中通过 Url 从 Google Drive 下载文件

[英]Download a file from Google Drive By Url In Android

I am developing an app to uploading ,displaying and downloading files from G Drive.我正在开发一个应用程序来从 G Drive 上传、显示和下载文件。 Unfortunately When downloading I am getting不幸的是,下载时我得到
com.google.api.client.http.HttpResponseException: 401 Unauthorized. com.google.api.client.http.HttpResponseException: 401 未经授权。

Please help me to solve this problem.请帮我解决这个问题。

Here I am assigning我在这里分配

credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);

service=new Drive.Builder(AndroidHttp.newCompatibleTransport(),new GsonFactory(),credential).build();

My Code Is:我的代码是:

package com.example.googledrive;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Children;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.ChildList;
import com.google.api.services.drive.model.ChildReference;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

    static final int REQUEST_ACCOUNT_PICKER = 1;
    static final int REQUEST_AUTHORIZATION = 2;
    static final int CAPTURE_IMAGE = 3;

    private static Uri fileUri;
    private static Drive service;
    private ProgressDialog progressDialog;
    private GoogleAccountCredential credential;

    String fileId;
    String fileName;
    String downloadUrl;
    ListView listView;
    Activity activity;
    String sdCardPadth;
    List<File> allFileList;
    ArrayList<String> fileType;
    ArrayList<String> mainTitleList;
    ArrayList<String> fileIdList;
    ArrayList<String> alternateUrlList;
    ArrayList<Integer> fileSizeList;
    FileTitlesAdapter myAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.uploadedFilesList);
        allFileList = new ArrayList<File>();
        mainTitleList = new ArrayList<String>();
        alternateUrlList = new ArrayList<String>();
        fileSizeList = new ArrayList<Integer>();
        fileType = new ArrayList<String>();
        fileIdList=new ArrayList<String>();
        progressDialog=new ProgressDialog(getApplicationContext());
        progressDialog.setTitle("Please Wait....");
        progressDialog.setCancelable(false);
        activity = this;

        credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);
        startActivityForResult(credential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View view, final int arg2,long arg3) {
                // String str=itemArray.get(arg2).toString().trim();
                System.out.println("mainTitleList size==="+mainTitleList.size());
                System.out.println("arg2==="+arg2);
                fileName = (String)mainTitleList.get(arg2);             
                mainTitleList.clear();              
                //fileSizeList.clear();
                final String fileTypeStr=fileType.get(arg2);
                fileType.clear();
                if(fileTypeStr.contains("application/vnd.google-apps.folder"))
                {
                    Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                    boolean b=true;
                    try {                       
                        String dirUrl=alternateUrlList.get(arg2);                       
                        alternateUrlList.clear();
                        System.out.println("Folder Name Is:"+fileName);
                        System.out.println("Folder Type Is:"+fileTypeStr);
                        System.out.println("Folder URL Is:"+dirUrl);
                        String fileId=fileIdList.get(arg2);
                        System.out.println("Folder Id Is:"+fileId);                     
                        //retrieveAllFilesFromDir(service, fileId, b);                      
                        //retrieveAllFiles1(service, b, fileId);
                        //Files.List request = service.children().get(fileId, null);
                        Files.List request = service.files().list().setQ("'" + fileId + "' in parents ");
                        retrieveAllFiles(service,request,b);                        
                        //retrieveAllFiles(service, b);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        System.out.println("Exception In retrieveAllFiles Dir Is:"+e);
                        e.printStackTrace();
                    }
                        }
                        });t.start();       
                }
                else
                {       

                try {
                    System.out.println("fileSizeList size===="+fileSizeList.size());
                    System.out.println("arg2===="+arg2);                    
                    Integer fileSize = (int) fileSizeList.get(arg2);
                    downloadUrl = alternateUrlList.get(arg2);
                    byte[] size = new byte[fileSize];
                    int byteRead = 0, byteWritten = 0;
                    sdCardPadth = Environment.getExternalStorageDirectory().getPath();


                    System.out.println("Download Url==="+downloadUrl);

                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            InputStream inStream=downloadFile(service, downloadUrl);

                            java.io.File inFile=new java.io.File(sdCardPadth+"/"+fileName+"1");
                            System.out.println("File Succesfully Stored");

                        }
                    }).start();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    System.out.println("Exception In get Integer Is:" + e);
                    e.printStackTrace();
                }
                }
            }
        });
    }

    @Override
    protected void onActivityResult(final int requestCode,
            final int resultCode, final Intent data) {      
        switch (requestCode) {
        case REQUEST_ACCOUNT_PICKER:            
            if (resultCode == RESULT_OK && data != null
                    && data.getExtras() != null) {
                String accountName = data
                        .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                if (accountName != null) {
                    credential.setSelectedAccountName(accountName);
                    service = getDriveService(credential);      
                    final boolean b=false;                  
                    Thread t=new Thread(new Runnable() {                        
                        @Override
                        public void run() {
                            try
                            {
                                Files.List request = service.files().list().setQ("hidden="+b);
                                    retrieveAllFiles(service,request,b);
                            } catch (Exception e) {
                                System.out.println("Exception Is:"+e);
                                e.printStackTrace();
                            }

                        }
                    }) ;t.start();

                }
            }
            break;
        case REQUEST_AUTHORIZATION:
            if (resultCode == Activity.RESULT_OK) {
                System.out.println("REQUEST_AUTHORIZATION case Is:"
                        + REQUEST_AUTHORIZATION);
                saveFileToDrive();
            } else {
                startActivityForResult(credential.newChooseAccountIntent(),
                        REQUEST_ACCOUNT_PICKER);
            }
            break;
        case CAPTURE_IMAGE:
            if (resultCode == Activity.RESULT_OK) {
                System.out.println("CAPTURE_IMAGE case Is:" + CAPTURE_IMAGE);
                saveFileToDrive();
            }
        }
    }
    private void saveFileToDrive() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // File's binary content
                    System.out.println("run method");
                    java.io.File fileContent = new java.io.File(fileUri.getPath());
                    FileContent mediaContent = new FileContent("image/jpeg",fileContent);
                    // File's metadata.
                    File body = new File();
                    body.setTitle(fileContent.getName());
                    body.setMimeType("image/jpeg");
                    File file=null;
                    try {

                        file = service.files().insert(body, mediaContent).execute();
                    } catch (Exception e) {

                        System.out.println("Exception In Insert File Is"+e);
                        e.printStackTrace();
                    }
                    if (file != null) {
                        showToast("Photo uploaded: " + file.getTitle());
                        System.out.println("photo sucessfullly uploaded:"+ fileId);boolean b=false;
Files.List request = service.files().list().setQ("hidden="+b);
                        retrieveAllFiles(service,request,b);                        
                    }
                } catch (UserRecoverableAuthIOException e) {
                    startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
    private Drive getDriveService(GoogleAccountCredential credential) {
        return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
                new GsonFactory(), credential).build();
    }

    public void showToast(final String toast) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), toast,Toast.LENGTH_SHORT).show();
            }
        });
    }

    private List<File> retrieveAllFiles(Drive service,Files.List request,boolean b) throws IOException {
        List<File> result = new ArrayList<File>();
        final ArrayList<String> titleList = new ArrayList<String>();
        String fileUrl = "";
        do {
            try {
                FileList files = request.execute();
                result.addAll(files.getItems());
                request.setPageToken(files.getNextPageToken());
                for (int i = 0; i < result.size(); i++) {
                    File tempFile = result.get(i);
                    String fileTypeStr = tempFile.getMimeType();                
                    String fileName = tempFile.getTitle();
                    titleList.add(fileName);    
                    fileId = tempFile.getId();
                    fileIdList.add(fileId);                 
                    fileUrl = tempFile.getAlternateLink();
                    System.out.println("<><>< fileUrl Is:" + fileUrl);
                    alternateUrlList.add(fileUrl);

                    fileType.add(fileTypeStr);
                    mainTitleList.add(fileName);                    

                    try {
                        Integer fileSize =tempFile.getFileSize()==null?100:(int) (long) tempFile.getFileSize();
                        fileSizeList.add(fileSize);
                        System.out.println("<><>< fileSize Is:" + fileSize);
                    } catch (Exception e) {

                        fileSizeList.add(2000);
                        e.printStackTrace();
                    }


                }



                try {
                    runOnUiThread(new Runnable() {
                        public void run() {

                            myAdapter = new FileTitlesAdapter(activity,
                                    fileType, mainTitleList, alternateUrlList,
                                    fileSizeList);
                            listView.setAdapter(myAdapter);
                        }
                    });

                } catch (Exception e) {


                    System.out.println("Exception Setting ListView Is:" + e);
                    e.printStackTrace();
                }
            } catch (IOException e) {
                System.out.println("An error occurred in retrieveAllFiles:"+ e);
                request.setPageToken(null);
            }
        } while (request.getPageToken() != null
                && request.getPageToken().length() > 0);
        return result;
    }


     private static InputStream downloadFile(Drive service, String url) {
         System.out.println("downloadFile is called service=="+service);
            if (url != null && url.length() > 0) {
              try {
                  System.out.println("downloadFile is called try");
                HttpResponse resp =service.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute();
                System.out.println("resp.getContent()===="+resp.getContent());
                return resp.getContent();
              } catch (Exception e) {
                System.out.println("Exception Is:"+e);
                e.printStackTrace();
                return null;
              }
            } else {
                 System.out.println("No Exception No Output");
              return null;
            }
          }


}

This is code that I use to download File from google Drive这是我用来从谷歌云端硬盘下载文件的代码

   new AsyncTask<Void, Integer, Boolean>() {

        @Override
        protected Boolean doInBackground(Void... params) {
        try {
            File file = service.files().get("path in drive").execute();
            java.io.File toFile = new java.io.File("where you want to store");
            toFile.createNewFile();
            HttpDownloadManager downloader = new HttpDownloadManager(file, toFile);
            downloader.setListener(new HttpDownloadManager.FileDownloadProgressListener() {

                public void downloadProgress(long bytesRead, long totalBytes) {
                    Log.i("chauster",totalBytes);
                    Log.i("chauster",bytesRead);
                }

                @Override
                public void downloadFinished() {
                    // TODO Auto-generated method stub
                }

                @Override
                public void downloadFailedWithError(Exception e) {
                    // TODO Auto-generated method stub  
                }                       
            });
            return downloader.download(service);
        } catch (IOException e) {
            e.printStackTrace();
        }
            return false;
        }
        protected void onPostExecute(Boolean result) {
        };
    }.execute();

HttpDownloadManager.java HttpDownloadManager.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.grandex.ShareInfomation.ShareData;
import com.grandex.ShareInfomation.ShareData.ToolTapState;

public class HttpDownloadManager {
    private String donwloadUrl;
    private String toFile;
    private FileDownloadProgressListener listener;
    private long totalBytes;

    public void setListener(FileDownloadProgressListener listener) {
        this.listener = listener;
    } 

    public HttpDownloadManager(File sourceFile, java.io.File destinationFile) {
        super(); 
        this.donwloadUrl = sourceFile.getDownloadUrl();
        this.toFile = destinationFile.toString();
        this.totalBytes = sourceFile.getFileSize();
    } 

    public static interface FileDownloadProgressListener {
        public void downloadProgress(long bytesRead, long totalBytes);

        public void downloadFinished();

        public void downloadFailedWithError(Exception e);
    }

    public boolean download(Drive service) {
        HttpResponse respEntity = null;
        try {
            // URL url = new URL(urlString);
            respEntity = service.getRequestFactory()
                    .buildGetRequest(new GenericUrl(donwloadUrl)).execute();
            InputStream in = respEntity.getContent();
            if(totalBytes == 0) {
                totalBytes = respEntity.getContentLoggingLimit();
            } 
            try { 
                FileOutputStream f = new FileOutputStream(toFile) {

                    @Override
                    public void write(byte[] buffer, int byteOffset,
                            int byteCount) throws IOException {
                        // TODO Auto-generated method stub
                        super.write(buffer, byteOffset, byteCount);
                        }
                    }
                };
                byte[] buffer = new byte[1024];
                int len1 = 0;
                long bytesRead = 0;
                while ((len1 = in.read(buffer)) > 0) {
                    f.write(buffer, 0, len1);
                    if (listener != null) {
                        bytesRead += len1;
                        listener.downloadProgress(bytesRead, totalBytes);
                    }
                }
                f.close();
            } catch (Exception e) {
                if (listener != null) {
                    listener.downloadFailedWithError(e);
                }
                return false;
            }
            if (listener != null) {
                listener.downloadFinished();
            }
            return true;

        } catch (IOException ex) {
            if (listener != null) {
                listener.downloadFailedWithError(ex);
                return false;
            }
        } finally {
            if(respEntity != null) {
                try {
                    respEntity.disconnect();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return false;
    }
}

Nowhere in your code are you setting the Authorization header.您的代码中没有任何地方设置 Authorization 标头。

You need something like你需要类似的东西

setRequestProperty("Authorization", "OAuth " + "***ACCESS_TOKEN***");

For any 401/403 errors it's well worth getting your request working on the Oauth.对于任何 401/403 错误,让您的请求在 Oauth 上工作是非常值得的。 Try this out试试这个

Please check below code for download apk file from google drive请检查以下代码以从谷歌驱动器下载 apk 文件

implementation 'com.google.android.material:material:1.0.0'

Add uses permission添加使用权限

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

Create a file provider创建文件提供程序

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
    name="external"
    path="." />
<external-files-path
    name="external_files"
    path="." />
<files-path
    name="files"
    path="." />

Now declare the file provider inside the manifest现在在清单中声明文件提供程序

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
Add some value inside strings.xml file 在 strings.xml 文件中添加一些值
package com.hktpayment.mytmoney.pos.mauritius.util
import android.app.Dialog
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.util.Log
import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.content.FileProvider
import com.hktpayment.mytmoney.pos.mauritius.BuildConfig
import com.hktpayment.mytmoney.pos.mauritius.R
import java.io.File




class DownloadController(
private val context: Context,
private val url: String,
private val progressBar: Dialog
) {
companion object {
    private const val FILE_NAME = "SampleDownloadApp.apk"
    private const val FILE_BASE_PATH = "file://"
    private const val MIME_TYPE = "application/vnd.android.package-archive"
    private const val PROVIDER_PATH = ".provider"
    private const val APP_INSTALL_PATH = "application/vnd.android.package- 
    archive"
    }


    private lateinit var downloadManager: DownloadManager

    fun enqueueDownload() {
    var destination =
        
    context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() 
    + "/"
    destination += FILE_NAME
    val uri = Uri.parse("$FILE_BASE_PATH$destination")
    val file = File(destination)
    if (file.exists()) file.delete()
    downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as 
    DownloadManager
    val downloadUri = Uri.parse(url)
    val request = DownloadManager.Request(downloadUri)
    request.setMimeType(MIME_TYPE)
    request.setTitle(context.getString(R.string.title_file_download))
    request.setDescription(context.getString(R.string.downloading))
    // set destination
    request.setDestinationUri(uri)
    showInstallOption(destination, uri)
    // Enqueue a new download and same the referenceId
    downloadManager.enqueue(request)
    Toast.makeText(context, context.getString(R.string.downloading), 
    Toast.LENGTH_LONG)
        .show()
     }


    private fun showInstallOption(
    destination: String,
    uri: Uri
) {
    // set BroadcastReceiver to install app when .apk is downloaded
    progressBar.show()
    val onComplete = object : BroadcastReceiver() {
        override fun onReceive(
            context: Context,
            intent: Intent
        ) {
            progressBar.dismiss()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                val contentUri = FileProvider.getUriForFile(
                    context,
                    BuildConfig.APPLICATION_ID + PROVIDER_PATH,
                    File(destination)
                )
                val install = Intent(Intent.ACTION_VIEW)
                install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                install.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
                install.data = contentUri
                context.startActivity(install)
                context.unregisterReceiver(this)
                // finish()
            } else {
                val install = Intent(Intent.ACTION_VIEW)
                install.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
                install.setDataAndType(
                    uri,
                    APP_INSTALL_PATH
                )
                context.startActivity(install)
                context.unregisterReceiver(this)
                // finish()
            }
        }
    }
    context.registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}

Create a download controller创建下载控制器

package com.hktpayment.mytmoney.pos.mauritius.util import android.app.Dialog import android.app.DownloadManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.database.Cursor import android.net.Uri import android.os.Build import android.os.Environment import android.util.Log import android.widget.ProgressBar import android.widget.Toast import androidx.core.content.FileProvider import com.hktpayment.mytmoney.pos.mauritius.BuildConfig import com.hktpayment.mytmoney.pos.mauritius.R import java.io.File class DownloadController( private val context: Context, private val url: String, private val progressBar: Dialog ) { companion object { private const val FILE_NAME = "SampleDownloadApp.apk" private const val FILE_BASE_PATH = "file://" private const val MIME_TYPE = "application/vnd.android.package-archive" private const val PROVIDER_PATH = ".provider" private const val APP_INSTALL_PATH = "application/vnd.android.package- archive" } private lateinit var downloadManager: DownloadManager fun enqueueDownload() { var destination = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" destination += FILE_NAME val uri = Uri.parse("$FILE_BASE_PATH$destination") val file = File(destination) if (file.exists()) file.delete() downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val downloadUri = Uri.parse(url) val request = DownloadManager.Request(downloadUri) request.setMimeType(MIME_TYPE) request.setTitle(context.getString(R.string.title_file_download)) request.setDescription(context.getString(R.string.downloading)) // set destination request.setDestinationUri(uri) showInstallOption(destination, uri) // Enqueue a new download and same the referenceId downloadManager.enqueue(request) Toast.makeText(context, context.getString(R.string.downloading), Toast.LENGTH_LONG) .show() } private fun showInstallOption( destination: String, uri: Uri ) { // set BroadcastReceiver to install app when .apk is downloaded progressBar.show() val onComplete = object : BroadcastReceiver() { override fun onReceive( context: Context, intent: Intent ) { progressBar.dismiss() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { val contentUri = FileProvider.getUriForFile( context, BuildConfig.APPLICATION_ID + PROVIDER_PATH, File(destination) ) val install = Intent(Intent.ACTION_VIEW) install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) install.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true) install.data = contentUri context.startActivity(install) context.unregisterReceiver(this) // finish() } else { val install = Intent(Intent.ACTION_VIEW) install.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP install.setDataAndType( uri, APP_INSTALL_PATH ) context.startActivity(install) context.unregisterReceiver(this) // finish() } } } context.registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) }

} }

In this activity, we are checking storage permission first.在本次活动中,我们首先检查存储权限。 If permission is granted than calling download function otherwise requesting for storage permission.如果授予权限,则调用下载功能,否则请求存储权限。

 val apkUrl = "https://download .apk" downloadController = DownloadController(this, apkUrl) downloadController.enqueueDownload()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM