From a088d4a04bd11c0439a1603a8a52bac38e85ecaf Mon Sep 17 00:00:00 2001 From: Nya Elimu Date: Sat, 4 Jul 2020 11:41:29 +0800 Subject: [PATCH] #224 Fix bug: NullPointerException when no ApplicationVersion exists for installed APK --- .../applications/ApplicationListAdapter.java | 190 +++++++++--------- 1 file changed, 99 insertions(+), 91 deletions(-) diff --git a/app/src/main/java/ai/elimu/appstore/ui/applications/ApplicationListAdapter.java b/app/src/main/java/ai/elimu/appstore/ui/applications/ApplicationListAdapter.java index 4462305d..1937cbc3 100644 --- a/app/src/main/java/ai/elimu/appstore/ui/applications/ApplicationListAdapter.java +++ b/app/src/main/java/ai/elimu/appstore/ui/applications/ApplicationListAdapter.java @@ -82,25 +82,104 @@ public void onBindViewHolder(ApplicationViewHolder viewHolder, int position) { viewHolder.textViewSecondLine.setAlpha(0.5f); } - if (InstallationHelper.isApplicationInstalled(application.getPackageName(), context)) { - // The APK has been installed - - // Check if an update is available for download - int versionCodeInstalled = InstallationHelper.getVersionCodeOfInstalledApplication(application.getPackageName(), context); - Timber.i("versionCodeInstalled: " + versionCodeInstalled); - ApplicationVersion applicationVersion = getNewestApplicationVersion(application, applicationVersions); - Timber.i("applicationVersion.getVersionCode(): " + applicationVersion.getVersionCode()); - if (versionCodeInstalled < applicationVersion.getVersionCode()) { - // An update is available for download - - // If the APK has been downloaded (but not yet installed), display the "Install update" button + // Check if any application versions (APKs) have been uploaded to the webapp + ApplicationVersion newestApplicationVersion = getNewestApplicationVersion(application, applicationVersions); + Timber.i("newestApplicationVersion: " + newestApplicationVersion); + if (newestApplicationVersion != null) { + // Display a button matching the current state of the application + // "Download", "Install", "Launch", "Download update", "Install update" + + if (InstallationHelper.isApplicationInstalled(application.getPackageName(), context)) { + // The APK has been installed + + // Check if an update is available for download + int versionCodeInstalled = InstallationHelper.getVersionCodeOfInstalledApplication(application.getPackageName(), context); + Timber.i("versionCodeInstalled: " + versionCodeInstalled); + ApplicationVersion applicationVersion = getNewestApplicationVersion(application, applicationVersions); + Timber.i("applicationVersion.getVersionCode(): " + applicationVersion.getVersionCode()); + if (versionCodeInstalled < applicationVersion.getVersionCode()) { + // An update is available for download + + // If the APK has been downloaded (but not yet installed), display the "Install update" button + File apkFile = FileHelper.getApkFile(application.getPackageName(), applicationVersion.getVersionCode(), context); + Timber.i("apkFile: " + apkFile); + Timber.i("apkFile.exists(): " + apkFile.exists()); + if (apkFile.exists()) { + viewHolder.installUpdateButton.setVisibility(View.VISIBLE); + View.OnClickListener onClickListener = v -> { + Timber.i("viewHolder.installUpdateButton onClick"); + + // Initiate installation of the APK file + IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addDataScheme("package"); + context.registerReceiver(new PackageAddedReceiver(position), intentFilter); + Uri apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".apk.provider", apkFile); + Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + intent.setData(apkUri); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + context.startActivity(intent); + }; + viewHolder.installUpdateButton.setOnClickListener(onClickListener); + } + + // If the APK has not been downloaded, display the "Download update" button + if (!apkFile.exists()) { + viewHolder.downloadUpdateButton.setVisibility(View.VISIBLE); + ApplicationVersion finalApplicationVersion = applicationVersion; + viewHolder.downloadUpdateButton.setOnClickListener(v -> { + Timber.i("viewHolder.downloadUpdateButton onClick"); + + // Initiate download of the APK file + context.registerReceiver(new DownloadCompleteReceiver(position), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + BaseApplication baseApplication = (BaseApplication) context.getApplicationContext(); + String fileUrl = baseApplication.getBaseUrl() + finalApplicationVersion.getFileUrl(); + Timber.i("fileUrl: " + fileUrl); + DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(fileUrl)); + String destinationInExternalFilesDir = File.separator + "lang-" + SharedPreferencesHelper.getLanguage(context).getIsoCode() + File.separator + "apks" + File.separator + apkFile.getName(); + Timber.i("destinationInExternalFilesDir: " + destinationInExternalFilesDir); + request.setDestinationInExternalFilesDir(context, null, destinationInExternalFilesDir); + long downloadId = downloadManager.enqueue(request); + Timber.i("downloadId: " + downloadId); + + // Replace download button with progress bar + viewHolder.downloadUpdateButton.setVisibility(View.INVISIBLE); + viewHolder.downloadProgressBar.setVisibility(View.VISIBLE); + }); + } + } else { + // The installed APK is up-to-date + + // Display the "Launch" button + viewHolder.launchButton.setVisibility(View.VISIBLE); + viewHolder.launchButton.setOnClickListener((View.OnClickListener) v -> { + Timber.i("onClick"); + + Timber.i("Launching \"" + application.getPackageName() + "\""); + PackageManager packageManager = context.getPackageManager(); + Intent launchIntent = packageManager.getLaunchIntentForPackage(application.getPackageName()); + Timber.i("launchIntent: " + launchIntent); + context.startActivity(launchIntent); + }); + } + } else { + // The APK has not been installed + + // Fetch information about the newest APK file + ApplicationVersion applicationVersion = getNewestApplicationVersion(application, applicationVersions); + if (applicationVersion == null) { + return; + } + Timber.i("applicationVersion.getVersionCode(): " + applicationVersion.getVersionCode()); + + // If the APK has been downloaded (but not yet installed), display the "Install" button File apkFile = FileHelper.getApkFile(application.getPackageName(), applicationVersion.getVersionCode(), context); Timber.i("apkFile: " + apkFile); Timber.i("apkFile.exists(): " + apkFile.exists()); if (apkFile.exists()) { - viewHolder.installUpdateButton.setVisibility(View.VISIBLE); + viewHolder.installButton.setVisibility(View.VISIBLE); View.OnClickListener onClickListener = v -> { - Timber.i("viewHolder.installUpdateButton onClick"); + Timber.i("viewHolder.installButton onClick"); // Initiate installation of the APK file IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); @@ -112,15 +191,15 @@ public void onBindViewHolder(ApplicationViewHolder viewHolder, int position) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); context.startActivity(intent); }; - viewHolder.installUpdateButton.setOnClickListener(onClickListener); + viewHolder.installButton.setOnClickListener(onClickListener); } - // If the APK has not been downloaded, display the "Download update" button + // If the APK has not been downloaded, display the "Download" button if (!apkFile.exists()) { - viewHolder.downloadUpdateButton.setVisibility(View.VISIBLE); + viewHolder.downloadButton.setVisibility(View.VISIBLE); ApplicationVersion finalApplicationVersion = applicationVersion; - viewHolder.downloadUpdateButton.setOnClickListener(v -> { - Timber.i("viewHolder.downloadUpdateButton onClick"); + viewHolder.downloadButton.setOnClickListener(v -> { + Timber.i("viewHolder.downloadButton onClick"); // Initiate download of the APK file context.registerReceiver(new DownloadCompleteReceiver(position), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); @@ -136,81 +215,10 @@ public void onBindViewHolder(ApplicationViewHolder viewHolder, int position) { Timber.i("downloadId: " + downloadId); // Replace download button with progress bar - viewHolder.downloadUpdateButton.setVisibility(View.INVISIBLE); + viewHolder.downloadButton.setVisibility(View.INVISIBLE); viewHolder.downloadProgressBar.setVisibility(View.VISIBLE); }); } - } else { - // The installed APK is up-to-date - - // Display the "Launch" button - viewHolder.launchButton.setVisibility(View.VISIBLE); - viewHolder.launchButton.setOnClickListener((View.OnClickListener) v -> { - Timber.i("onClick"); - - Timber.i("Launching \"" + application.getPackageName() + "\""); - PackageManager packageManager = context.getPackageManager(); - Intent launchIntent = packageManager.getLaunchIntentForPackage(application.getPackageName()); - Timber.i("launchIntent: " + launchIntent); - context.startActivity(launchIntent); - }); - } - } else { - // The APK has not been installed - - // Fetch information about the newest APK file - ApplicationVersion applicationVersion = getNewestApplicationVersion(application, applicationVersions); - if (applicationVersion == null) { - return; - } - Timber.i("applicationVersion.getVersionCode(): " + applicationVersion.getVersionCode()); - - // If the APK has been downloaded (but not yet installed), display the "Install" button - File apkFile = FileHelper.getApkFile(application.getPackageName(), applicationVersion.getVersionCode(), context); - Timber.i("apkFile: " + apkFile); - Timber.i("apkFile.exists(): " + apkFile.exists()); - if (apkFile.exists()) { - viewHolder.installButton.setVisibility(View.VISIBLE); - View.OnClickListener onClickListener = v -> { - Timber.i("viewHolder.installButton onClick"); - - // Initiate installation of the APK file - IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); - intentFilter.addDataScheme("package"); - context.registerReceiver(new PackageAddedReceiver(position), intentFilter); - Uri apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".apk.provider", apkFile); - Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); - intent.setData(apkUri); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - context.startActivity(intent); - }; - viewHolder.installButton.setOnClickListener(onClickListener); - } - - // If the APK has not been downloaded, display the "Download" button - if (!apkFile.exists()) { - viewHolder.downloadButton.setVisibility(View.VISIBLE); - ApplicationVersion finalApplicationVersion = applicationVersion; - viewHolder.downloadButton.setOnClickListener(v -> { - Timber.i("viewHolder.downloadButton onClick"); - - // Initiate download of the APK file - context.registerReceiver(new DownloadCompleteReceiver(position), new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); - BaseApplication baseApplication = (BaseApplication) context.getApplicationContext(); - String fileUrl = baseApplication.getBaseUrl() + finalApplicationVersion.getFileUrl(); - Timber.i("fileUrl: " + fileUrl); - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - DownloadManager.Request request = new DownloadManager.Request(Uri.parse(fileUrl)); - String destinationInExternalFilesDir = File.separator + "lang-" + SharedPreferencesHelper.getLanguage(context).getIsoCode() + File.separator + "apks" + File.separator + apkFile.getName(); - Timber.i("destinationInExternalFilesDir: " + destinationInExternalFilesDir); - request.setDestinationInExternalFilesDir(context, null, destinationInExternalFilesDir); - long downloadId = downloadManager.enqueue(request); - Timber.i("downloadId: " + downloadId); - - // Replace download button with progress bar - viewHolder.downloadButton.setVisibility(View.INVISIBLE); - viewHolder.downloadProgressBar.setVisibility(View.VISIBLE); - }); } } }