1111import android .widget .Button ;
1212import android .widget .EditText ;
1313import android .widget .FrameLayout ;
14+ import android .widget .Spinner ;
1415
1516import androidx .annotation .NonNull ;
1617import androidx .annotation .Nullable ;
2122import io .agora .api .example .R ;
2223import io .agora .api .example .annotation .Example ;
2324import io .agora .api .example .common .BaseFragment ;
24- import io .agora .api .example .examples .basic .JoinChannelVideo ;
2525import io .agora .api .example .utils .CommonUtil ;
2626import io .agora .rtc .Constants ;
2727import io .agora .rtc .IRtcEngineEventHandler ;
2828import io .agora .rtc .RtcEngine ;
29+ import io .agora .rtc .RtcEngineConfig ;
2930import io .agora .rtc .video .VideoCanvas ;
3031import io .agora .rtc .video .VideoEncoderConfiguration ;
3132
3233import static io .agora .api .example .common .model .Examples .ADVANCED ;
34+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_AS ;
35+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_CN ;
36+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_EU ;
37+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_GLOB ;
38+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_IN ;
39+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_JP ;
40+ import static io .agora .rtc .RtcEngineConfig .AreaCode .AREA_CODE_NA ;
3341import static io .agora .rtc .video .VideoCanvas .RENDER_MODE_HIDDEN ;
3442import static io .agora .rtc .video .VideoEncoderConfiguration .FRAME_RATE .FRAME_RATE_FPS_15 ;
3543import static io .agora .rtc .video .VideoEncoderConfiguration .ORIENTATION_MODE .ORIENTATION_MODE_ADAPTIVE ;
3644import static io .agora .rtc .video .VideoEncoderConfiguration .STANDARD_BITRATE ;
3745import static io .agora .rtc .video .VideoEncoderConfiguration .VD_640x360 ;
38- //
39- // @Example(
40- // index = 17 ,
41- // group = ADVANCED,
42- // name = R.string.item_geofencing,
43- // actionId = R.id.action_mainFragment_to_GeoFencing,
44- // tipsId = R.string.geofencing
45- // )
46+
47+ @ Example (
48+ index = 20 ,
49+ group = ADVANCED ,
50+ name = R .string .item_geofencing ,
51+ actionId = R .id .action_mainFragment_to_GeoFencing ,
52+ tipsId = R .string .geofencing
53+ )
4654public class GeoFencing extends BaseFragment implements View .OnClickListener {
4755 private static final String TAG = GeoFencing .class .getSimpleName ();
4856
@@ -52,79 +60,85 @@ public class GeoFencing extends BaseFragment implements View.OnClickListener {
5260 private RtcEngine engine ;
5361 private int myUid ;
5462 private boolean joined = false ;
63+ private Spinner areaCode ;
64+
5565
5666 @ Nullable
5767 @ Override
58- public View onCreateView (@ NonNull LayoutInflater inflater , @ Nullable ViewGroup container , @ Nullable Bundle savedInstanceState )
59- {
68+ public View onCreateView (@ NonNull LayoutInflater inflater , @ Nullable ViewGroup container , @ Nullable Bundle savedInstanceState ) {
6069 View view = inflater .inflate (R .layout .fragment_geo_fencing , container , false );
6170 return view ;
6271 }
6372
6473 @ Override
65- public void onViewCreated (@ NonNull View view , @ Nullable Bundle savedInstanceState )
66- {
74+ public void onViewCreated (@ NonNull View view , @ Nullable Bundle savedInstanceState ) {
6775 super .onViewCreated (view , savedInstanceState );
6876 join = view .findViewById (R .id .btn_join );
6977 et_channel = view .findViewById (R .id .et_channel );
7078 view .findViewById (R .id .btn_join ).setOnClickListener (this );
7179 fl_local = view .findViewById (R .id .fl_local );
7280 fl_remote = view .findViewById (R .id .fl_remote );
81+ areaCode = view .findViewById (R .id .areacode );
7382 }
7483
75- @ Override
76- public void onActivityCreated (@ Nullable Bundle savedInstanceState )
77- {
78- super .onActivityCreated (savedInstanceState );
84+ private int getAreaCode () {
85+ switch (areaCode .getSelectedItem ().toString ()) {
86+ case "CN" :
87+ return AREA_CODE_CN ;
88+ case "NA" :
89+ return AREA_CODE_NA ;
90+ case "EU" :
91+ return AREA_CODE_EU ;
92+ case "AS" :
93+ return AREA_CODE_AS ;
94+ case "JP" :
95+ return AREA_CODE_JP ;
96+ case "IN" :
97+ return AREA_CODE_IN ;
98+ default :
99+ return AREA_CODE_GLOB ;
100+ }
101+ }
102+
103+ private void initializeEngine () {
79104 // Check if the context is valid
80105 Context context = getContext ();
81- if (context == null )
82- {
106+ if (context == null || engine != null ) {
83107 return ;
84108 }
85- try
86- {
87- /**Creates an RtcEngine instance.
88- * @param context The context of Android Activity
89- * @param appId The App ID issued to you by Agora. See <a href="https://docs.agora.io/en/Agora%20Platform/token#get-an-app-id">
90- * How to get the App ID</a>
91- * @param handler IRtcEngineEventHandler is an abstract class providing default implementation.
92- * The SDK uses this class to report to the app on SDK runtime events.*/
93- engine = RtcEngine .create (context .getApplicationContext (), getString (R .string .agora_app_id ), iRtcEngineEventHandler );
94- }
95- catch (Exception e )
96- {
109+ try {
110+ RtcEngineConfig config = new RtcEngineConfig ();
111+ config .mAppId = getString (R .string .agora_app_id );
112+ config .mEventHandler = iRtcEngineEventHandler ;
113+ config .mContext = context .getApplicationContext ();
114+ config .mAreaCode = getAreaCode ();
115+ engine = RtcEngine .create (config );
116+ } catch (Exception e ) {
97117 e .printStackTrace ();
98118 getActivity ().onBackPressed ();
99119 }
100120 }
101121
102122 @ Override
103- public void onDestroy ()
104- {
123+ public void onDestroy () {
105124 super .onDestroy ();
106125 /**leaveChannel and Destroy the RtcEngine instance*/
107- if (engine != null )
108- {
126+ if (engine != null ) {
109127 engine .leaveChannel ();
110128 }
111129 handler .post (RtcEngine ::destroy );
112130 engine = null ;
113131 }
114132
115133 @ Override
116- public void onClick (View v )
117- {
118- if (v .getId () == R .id .btn_join )
119- {
120- if (!joined )
121- {
134+ public void onClick (View v ) {
135+ if (v .getId () == R .id .btn_join ) {
136+ if (!joined ) {
122137 CommonUtil .hideInputBoard (getActivity (), et_channel );
123138 // call when join button hit
124139 String channelId = et_channel .getText ().toString ();
125140 // Check permission
126- if (AndPermission .hasPermissions (this , Permission .Group .STORAGE , Permission .Group .MICROPHONE , Permission .Group .CAMERA ))
127- {
141+ if (AndPermission .hasPermissions (this , Permission .Group .STORAGE , Permission .Group .MICROPHONE , Permission .Group .CAMERA )) {
128142 joinChannel (channelId );
129143 return ;
130144 }
@@ -138,9 +152,7 @@ public void onClick(View v)
138152 // Permissions Granted
139153 joinChannel (channelId );
140154 }).start ();
141- }
142- else
143- {
155+ } else {
144156 joined = false ;
145157 /**After joining a channel, the user must call the leaveChannel method to end the
146158 * call before joining another channel. This method returns 0 if the user leaves the
@@ -165,21 +177,19 @@ public void onClick(View v)
165177 }
166178 }
167179
168- private void joinChannel (String channelId )
169- {
180+ private void joinChannel (String channelId ) {
181+ initializeEngine ();
170182 // Check if the context is valid
171183 Context context = getContext ();
172- if (context == null )
173- {
184+ if (context == null ) {
174185 return ;
175186 }
176187
177188 // Create render view by RtcEngine
178189 SurfaceView surfaceView = RtcEngine .CreateRendererView (context );
179190 // Local video is on the top
180191 surfaceView .setZOrderMediaOverlay (true );
181- if (fl_local .getChildCount () > 0 )
182- {
192+ if (fl_local .getChildCount () > 0 ) {
183193 fl_local .removeAllViews ();
184194 }
185195 // Add to the local container
@@ -214,15 +224,13 @@ private void joinChannel(String channelId)
214224 * A token generated at the server. This applies to scenarios with high-security requirements. For details, see
215225 * https://docs.agora.io/en/cloud-recording/token_server_java?platform=Java*/
216226 String accessToken = getString (R .string .agora_access_token );
217- if (TextUtils .equals (accessToken , "" ) || TextUtils .equals (accessToken , "<#YOUR ACCESS TOKEN#>" ))
218- {
227+ if (TextUtils .equals (accessToken , "" ) || TextUtils .equals (accessToken , "<#YOUR ACCESS TOKEN#>" )) {
219228 accessToken = null ;
220229 }
221230 /** Allows a user to join a channel.
222231 if you do not specify the uid, we will generate the uid for you*/
223232 int res = engine .joinChannel (accessToken , channelId , "Extra Optional Data" , 0 );
224- if (res != 0 )
225- {
233+ if (res != 0 ) {
226234 // Usually happens with invalid parameters
227235 // Error code description can be found at:
228236 // en: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html
@@ -238,31 +246,31 @@ private void joinChannel(String channelId)
238246 * IRtcEngineEventHandler is an abstract class providing default implementation.
239247 * The SDK uses this class to report to the app on SDK runtime events.
240248 */
241- private final IRtcEngineEventHandler iRtcEngineEventHandler = new IRtcEngineEventHandler ()
242- {
249+ private final IRtcEngineEventHandler iRtcEngineEventHandler = new IRtcEngineEventHandler () {
243250 /**Reports a warning during SDK runtime.
244251 * Warning code: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_warn_code.html*/
245252 @ Override
246- public void onWarning (int warn )
247- {
253+ public void onWarning (int warn ) {
248254 Log .w (TAG , String .format ("onWarning code %d message %s" , warn , RtcEngine .getErrorDescription (warn )));
249255 }
250256
251257 /**Reports an error during SDK runtime.
252258 * Error code: https://docs.agora.io/en/Voice/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_i_rtc_engine_event_handler_1_1_error_code.html*/
253259 @ Override
254- public void onError (int err )
255- {
260+ public void onError (int err ) {
256261 Log .e (TAG , String .format ("onError code %d message %s" , err , RtcEngine .getErrorDescription (err )));
257- showAlert (String .format ("onError code %d message %s" , err , RtcEngine .getErrorDescription (err )));
262+ if (err == 103 ) {
263+ showLongToast ("Current Area Code can't find server resources. Please try to set other area code." );
264+ handler .post (() -> join .setEnabled (true ));
265+ } else
266+ showAlert (String .format ("onError code %d message %s" , err , RtcEngine .getErrorDescription (err )));
258267 }
259268
260269 /**Occurs when a user leaves the channel.
261270 * @param stats With this callback, the application retrieves the channel information,
262271 * such as the call duration and statistics.*/
263272 @ Override
264- public void onLeaveChannel (RtcStats stats )
265- {
273+ public void onLeaveChannel (RtcStats stats ) {
266274 super .onLeaveChannel (stats );
267275 Log .i (TAG , String .format ("local user %d leaveChannel!" , myUid ));
268276 showLongToast (String .format ("local user %d leaveChannel!" , myUid ));
@@ -275,17 +283,14 @@ public void onLeaveChannel(RtcStats stats)
275283 * @param uid User ID
276284 * @param elapsed Time elapsed (ms) from the user calling joinChannel until this callback is triggered*/
277285 @ Override
278- public void onJoinChannelSuccess (String channel , int uid , int elapsed )
279- {
286+ public void onJoinChannelSuccess (String channel , int uid , int elapsed ) {
280287 Log .i (TAG , String .format ("onJoinChannelSuccess channel %s uid %d" , channel , uid ));
281288 showLongToast (String .format ("onJoinChannelSuccess channel %s uid %d" , channel , uid ));
282289 myUid = uid ;
283290 joined = true ;
284- handler .post (new Runnable ()
285- {
291+ handler .post (new Runnable () {
286292 @ Override
287- public void run ()
288- {
293+ public void run () {
289294 join .setEnabled (true );
290295 join .setText (getString (R .string .leave ));
291296 }
@@ -325,8 +330,7 @@ public void run()
325330 * @param elapsed Time elapsed (ms) from the local user calling the joinChannel method
326331 * until the SDK triggers this callback.*/
327332 @ Override
328- public void onRemoteAudioStateChanged (int uid , int state , int reason , int elapsed )
329- {
333+ public void onRemoteAudioStateChanged (int uid , int state , int reason , int elapsed ) {
330334 super .onRemoteAudioStateChanged (uid , state , reason , elapsed );
331335 Log .i (TAG , "onRemoteAudioStateChanged->" + uid + ", state->" + state + ", reason->" + reason );
332336 }
@@ -369,8 +373,7 @@ public void onRemoteAudioStateChanged(int uid, int state, int reason, int elapse
369373 * @param elapsed Time elapsed (ms) from the local user calling the joinChannel method until
370374 * the SDK triggers this callback.*/
371375 @ Override
372- public void onRemoteVideoStateChanged (int uid , int state , int reason , int elapsed )
373- {
376+ public void onRemoteVideoStateChanged (int uid , int state , int reason , int elapsed ) {
374377 super .onRemoteVideoStateChanged (uid , state , reason , elapsed );
375378 Log .i (TAG , "onRemoteVideoStateChanged->" + uid + ", state->" + state + ", reason->" + reason );
376379 }
@@ -380,8 +383,7 @@ public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapse
380383 * @param elapsed Time delay (ms) from the local user calling joinChannel/setClientRole
381384 * until this callback is triggered.*/
382385 @ Override
383- public void onUserJoined (int uid , int elapsed )
384- {
386+ public void onUserJoined (int uid , int elapsed ) {
385387 super .onUserJoined (uid , elapsed );
386388 Log .i (TAG , "onUserJoined->" + uid );
387389 showLongToast (String .format ("user %d joined!" , uid ));
@@ -394,8 +396,7 @@ public void onUserJoined(int uid, int elapsed)
394396 {
395397 /**Display remote video stream*/
396398 SurfaceView surfaceView = null ;
397- if (fl_remote .getChildCount () > 0 )
398- {
399+ if (fl_remote .getChildCount () > 0 ) {
399400 fl_remote .removeAllViews ();
400401 }
401402 // Create render view by RtcEngine
@@ -420,8 +421,7 @@ public void onUserJoined(int uid, int elapsed)
420421 * USER_OFFLINE_BECOME_AUDIENCE(2): (Live broadcast only.) The client role switched from
421422 * the host to the audience.*/
422423 @ Override
423- public void onUserOffline (int uid , int reason )
424- {
424+ public void onUserOffline (int uid , int reason ) {
425425 Log .i (TAG , String .format ("user %d offline! reason:%d" , uid , reason ));
426426 showLongToast (String .format ("user %d offline! reason:%d" , uid , reason ));
427427 handler .post (new Runnable () {
0 commit comments