6

I'm trying to download a file stored in Google Drive using android DownloadManager.

I get the sign in token from Google like following:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(AppConfig.getInstance().get("google_client_id"))
            .requestProfile()
            .requestEmail()
            .build();

I receive a notification with google drive file url and i pass it to the DownloadManager, passing to it the token:

String cookie = CookieManager.getInstance().getCookie(d.getURL());
            request.addRequestHeader("Cookie",cookie);
            request.addRequestHeader("Authorization", "OAuth " + profile.getToken());
//d is the document object, that contains url, file name, etcc
//Profile is a simple object class that hold the user data taken from sign Google, like token, name, email, etcc

Using a simple Broadcast Receiver to manage the download result (ACTION_DOWNLOAD_COMPLETE).

The download is done successfully, but the file is corrupted. If i try to open it, the device (and pc) gives me a format error. The file contains a HTML code of a Google page that says that there war an error, no more.

(The account that i'm using is enabled to read and dwonload the document form this specific drive storage)

Is this the correct way to download a Google Drive file using DownloadManager? Is it possible to do that?

MikeKeepsOnShine
  • 1,730
  • 4
  • 23
  • 35
  • The download is done successfully, but the file is corrupted. If i try to open it, the device (and pc) gives me a format error. There is no format error it just had a external link which is not opening – Jin Thakur Jul 31 '20 at 15:02
  • Hey @MikeKeepsOnShine, did you find any solution for it? – Shunan Feb 01 '21 at 16:49
  • 1
    @Shubh no, finally i used Google Drive API. Start from here: https://developers.google.com/drive/api/v3/manage-downloads. The process is a bit complicated, when i'll be free i'll update my question to explain what i did – MikeKeepsOnShine Feb 03 '21 at 11:31

3 Answers3

1

You can also downlaod file form google via this method

Refer to this Url

https://drive.google.com/uc?id=<FILE_ID>&export=download 

Replace <FILE_ID> with your shareable file ID.

Further you can take help from this solution Download a file with Android, and showing the progress in a ProgressDialog

You can use the doInBackground function in it to solve your query.

Saddam
  • 1,174
  • 7
  • 14
1

Try whether this helps...

As in @saddamkamal 's answer, use the Google Drive download URL.

AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                DownloadManager downloadmanager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
                Uri uri = Uri.parse("https://drive.google.com/uc?id=<FILE_ID>&export=download");

                DownloadManager.Request request = new DownloadManager.Request(uri);
                request.setTitle("My File");
                request.setDescription("Downloading");
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file.extension");
                downloadmanager.enqueue(request);
            }
        });
Dharman
  • 30,962
  • 25
  • 85
  • 135
Vishnu
  • 663
  • 3
  • 7
  • 24
0

Since file is downloaded. Check the size of file in Google drive and your android. Then make sure your file extension is correct. Because file extension may not be present and android will treat it as binary file. Now you have file extension in android. Install proper application to open it. This is updated code

public class MainActivity extends AppCompatActivity {
private Button btn_download;
private long downloadID;



 // using broadcast method
    private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //Fetching the download id received with the broadcast
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            //Checking if the received broadcast is for our enqueued download by matching download id
            if (downloadID == id) {
                Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_SHORT).show();
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_download = findViewById(R.id.download_btn);
        // using broadcast method
        registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                beginDownload();
            }
        });
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        // using broadcast method  
        unregisterReceiver(onDownloadComplete);
    }
    private void beginDownload(){
       String url = "http://speedtest.ftp.otenet.gr/files/test10Mb.db";
       String fileName = url.substring(url.lastIndexOf('/') + 1);
       fileName = fileName.substring(0,1).toUpperCase() + fileName.substring(1);
       File file = Util.createDocumentFile(fileName, context);

       DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url))
                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)// Visibility of the download Notification
                .setDestinationUri(Uri.fromFile(file))// Uri of the destination file
                .setTitle(fileName)// Title of the Download Notification
                .setDescription("Downloading")// Description of the Download Notification
                .setRequiresCharging(false)// Set if charging is required to begin the download
                .setAllowedOverMetered(true)// Set if download is allowed on Mobile network
                .setAllowedOverRoaming(true);// Set if download is allowed on roaming network
        DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.
      
      // using query method
      boolean finishDownload = false;
      int progress;
      while (!finishDownload) {
        Cursor cursor = downloadManager.query(new DownloadManager.Query().setFilterById(downloadID));
        if (cursor.moveToFirst()) {
          int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
          switch (status) {
            case DownloadManager.STATUS_FAILED: {
              finishDownload = true;
              break;
            }
            case DownloadManager.STATUS_PAUSED:
              break;
            case DownloadManager.STATUS_PENDING:
              break;
            case DownloadManager.STATUS_RUNNING: {
              final long total = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
              if (total >= 0) {
                final long downloaded = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                progress = (int) ((downloaded * 100L) / total);
                // if you use downloadmanger in async task, here you can use like this to display progress. 
                // Don't forget to do the division in long to get more digits rather than double.
                //  publishProgress((int) ((downloaded * 100L) / total));
              }
              break;
            }
            case DownloadManager.STATUS_SUCCESSFUL: {
              progress = 100;
              // if you use aysnc task
              // publishProgress(100);
              finishDownload = true;
              Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_SHORT).show();
              break;
            }
          }
        }
      }
    }
}
Jin Thakur
  • 2,711
  • 18
  • 15
  • The extension of the file is correct. The manager downloads the files correctly, but there is a auth problem: the file downloaded is a PDF file (correct, my file is PDF) that contains an HTML page that shows the error. The problem is not the download of the file, is the correct way to do it – MikeKeepsOnShine Jul 31 '20 at 08:49
  • @mikekeepsonshine So if file is correct why you wrote this The download is done successfully, but the file is corrupted. If i try to open it, the device (and pc) gives me a format error. any way you might have pdf where you embed a external html page which might throw error . it may throw error due to internet google fonts. How android pdf program handles it is different from acrobat pdf on computer. – Jin Thakur Jul 31 '20 at 15:01