Home » Android » php 7 – Download .apk file from php with okhttp3 on Android-Exceptionshub

php 7 – Download .apk file from php with okhttp3 on Android-Exceptionshub

Posted by: admin February 26, 2020 Leave a comment

Questions:

I want to make an Android app that downloads .apk files (a bit like filelinked but not the same) from my website (running apache2.4 and php 7.3) via an okhttp asynchronous call. The url for testing just returned 1 file for now to see if it’s working. Let’s say my url is https://www.example.com/download.php
The reason I want to serve the file over download.php rather than just https://www.example.com/myAwesomeApp.apk is because I don’t want that anyone can just download my app. Therefore my .apk file is outside the /public_html/www/ scope. I placed the file in /upperScope/myAwesomeApp.apk

My php code of download.php is:

<?php
    $dl = dirname($_SERVER['DOCUMENT_ROOT']) . '/upperScope/'; # Outside the public web folder.
    $file = 'myAwesomeApp.apk'; // file not public
    $path = $dl . $file;

    if (file_exists($path)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/vnd.android.package-archive');
        header('Content-Disposition: attachment; filename="'.basename($path).'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($path));
        readfile($path);
        exit;
    }
?>

My 1st Q: is this how I’d set the headers to serve my apk or should I add/change it or should I use another approach?

2nd Q: I want that only registered users can download the app so upon doing the okhttp call in Android I pass along the username and encrypted password to the download.php file in a post call. Login verification works and I didn’t include it here because its’s out of the scope of these questions. My question here is, if I get a response back and do the following code in onResponse()

String dloc =  getString(R.string.appDownloadLocation) + getString(R.string.myAppUpdateFolder);
String fileName = "app_update.apk";
String pathAndName = dloc + fileName;
File dlf = new File(Environment.getExternalStorageDirectory(), pathAndName);
dlf.getParentFile().mkdirs();
if (dlf != null){
   try {
        FileOutputStream fos = new FileOutputStream(dlf);
        fos.write(response.body().bytes());
        fos.close();
   } catch (IOException e) {
        e.printStackTrace();
   }
}

will the FileOutputStream just process the data from the response object or do a new call? Because the file gets created but it’s version is N/A, size is 0,00 bytes and package name is N/A if I look to the file properties. If FileOutputStream indeed does a new call to get the content written into the file it might fail to get the contents because if a 2nd call would be involved the credentials wouldn’t be send so resulting in a empty file?

3rd Q: why does the onResponse work with the absolute path (https://www.example.com/myAwesomeApp.apk) but not with the /.download.php approach?

4th Q: what would be the best approach to get it working so a member can only download it via /download.php so that the call couldn’t be replicated aka one-time-download?

5th Q: why isn’t the filesize shown when I try it on a browser (when the popup is showing that asks if you want to open or download the file)? Is something missing in the headers?

Thanks in advance!

How to&Answers: