Request notification permission in demo app for API 33+

Starting with API 33 the POST_NOTIFICATION permission needs to be
requested at runtime or the notification is not shown.

Note that with an app with targetSdkVersion < 33
but on a device with API 33 the notification permission is automatically
requested when the app starts for the first time. If the user does not
grant the permission, requesting the permission at runtime result in
an empty array of grant results.

Issue: google/ExoPlayer#10884
PiperOrigin-RevId: 501320632
(cherry picked from commit 6bacbaac548d612e85647b4d13c22dae0401447e)
This commit is contained in:
bachinger 2023-01-11 18:39:11 +00:00 committed by christosts
parent 61eeb8b15e
commit b1b9c1207b
3 changed files with 58 additions and 7 deletions

View File

@ -23,6 +23,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-feature android:name="android.software.leanback" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>

View File

@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -41,7 +42,9 @@ import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.DoNotInline;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.MediaItem.ClippingConfiguration;
@ -75,6 +78,7 @@ public class SampleChooserActivity extends AppCompatActivity
private static final String TAG = "SampleChooserActivity";
private static final String GROUP_POSITION_PREFERENCE_KEY = "sample_chooser_group_position";
private static final String CHILD_POSITION_PREFERENCE_KEY = "sample_chooser_child_position";
private static final int POST_NOTIFICATION_PERMISSION_REQUEST_CODE = 100;
private String[] uris;
private boolean useExtensionRenderers;
@ -82,6 +86,8 @@ public class SampleChooserActivity extends AppCompatActivity
private SampleAdapter sampleAdapter;
private MenuItem preferExtensionDecodersMenuItem;
private ExpandableListView sampleListView;
@Nullable private MediaItem downloadMediaItemWaitingForNotificationPermission;
private boolean notificationPermissionToastShown;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -170,12 +176,34 @@ public class SampleChooserActivity extends AppCompatActivity
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == POST_NOTIFICATION_PERMISSION_REQUEST_CODE) {
handlePostNotificationPermissionGrantResults(grantResults);
} else {
handleExternalStoragePermissionGrantResults(grantResults);
}
}
private void handlePostNotificationPermissionGrantResults(int[] grantResults) {
if (!notificationPermissionToastShown
&& (grantResults.length == 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(
getApplicationContext(), R.string.post_notification_not_granted, Toast.LENGTH_LONG)
.show();
notificationPermissionToastShown = true;
}
if (downloadMediaItemWaitingForNotificationPermission != null) {
// Download with or without permission to post notifications.
toggleDownload(downloadMediaItemWaitingForNotificationPermission);
downloadMediaItemWaitingForNotificationPermission = null;
}
}
private void handleExternalStoragePermissionGrantResults(int[] grantResults) {
if (grantResults.length == 0) {
// Empty results are triggered if a permission is requested while another request was already
// pending and can be safely ignored in this case.
return;
}
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadSample();
} else {
Toast.makeText(getApplicationContext(), R.string.sample_list_load_error, Toast.LENGTH_LONG)
@ -242,15 +270,26 @@ public class SampleChooserActivity extends AppCompatActivity
if (downloadUnsupportedStringId != 0) {
Toast.makeText(getApplicationContext(), downloadUnsupportedStringId, Toast.LENGTH_LONG)
.show();
} else if (!notificationPermissionToastShown
&& Util.SDK_INT >= 33
&& checkSelfPermission(Api33.getPostNotificationPermissionString())
!= PackageManager.PERMISSION_GRANTED) {
downloadMediaItemWaitingForNotificationPermission = playlistHolder.mediaItems.get(0);
requestPermissions(
new String[] {Api33.getPostNotificationPermissionString()},
/* requestCode= */ POST_NOTIFICATION_PERMISSION_REQUEST_CODE);
} else {
RenderersFactory renderersFactory =
DemoUtil.buildRenderersFactory(
/* context= */ this, isNonNullAndChecked(preferExtensionDecodersMenuItem));
downloadTracker.toggleDownload(
getSupportFragmentManager(), playlistHolder.mediaItems.get(0), renderersFactory);
toggleDownload(playlistHolder.mediaItems.get(0));
}
}
private void toggleDownload(MediaItem mediaItem) {
RenderersFactory renderersFactory =
DemoUtil.buildRenderersFactory(
/* context= */ this, isNonNullAndChecked(preferExtensionDecodersMenuItem));
downloadTracker.toggleDownload(getSupportFragmentManager(), mediaItem, renderersFactory);
}
private int getDownloadUnsupportedStringId(PlaylistHolder playlistHolder) {
if (playlistHolder.mediaItems.size() > 1) {
return R.string.download_playlist_unsupported;
@ -627,4 +666,13 @@ public class SampleChooserActivity extends AppCompatActivity
this.playlists = new ArrayList<>();
}
}
@RequiresApi(33)
private static class Api33 {
@DoNotInline
public static String getPostNotificationPermissionString() {
return Manifest.permission.POST_NOTIFICATIONS;
}
}
}

View File

@ -45,6 +45,8 @@
<string name="sample_list_load_error">One or more sample lists failed to load</string>
<string name="post_notification_not_granted">Notifications suppressed. Grant permission to see download notifications.</string>
<string name="download_start_error">Failed to start download</string>
<string name="download_start_error_offline_license">Failed to obtain offline license</string>