actually fix crashes from update notifications on < android-11
8600ce8d8a56398a4eb731f0cccb848c4e18d2eb didn't get all the affected places. #1306
This commit is contained in:
parent
978f4a2928
commit
5547f12527
@ -7,6 +7,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
@ -36,7 +37,6 @@ import java.util.Map;
|
|||||||
* and {@code versionCode} since there could be different copies of the same
|
* and {@code versionCode} since there could be different copies of the same
|
||||||
* APK on different servers, signed by different keys, or even different builds.
|
* APK on different servers, signed by different keys, or even different builds.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("LineLength")
|
|
||||||
public final class AppUpdateStatusManager {
|
public final class AppUpdateStatusManager {
|
||||||
|
|
||||||
private static final String TAG = "AppUpdateStatusManager";
|
private static final String TAG = "AppUpdateStatusManager";
|
||||||
@ -132,7 +132,7 @@ public final class AppUpdateStatusManager {
|
|||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return app.packageName + " [Status: " + status
|
return app.packageName + " [Status: " + status
|
||||||
+ ", Progress: " + progressCurrent + " / " + progressMax + "]";
|
+ ", Progress: " + progressCurrent + " / " + progressMax + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AppUpdateStatus(Parcel in) {
|
protected AppUpdateStatus(Parcel in) {
|
||||||
@ -257,20 +257,14 @@ public final class AppUpdateStatusManager {
|
|||||||
boolean isStatusUpdate = entry.status != status;
|
boolean isStatusUpdate = entry.status != status;
|
||||||
entry.status = status;
|
entry.status = status;
|
||||||
entry.intent = intent;
|
entry.intent = intent;
|
||||||
// If intent not set, see if we need to create a default intent
|
setEntryContentIntentIfEmpty(entry);
|
||||||
if (entry.intent == null) {
|
|
||||||
entry.intent = getContentIntent(entry);
|
|
||||||
}
|
|
||||||
notifyChange(entry, isStatusUpdate);
|
notifyChange(entry, isStatusUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addApkInternal(@NonNull Apk apk, @NonNull Status status, PendingIntent intent) {
|
private void addApkInternal(@NonNull Apk apk, @NonNull Status status, PendingIntent intent) {
|
||||||
Utils.debugLog(LOGTAG, "Add APK " + apk.apkName + " with state " + status.name());
|
Utils.debugLog(LOGTAG, "Add APK " + apk.apkName + " with state " + status.name());
|
||||||
AppUpdateStatus entry = createAppEntry(apk, status, intent);
|
AppUpdateStatus entry = createAppEntry(apk, status, intent);
|
||||||
// If intent not set, see if we need to create a default intent
|
setEntryContentIntentIfEmpty(entry);
|
||||||
if (entry.intent == null) {
|
|
||||||
entry.intent = getContentIntent(entry);
|
|
||||||
}
|
|
||||||
appMapping.put(entry.getUniqueKey(), entry);
|
appMapping.put(entry.getUniqueKey(), entry);
|
||||||
notifyAdd(entry);
|
notifyAdd(entry);
|
||||||
}
|
}
|
||||||
@ -453,6 +447,7 @@ public final class AppUpdateStatusManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("LineLength")
|
||||||
void clearAllUpdates() {
|
void clearAllUpdates() {
|
||||||
synchronized (appMapping) {
|
synchronized (appMapping) {
|
||||||
for (Iterator<Map.Entry<String, AppUpdateStatus>> it = appMapping.entrySet().iterator(); it.hasNext(); ) { // NOCHECKSTYLE EmptyForIteratorPad
|
for (Iterator<Map.Entry<String, AppUpdateStatus>> it = appMapping.entrySet().iterator(); it.hasNext(); ) { // NOCHECKSTYLE EmptyForIteratorPad
|
||||||
@ -465,6 +460,7 @@ public final class AppUpdateStatusManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("LineLength")
|
||||||
void clearAllInstalled() {
|
void clearAllInstalled() {
|
||||||
synchronized (appMapping) {
|
synchronized (appMapping) {
|
||||||
for (Iterator<Map.Entry<String, AppUpdateStatus>> it = appMapping.entrySet().iterator(); it.hasNext(); ) { // NOCHECKSTYLE EmptyForIteratorPad
|
for (Iterator<Map.Entry<String, AppUpdateStatus>> it = appMapping.entrySet().iterator(); it.hasNext(); ) { // NOCHECKSTYLE EmptyForIteratorPad
|
||||||
@ -477,28 +473,46 @@ public final class AppUpdateStatusManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PendingIntent getContentIntent(AppUpdateStatus entry) {
|
/**
|
||||||
|
* If the {@link PendingIntent} aimed at {@link Notification.Builder#setContentIntent(PendingIntent)}
|
||||||
|
* is not set, then create a default one. The goal is to link the notification
|
||||||
|
* to the most relevant action, like the installer if the APK is downloaded, or the launcher once
|
||||||
|
* installed, if possible, or other relevant action. If there is no app launch
|
||||||
|
* {@code PendingIntent}, the app is probably not launchable, e.g. its a keyboard.
|
||||||
|
* If there is not an {@code PendingIntent} to install the app, this creates an {@code PendingIntent}
|
||||||
|
* to open up the app details page for the app. From there, the user can hit "install".
|
||||||
|
* <p>
|
||||||
|
* Before {@code android-11}, a {@code ContentIntent} was required in every
|
||||||
|
* {@link Notification}. This generates a boilerplate one for places where
|
||||||
|
* there isn't an obvious one.
|
||||||
|
*/
|
||||||
|
private void setEntryContentIntentIfEmpty(AppUpdateStatus entry) {
|
||||||
|
if (entry.intent != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (entry.status) {
|
switch (entry.status) {
|
||||||
case UpdateAvailable:
|
case UpdateAvailable:
|
||||||
case ReadyToInstall:
|
case ReadyToInstall:
|
||||||
// Make sure we have an intent to install the app. If not set, we create an intent
|
entry.intent = getAppDetailsIntent(entry.apk);
|
||||||
// to open up the app details page for the app. From there, the user can hit "install"
|
break;
|
||||||
return getAppDetailsIntent(entry.apk);
|
|
||||||
|
|
||||||
case InstallError:
|
case InstallError:
|
||||||
return getAppErrorIntent(entry);
|
entry.intent = getAppErrorIntent(entry);
|
||||||
|
break;
|
||||||
case Installed:
|
case Installed:
|
||||||
PackageManager pm = context.getPackageManager();
|
PackageManager pm = context.getPackageManager();
|
||||||
Intent intentObject = pm.getLaunchIntentForPackage(entry.app.packageName);
|
Intent intentObject = pm.getLaunchIntentForPackage(entry.app.packageName);
|
||||||
if (intentObject != null) {
|
if (intentObject != null) {
|
||||||
return PendingIntent.getActivity(context, 0, intentObject, 0);
|
entry.intent = PendingIntent.getActivity(context, 0, intentObject, 0);
|
||||||
} else {
|
} else {
|
||||||
// Could not get launch intent, maybe not launchable, e.g. a keyboard
|
entry.intent = getAppDetailsIntent(entry.apk);
|
||||||
return getAppDetailsIntent(entry.apk);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT < 11 && entry.intent == null) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
entry.intent = PendingIntent.getActivity(context, 0, intent, 0);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,9 +77,12 @@ class NotificationHelper {
|
|||||||
BroadcastReceiver receiverAppStatusChanges = new BroadcastReceiver() {
|
BroadcastReceiver receiverAppStatusChanges = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AppUpdateStatusManager.AppUpdateStatus entry;
|
AppUpdateStatusManager.AppUpdateStatus entry;
|
||||||
String url;
|
String url;
|
||||||
|
|
||||||
switch (intent.getAction()) {
|
switch (intent.getAction()) {
|
||||||
case AppUpdateStatusManager.BROADCAST_APPSTATUS_LIST_CHANGED:
|
case AppUpdateStatusManager.BROADCAST_APPSTATUS_LIST_CHANGED:
|
||||||
notificationManager.cancelAll();
|
notificationManager.cancelAll();
|
||||||
@ -434,11 +437,6 @@ class NotificationHelper {
|
|||||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
builder.setDeleteIntent(piDeleted);
|
builder.setDeleteIntent(piDeleted);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < 11) {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
|
|
||||||
}
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user