Move functionality from DemoApplication to DemoUtil
https://developer.android.com/reference/android/app/Application recommends against subclassing application. PiperOrigin-RevId: 322163812
This commit is contained in:
parent
97cc355baf
commit
9594aa45ff
@ -63,6 +63,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
|
||||
implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion
|
||||
implementation 'androidx.appcompat:appcompat:' + androidxAppCompatVersion
|
||||
implementation 'androidx.multidex:multidex:' + androidxMultidexVersion
|
||||
|
@ -35,7 +35,7 @@
|
||||
android:largeHeap="true"
|
||||
android:allowBackup="false"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:name="com.google.android.exoplayer2.demo.DemoApplication"
|
||||
android:name="androidx.multidex.MultiDexApplication"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<activity android:name="com.google.android.exoplayer2.demo.SampleChooserActivity"
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.demo;
|
||||
|
||||
import static com.google.android.exoplayer2.demo.DemoApplication.DOWNLOAD_NOTIFICATION_CHANNEL_ID;
|
||||
import static com.google.android.exoplayer2.demo.DemoUtil.DOWNLOAD_NOTIFICATION_CHANNEL_ID;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
@ -50,10 +50,9 @@ public class DemoDownloadService extends DownloadService {
|
||||
protected DownloadManager getDownloadManager() {
|
||||
// This will only happen once, because getDownloadManager is guaranteed to be called only once
|
||||
// in the life cycle of the process.
|
||||
DemoApplication application = (DemoApplication) getApplication();
|
||||
DownloadManager downloadManager = application.getDownloadManager();
|
||||
DownloadManager downloadManager = DemoUtil.getDownloadManager(/* context= */ this);
|
||||
DownloadNotificationHelper downloadNotificationHelper =
|
||||
application.getDownloadNotificationHelper();
|
||||
DemoUtil.getDownloadNotificationHelper(/* context= */ this);
|
||||
downloadManager.addListener(
|
||||
new TerminalStateNotificationHelper(
|
||||
this, downloadNotificationHelper, FOREGROUND_NOTIFICATION_ID + 1));
|
||||
@ -68,10 +67,13 @@ public class DemoDownloadService extends DownloadService {
|
||||
@Override
|
||||
@NonNull
|
||||
protected Notification getForegroundNotification(@NonNull List<Download> downloads) {
|
||||
return ((DemoApplication) getApplication())
|
||||
.getDownloadNotificationHelper()
|
||||
return DemoUtil.getDownloadNotificationHelper(/* context= */ this)
|
||||
.buildProgressNotification(
|
||||
R.drawable.ic_download, /* contentIntent= */ null, /* message= */ null, downloads);
|
||||
/* context= */ this,
|
||||
R.drawable.ic_download,
|
||||
/* contentIntent= */ null,
|
||||
/* message= */ null,
|
||||
downloads);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,12 +103,14 @@ public class DemoDownloadService extends DownloadService {
|
||||
if (download.state == Download.STATE_COMPLETED) {
|
||||
notification =
|
||||
notificationHelper.buildDownloadCompletedNotification(
|
||||
context,
|
||||
R.drawable.ic_download_done,
|
||||
/* contentIntent= */ null,
|
||||
Util.fromUtf8Bytes(download.request.data));
|
||||
} else if (download.state == Download.STATE_FAILED) {
|
||||
notification =
|
||||
notificationHelper.buildDownloadFailedNotification(
|
||||
context,
|
||||
R.drawable.ic_download_done,
|
||||
/* contentIntent= */ null,
|
||||
Util.fromUtf8Bytes(download.request.data));
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.demo;
|
||||
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
import android.content.Context;
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||
import com.google.android.exoplayer2.RenderersFactory;
|
||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||
@ -38,53 +38,34 @@ import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Executors;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* Placeholder application to facilitate overriding Application methods for debugging and testing.
|
||||
*/
|
||||
public class DemoApplication extends MultiDexApplication {
|
||||
/** Utility methods for the demo app. */
|
||||
public final class DemoUtil {
|
||||
|
||||
public static final String DOWNLOAD_NOTIFICATION_CHANNEL_ID = "download_channel";
|
||||
|
||||
private static final String TAG = "DemoApplication";
|
||||
private static final String TAG = "DemoUtil";
|
||||
private static final String DOWNLOAD_ACTION_FILE = "actions";
|
||||
private static final String DOWNLOAD_TRACKER_ACTION_FILE = "tracked_actions";
|
||||
private static final String DOWNLOAD_CONTENT_DIRECTORY = "downloads";
|
||||
|
||||
private HttpDataSource.Factory httpDataSourceFactory;
|
||||
private DatabaseProvider databaseProvider;
|
||||
private File downloadDirectory;
|
||||
private Cache downloadCache;
|
||||
private DownloadManager downloadManager;
|
||||
private DownloadTracker downloadTracker;
|
||||
private DownloadNotificationHelper downloadNotificationHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper(/* context= */ this);
|
||||
String userAgent = Util.getUserAgent(this, "ExoPlayerDemo");
|
||||
httpDataSourceFactory =
|
||||
new CronetDataSourceFactory(
|
||||
cronetEngineWrapper,
|
||||
Executors.newSingleThreadExecutor(),
|
||||
/* transferListener= */ null,
|
||||
userAgent);
|
||||
}
|
||||
|
||||
/** Returns a {@link DataSource.Factory}. */
|
||||
public DataSource.Factory buildDataSourceFactory() {
|
||||
DefaultDataSourceFactory upstreamFactory =
|
||||
new DefaultDataSourceFactory(/* context= */ this, httpDataSourceFactory);
|
||||
return buildReadOnlyCacheDataSource(upstreamFactory, getDownloadCache());
|
||||
}
|
||||
private static DataSource.@MonotonicNonNull Factory dataSourceFactory;
|
||||
private static HttpDataSource.@MonotonicNonNull Factory httpDataSourceFactory;
|
||||
private static @MonotonicNonNull DatabaseProvider databaseProvider;
|
||||
private static @MonotonicNonNull File downloadDirectory;
|
||||
private static @MonotonicNonNull Cache downloadCache;
|
||||
private static @MonotonicNonNull DownloadManager downloadManager;
|
||||
private static @MonotonicNonNull DownloadTracker downloadTracker;
|
||||
private static @MonotonicNonNull DownloadNotificationHelper downloadNotificationHelper;
|
||||
|
||||
/** Returns whether extension renderers should be used. */
|
||||
public boolean useExtensionRenderers() {
|
||||
public static boolean useExtensionRenderers() {
|
||||
return "withDecoderExtensions".equals(BuildConfig.FLAVOR);
|
||||
}
|
||||
|
||||
public RenderersFactory buildRenderersFactory(boolean preferExtensionRenderer) {
|
||||
public static RenderersFactory buildRenderersFactory(
|
||||
Context context, boolean preferExtensionRenderer) {
|
||||
@DefaultRenderersFactory.ExtensionRendererMode
|
||||
int extensionRendererMode =
|
||||
useExtensionRenderers()
|
||||
@ -92,61 +73,96 @@ public class DemoApplication extends MultiDexApplication {
|
||||
? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
|
||||
: DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
|
||||
: DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
|
||||
return new DefaultRenderersFactory(/* context= */ this)
|
||||
return new DefaultRenderersFactory(context.getApplicationContext())
|
||||
.setExtensionRendererMode(extensionRendererMode);
|
||||
}
|
||||
|
||||
public DownloadNotificationHelper getDownloadNotificationHelper() {
|
||||
public static synchronized HttpDataSource.Factory getHttpDataSourceFactory(Context context) {
|
||||
if (httpDataSourceFactory == null) {
|
||||
context = context.getApplicationContext();
|
||||
CronetEngineWrapper cronetEngineWrapper = new CronetEngineWrapper(context);
|
||||
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo");
|
||||
httpDataSourceFactory =
|
||||
new CronetDataSourceFactory(
|
||||
cronetEngineWrapper,
|
||||
Executors.newSingleThreadExecutor(),
|
||||
/* transferListener= */ null,
|
||||
userAgent);
|
||||
}
|
||||
return httpDataSourceFactory;
|
||||
}
|
||||
|
||||
/** Returns a {@link DataSource.Factory}. */
|
||||
public static synchronized DataSource.Factory buildDataSourceFactory(Context context) {
|
||||
if (dataSourceFactory == null) {
|
||||
context = context.getApplicationContext();
|
||||
DefaultDataSourceFactory upstreamFactory =
|
||||
new DefaultDataSourceFactory(context, getHttpDataSourceFactory(context));
|
||||
dataSourceFactory = buildReadOnlyCacheDataSource(upstreamFactory, getDownloadCache(context));
|
||||
}
|
||||
return dataSourceFactory;
|
||||
}
|
||||
|
||||
public static synchronized DownloadNotificationHelper getDownloadNotificationHelper(
|
||||
Context context) {
|
||||
if (downloadNotificationHelper == null) {
|
||||
downloadNotificationHelper =
|
||||
new DownloadNotificationHelper(this, DOWNLOAD_NOTIFICATION_CHANNEL_ID);
|
||||
new DownloadNotificationHelper(context, DOWNLOAD_NOTIFICATION_CHANNEL_ID);
|
||||
}
|
||||
return downloadNotificationHelper;
|
||||
}
|
||||
|
||||
public DownloadManager getDownloadManager() {
|
||||
initDownloadManager();
|
||||
public static synchronized DownloadManager getDownloadManager(Context context) {
|
||||
ensureDownloadManagerInitialized(context);
|
||||
return downloadManager;
|
||||
}
|
||||
|
||||
public DownloadTracker getDownloadTracker() {
|
||||
initDownloadManager();
|
||||
public static synchronized DownloadTracker getDownloadTracker(Context context) {
|
||||
ensureDownloadManagerInitialized(context);
|
||||
return downloadTracker;
|
||||
}
|
||||
|
||||
private synchronized Cache getDownloadCache() {
|
||||
private static synchronized Cache getDownloadCache(Context context) {
|
||||
if (downloadCache == null) {
|
||||
File downloadContentDirectory = new File(getDownloadDirectory(), DOWNLOAD_CONTENT_DIRECTORY);
|
||||
File downloadContentDirectory =
|
||||
new File(getDownloadDirectory(context), DOWNLOAD_CONTENT_DIRECTORY);
|
||||
downloadCache =
|
||||
new SimpleCache(downloadContentDirectory, new NoOpCacheEvictor(), getDatabaseProvider());
|
||||
new SimpleCache(
|
||||
downloadContentDirectory, new NoOpCacheEvictor(), getDatabaseProvider(context));
|
||||
}
|
||||
return downloadCache;
|
||||
}
|
||||
|
||||
private synchronized void initDownloadManager() {
|
||||
private static synchronized void ensureDownloadManagerInitialized(Context context) {
|
||||
if (downloadManager == null) {
|
||||
DefaultDownloadIndex downloadIndex = new DefaultDownloadIndex(getDatabaseProvider());
|
||||
DefaultDownloadIndex downloadIndex = new DefaultDownloadIndex(getDatabaseProvider(context));
|
||||
upgradeActionFile(
|
||||
DOWNLOAD_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ false);
|
||||
context, DOWNLOAD_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ false);
|
||||
upgradeActionFile(
|
||||
DOWNLOAD_TRACKER_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ true);
|
||||
context,
|
||||
DOWNLOAD_TRACKER_ACTION_FILE,
|
||||
downloadIndex,
|
||||
/* addNewDownloadsAsCompleted= */ true);
|
||||
downloadManager =
|
||||
new DownloadManager(
|
||||
/* context= */ this,
|
||||
getDatabaseProvider(),
|
||||
getDownloadCache(),
|
||||
httpDataSourceFactory,
|
||||
context,
|
||||
getDatabaseProvider(context),
|
||||
getDownloadCache(context),
|
||||
getHttpDataSourceFactory(context),
|
||||
Executors.newFixedThreadPool(/* nThreads= */ 6));
|
||||
downloadTracker =
|
||||
new DownloadTracker(/* context= */ this, buildDataSourceFactory(), downloadManager);
|
||||
new DownloadTracker(context, buildDataSourceFactory(context), downloadManager);
|
||||
}
|
||||
}
|
||||
|
||||
private void upgradeActionFile(
|
||||
String fileName, DefaultDownloadIndex downloadIndex, boolean addNewDownloadsAsCompleted) {
|
||||
private static synchronized void upgradeActionFile(
|
||||
Context context,
|
||||
String fileName,
|
||||
DefaultDownloadIndex downloadIndex,
|
||||
boolean addNewDownloadsAsCompleted) {
|
||||
try {
|
||||
ActionFileUpgradeUtil.upgradeAndDelete(
|
||||
new File(getDownloadDirectory(), fileName),
|
||||
new File(getDownloadDirectory(context), fileName),
|
||||
/* downloadIdProvider= */ null,
|
||||
downloadIndex,
|
||||
/* deleteOnFailure= */ true,
|
||||
@ -156,18 +172,18 @@ public class DemoApplication extends MultiDexApplication {
|
||||
}
|
||||
}
|
||||
|
||||
private DatabaseProvider getDatabaseProvider() {
|
||||
private static synchronized DatabaseProvider getDatabaseProvider(Context context) {
|
||||
if (databaseProvider == null) {
|
||||
databaseProvider = new ExoDatabaseProvider(this);
|
||||
databaseProvider = new ExoDatabaseProvider(context);
|
||||
}
|
||||
return databaseProvider;
|
||||
}
|
||||
|
||||
private File getDownloadDirectory() {
|
||||
private static synchronized File getDownloadDirectory(Context context) {
|
||||
if (downloadDirectory == null) {
|
||||
downloadDirectory = getExternalFilesDir(null);
|
||||
downloadDirectory = context.getExternalFilesDir(/* type= */ null);
|
||||
if (downloadDirectory == null) {
|
||||
downloadDirectory = getFilesDir();
|
||||
downloadDirectory = context.getFilesDir();
|
||||
}
|
||||
}
|
||||
return downloadDirectory;
|
||||
@ -181,4 +197,6 @@ public class DemoApplication extends MultiDexApplication {
|
||||
.setCacheWriteDataSinkFactory(null)
|
||||
.setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
|
||||
}
|
||||
|
||||
private DemoUtil() {}
|
||||
}
|
@ -315,7 +315,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
boolean preferExtensionDecoders =
|
||||
intent.getBooleanExtra(IntentUtil.PREFER_EXTENSION_DECODERS_EXTRA, false);
|
||||
RenderersFactory renderersFactory =
|
||||
((DemoApplication) getApplication()).buildRenderersFactory(preferExtensionDecoders);
|
||||
DemoUtil.buildRenderersFactory(/* context= */ this, preferExtensionDecoders);
|
||||
|
||||
trackSelector = new DefaultTrackSelector(/* context= */ this, trackSelectionFactory);
|
||||
trackSelector.setParameters(trackSelectorParameters);
|
||||
@ -357,7 +357,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
|
||||
List<MediaItem> mediaItems =
|
||||
IntentUtil.createMediaItemsFromIntent(
|
||||
intent, ((DemoApplication) getApplication()).getDownloadTracker());
|
||||
intent, DemoUtil.getDownloadTracker(/* context= */ this));
|
||||
boolean hasAds = false;
|
||||
for (int i = 0; i < mediaItems.size(); i++) {
|
||||
MediaItem mediaItem = mediaItems.get(i);
|
||||
@ -439,7 +439,7 @@ public class PlayerActivity extends AppCompatActivity
|
||||
|
||||
/** Returns a new DataSource factory. */
|
||||
protected DataSource.Factory buildDataSourceFactory() {
|
||||
return ((DemoApplication) getApplication()).buildDataSourceFactory();
|
||||
return DemoUtil.buildDataSourceFactory(/* context= */ this);
|
||||
}
|
||||
|
||||
// User controls
|
||||
|
@ -114,9 +114,8 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
Arrays.sort(uris);
|
||||
}
|
||||
|
||||
DemoApplication application = (DemoApplication) getApplication();
|
||||
useExtensionRenderers = application.useExtensionRenderers();
|
||||
downloadTracker = application.getDownloadTracker();
|
||||
useExtensionRenderers = DemoUtil.useExtensionRenderers();
|
||||
downloadTracker = DemoUtil.getDownloadTracker(/* context= */ this);
|
||||
loadSample();
|
||||
|
||||
// Start the download service if it should be running but it's not currently.
|
||||
@ -247,8 +246,8 @@ public class SampleChooserActivity extends AppCompatActivity
|
||||
.show();
|
||||
} else {
|
||||
RenderersFactory renderersFactory =
|
||||
((DemoApplication) getApplication())
|
||||
.buildRenderersFactory(isNonNullAndChecked(preferExtensionDecodersMenuItem));
|
||||
DemoUtil.buildRenderersFactory(
|
||||
/* context= */ this, isNonNullAndChecked(preferExtensionDecodersMenuItem));
|
||||
downloadTracker.toggleDownload(
|
||||
getSupportFragmentManager(), playlistHolder.mediaItems.get(0), renderersFactory);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ public final class DownloadNotificationHelper {
|
||||
|
||||
private static final @StringRes int NULL_STRING_ID = 0;
|
||||
|
||||
private final Context context;
|
||||
private final NotificationCompat.Builder notificationBuilder;
|
||||
|
||||
/**
|
||||
@ -39,14 +38,14 @@ public final class DownloadNotificationHelper {
|
||||
* @param channelId The id of the notification channel to use.
|
||||
*/
|
||||
public DownloadNotificationHelper(Context context, String channelId) {
|
||||
context = context.getApplicationContext();
|
||||
this.context = context;
|
||||
this.notificationBuilder = new NotificationCompat.Builder(context, channelId);
|
||||
this.notificationBuilder =
|
||||
new NotificationCompat.Builder(context.getApplicationContext(), channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a progress notification for the given downloads.
|
||||
*
|
||||
* @param context A context.
|
||||
* @param smallIcon A small icon for the notification.
|
||||
* @param contentIntent An optional content intent to send when the notification is clicked.
|
||||
* @param message An optional message to display on the notification.
|
||||
@ -54,6 +53,7 @@ public final class DownloadNotificationHelper {
|
||||
* @return The notification.
|
||||
*/
|
||||
public Notification buildProgressNotification(
|
||||
Context context,
|
||||
@DrawableRes int smallIcon,
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message,
|
||||
@ -95,6 +95,7 @@ public final class DownloadNotificationHelper {
|
||||
indeterminate = allDownloadPercentagesUnknown && haveDownloadedBytes;
|
||||
}
|
||||
return buildNotification(
|
||||
context,
|
||||
smallIcon,
|
||||
contentIntent,
|
||||
message,
|
||||
@ -109,37 +110,47 @@ public final class DownloadNotificationHelper {
|
||||
/**
|
||||
* Returns a notification for a completed download.
|
||||
*
|
||||
* @param context A context.
|
||||
* @param smallIcon A small icon for the notifications.
|
||||
* @param contentIntent An optional content intent to send when the notification is clicked.
|
||||
* @param message An optional message to display on the notification.
|
||||
* @return The notification.
|
||||
*/
|
||||
public Notification buildDownloadCompletedNotification(
|
||||
@DrawableRes int smallIcon, @Nullable PendingIntent contentIntent, @Nullable String message) {
|
||||
Context context,
|
||||
@DrawableRes int smallIcon,
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message) {
|
||||
int titleStringId = R.string.exo_download_completed;
|
||||
return buildEndStateNotification(smallIcon, contentIntent, message, titleStringId);
|
||||
return buildEndStateNotification(context, smallIcon, contentIntent, message, titleStringId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a notification for a failed download.
|
||||
*
|
||||
* @param context A context.
|
||||
* @param smallIcon A small icon for the notifications.
|
||||
* @param contentIntent An optional content intent to send when the notification is clicked.
|
||||
* @param message An optional message to display on the notification.
|
||||
* @return The notification.
|
||||
*/
|
||||
public Notification buildDownloadFailedNotification(
|
||||
@DrawableRes int smallIcon, @Nullable PendingIntent contentIntent, @Nullable String message) {
|
||||
Context context,
|
||||
@DrawableRes int smallIcon,
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message) {
|
||||
@StringRes int titleStringId = R.string.exo_download_failed;
|
||||
return buildEndStateNotification(smallIcon, contentIntent, message, titleStringId);
|
||||
return buildEndStateNotification(context, smallIcon, contentIntent, message, titleStringId);
|
||||
}
|
||||
|
||||
private Notification buildEndStateNotification(
|
||||
Context context,
|
||||
@DrawableRes int smallIcon,
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message,
|
||||
@StringRes int titleStringId) {
|
||||
return buildNotification(
|
||||
context,
|
||||
smallIcon,
|
||||
contentIntent,
|
||||
message,
|
||||
@ -152,6 +163,7 @@ public final class DownloadNotificationHelper {
|
||||
}
|
||||
|
||||
private Notification buildNotification(
|
||||
Context context,
|
||||
@DrawableRes int smallIcon,
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message,
|
||||
|
@ -52,7 +52,7 @@ public final class DownloadNotificationUtil {
|
||||
@Nullable String message,
|
||||
List<Download> downloads) {
|
||||
return new DownloadNotificationHelper(context, channelId)
|
||||
.buildProgressNotification(smallIcon, contentIntent, message, downloads);
|
||||
.buildProgressNotification(context, smallIcon, contentIntent, message, downloads);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +72,7 @@ public final class DownloadNotificationUtil {
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message) {
|
||||
return new DownloadNotificationHelper(context, channelId)
|
||||
.buildDownloadCompletedNotification(smallIcon, contentIntent, message);
|
||||
.buildDownloadCompletedNotification(context, smallIcon, contentIntent, message);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,6 +92,6 @@ public final class DownloadNotificationUtil {
|
||||
@Nullable PendingIntent contentIntent,
|
||||
@Nullable String message) {
|
||||
return new DownloadNotificationHelper(context, channelId)
|
||||
.buildDownloadFailedNotification(smallIcon, contentIntent, message);
|
||||
.buildDownloadFailedNotification(context, smallIcon, contentIntent, message);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user