1313import android .media .projection .MediaProjectionManager ;
1414import android .os .Build ;
1515import android .os .Bundle ;
16+ import android .provider .Settings ;
1617import android .util .DisplayMetrics ;
1718import android .util .Log ;
1819import android .view .LayoutInflater ;
3233import androidx .activity .result .contract .ActivityResultContracts ;
3334import androidx .annotation .NonNull ;
3435import androidx .annotation .Nullable ;
36+ import androidx .appcompat .app .AlertDialog ;
37+ import androidx .core .app .NotificationManagerCompat ;
3538
3639import io .agora .api .example .MainApplication ;
3740import io .agora .api .example .R ;
3841import io .agora .api .example .annotation .Example ;
3942import io .agora .api .example .common .BaseFragment ;
4043import io .agora .api .example .service .MediaProjectionService ;
4144import io .agora .api .example .utils .CommonUtil ;
42- import io .agora .api .example .utils .PermissonUtils ;
4345import io .agora .api .example .utils .TokenUtils ;
4446import io .agora .rtc2 .ChannelMediaOptions ;
4547import io .agora .rtc2 .Constants ;
5254import io .agora .rtc2 .video .VideoCanvas ;
5355import io .agora .rtc2 .video .VideoEncoderConfiguration ;
5456
57+ import java .lang .reflect .Field ;
58+ import java .lang .reflect .Method ;
59+
5560/**
5661 * This example demonstrates how video can be flexibly switched between the camera stream and the
5762 * screen share stream during an audio-video call.
@@ -86,7 +91,6 @@ public class ScreenSharing extends BaseFragment implements View.OnClickListener,
8691 private final ActivityResultLauncher <Intent > mediaProjectionLauncher = registerForActivityResult (
8792 new ActivityResultContracts .StartActivityForResult (),
8893 result -> {
89- Log .d (TAG , "result-------------------result.getResultCode(): " + result .getResultCode ());
9094 if (result .getResultCode () == Activity .RESULT_OK ) {
9195 try {
9296 mediaProjection [0 ] = mediaProjectionManager
@@ -118,7 +122,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
118122 join .setOnClickListener (this );
119123
120124 screenPreview = view .findViewById (R .id .screen_preview );
121- externalMediaPro = view .findViewById (R .id .media_projection_external );
125+ // externalMediaPro = view.findViewById(R.id.media_projection_external);
122126 screenAudio = view .findViewById (R .id .screen_audio );
123127 screenAudioVolume = view .findViewById (R .id .screen_audio_volume );
124128 screenScenarioType = view .findViewById (R .id .spinner_screen_scenario_type );
@@ -185,11 +189,35 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
185189 e .printStackTrace ();
186190 getActivity ().onBackPressed ();
187191 }
192+ enableNotifications ();
193+ }
194+
195+ private void enableNotifications () {
196+ if (NotificationManagerCompat .from (requireContext ()).areNotificationsEnabled ()) {
197+ Log .d (TAG , "Notifications enable!" );
198+ return ;
199+ }
200+ Log .d (TAG , "Notifications not enable!" );
201+ new AlertDialog .Builder (requireContext ())
202+ .setTitle ("Tip" )
203+ .setMessage (R .string .notifications_enable_screen_tip )
204+ .setPositiveButton (R .string .setting , (dialog , which ) -> {
205+ Intent intent = new Intent ();
206+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
207+ intent .setAction (Settings .ACTION_APP_NOTIFICATION_SETTINGS );
208+ intent .putExtra (Settings .EXTRA_APP_PACKAGE , requireContext ().getPackageName ());
209+ intent .putExtra (Settings .EXTRA_CHANNEL_ID , requireContext ().getApplicationInfo ().uid );
210+ } else {
211+ intent .setAction (Settings .ACTION_APPLICATION_DETAILS_SETTINGS );
212+ }
213+ startActivity (intent );
214+ dialog .dismiss ();
215+ })
216+ .show ();
188217 }
189218
190219 @ Override
191220 public void onDestroy () {
192- stopService ();
193221 /*leaveChannel and Destroy the RtcEngine instance*/
194222 if (engine != null ) {
195223 engine .leaveChannel ();
@@ -219,8 +247,23 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
219247 }
220248 screenCaptureParameters .captureAudio = checked ;
221249 engine .updateScreenCaptureParameters (screenCaptureParameters );
222- } else if (compoundButton == externalMediaPro ) {
250+ } /*else if (compoundButton == externalMediaPro) {
251+ }*/
252+ }
253+
254+ @ Override
255+ protected void onBackPressed () {
256+ joined = false ;
257+ stopMediaProjectionService ();
258+ /*leaveChannel and Destroy the RtcEngine instance*/
259+ if (engine != null ) {
260+ engine .leaveChannel ();
261+ engine .stopScreenCapture ();
262+ engine .stopPreview ();
223263 }
264+ handler .post (RtcEngine ::destroy );
265+ engine = null ;
266+ super .onBackPressed ();
224267 }
225268
226269 @ Override
@@ -231,15 +274,12 @@ public void onClick(View v) {
231274 // call when join button hit
232275 channelId = et_channel .getText ().toString ();
233276 // Check permission
234- checkOrRequestPermisson (new PermissonUtils .PermissionResultCallback () {
235- @ Override
236- public void onPermissionsResult (boolean allPermissionsGranted , String [] permissions , int [] grantResults ) {
237- if (allPermissionsGranted ) {
238- if (externalMediaPro .isChecked ()) {
239- requestScreenCapture ();
240- } else {
241- joinChannel ();
242- }
277+ checkOrRequestPermisson ((allPermissionsGranted , permissions , grantResults ) -> {
278+ if (allPermissionsGranted ) {
279+ if (externalMediaPro .isChecked ()) {
280+ requestScreenCapture ();
281+ } else {
282+ joinChannel ();
243283 }
244284 }
245285 });
@@ -278,24 +318,41 @@ private void stopScreenSharePreview() {
278318 engine .stopPreview (Constants .VideoSourceType .VIDEO_SOURCE_SCREEN_PRIMARY );
279319 }
280320
281- private void startService () {
282- // if (joined) {
283- Intent intent = new Intent (requireContext (), MediaProjectionService .class );
284- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
285- requireContext ().startForegroundService (intent );
286- } else {
287- requireContext ().startService (intent );
321+ @ Override
322+ public void onPause () {
323+ super .onPause ();
324+ // startMediaProjectionService();
325+ }
326+
327+ @ Override
328+ public void onResume () {
329+ super .onResume ();
330+ // stopMediaProjectionService();
331+ }
332+
333+ private void startMediaProjectionService () {
334+ if (joined ) {
335+ Context context = getContext ();
336+ if (context != null ) {
337+ Intent intent = new Intent (context , MediaProjectionService .class );
338+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
339+ context .startForegroundService (intent );
340+ } else {
341+ context .startService (intent );
342+ }
343+ }
288344 }
289- // }
290345 }
291346
292- private void stopService () {
293- Intent serviceIntent = new Intent (getContext (), MediaProjectionService .class );
294- getContext ().stopService (serviceIntent );
347+ private void stopMediaProjectionService () {
348+ Context context = getContext ();
349+ if (context != null ) {
350+ Intent serviceIntent = new Intent (context , MediaProjectionService .class );
351+ context .stopService (serviceIntent );
352+ }
295353 }
296354
297355 private void requestScreenCapture () {
298- startService ();
299356 Intent intent = mediaProjectionManager .createScreenCaptureIntent ();
300357 mediaProjectionLauncher .launch (intent );
301358 }
@@ -519,7 +576,6 @@ public void onUserOffline(int uid, int reason) {
519576
520577 private void leaveChannel () {
521578 externalMediaPro .setEnabled (true );
522- stopService ();
523579 joined = false ;
524580 join .setText (getString (R .string .join ));
525581 fl_local .removeAllViews ();
0 commit comments