Unable to set image in ImageView using fragment - android-studio

I am developing an app using fragment, I am facing problem in setting the image in ImageView by capturing image from camera. Image is been stored in the location the only problem is image not set on the ImageView. Same code is running in activity but facing problem in fragment. Kindly help
//To capture image on button click
imgAddCameraImageQuestion.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//if system OS is >= marshmallow, request runtime permission
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ){
if(ContextCompat.checkSelfPermission(getContext(),Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED ||
ContextCompat.checkSelfPermission(getContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
//Permission not enable, request it
String [ ] permission = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
//show popup to request permission
requestPermissions(permission,PERMISSION_CODE);
}
else{
//Permission is granted
openCamera();
}
}
else{
//System OS < Marshmallow
openCamera();
}
}
});
private void openCamera() {
Context applicationContext = MainActivity.getContextOfApplication();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE,"New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION,"From the Camera");
image_uri = applicationContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);
//Camera Intent
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,image_uri);
startActivityForResult(cameraIntent,IMAGE_CAPTURE_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
//Called when image was captured from camera
if(resultCode == Activity.RESULT_OK){
imgQuestion.setImageURI(image_uri);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//this method is called, when user presses Allow or Deny from permission popup
switch(requestCode){
case PERMISSION_CODE: {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//permission from popup was granted
openCamera();
}
else{
//permission from popup denied
StyleableToast.makeText(getContext(),"Permission Denied",R.style.errorToast).show();
}
}
}
}

Related

Why doesn't the QRbarcode app get camera permission

I am following a tutorial to make a barcode-scanning app using a library from ZXing.
I noticed when I run the app it doesn't ask for the camera's permission, and I think it has to do with the "activityresultlauncher" since I had to use that instead of "startactivityfromresult". But I am unsure. Help would be appreciated.
Thank you
public class MainActivity extends AppCompatActivity {
//Makes permission granted permanent
public static final int CAMERA_REQUEST_PERMISSION = 1;
public static final int SCANNING_REQUEST_CODE = 2;
Button button;
ActivityResultLauncher<Intent> activityResultLauncher=registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult scanning_result) {
int result = scanning_result.getResultCode();
Intent data =scanning_result.getData();
new Intent(MainActivity.this,ScanningActivity.class);
}
}
);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.btnscan);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,ScanningActivity.class);
activityResultLauncher.launch(intent);
//Start Scanning
}
});
}
//Checks if android version is better than api
private void StartScanningActivity (){
Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//start Scanning
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//asks for permission
requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_PERMISSION);
} else {
//Start scanning if passes check
activityResultLauncher.launch(intent);
}
}else{
activityResultLauncher.launch(intent);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_REQUEST_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(MainActivity.this,ScanningActivity.class);
activityResultLauncher.launch(intent);
}
}
}
}

pass string from startActivityForResult to onActivityResult in RecyclerView

I want to upload image and pass string(UID) from startActivityForResult to onActivityResult, and get the string(UID) on onActivityResult.
The startActivityForResult in RecyclerView and onActivityResult in MainActivity.
I can upload image but can't get the string(UID), the string(UID) is null on onActivityResult.
The Null Message
I would appreciate if someone can help me with my questions.
Here is startActivityForResult in RecyclerView:
class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private Button UploadImageButton;
ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textView);
UploadImageButton = itemView.findViewById(R.id.UploadImageButton);
UploadImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.putExtra("UID", textView.getText().toString());
((Activity) context).startActivityForResult(intent, 6);
}
});
}
}
Here is onActivityResult in MainActivity:
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (resultCode == RESULT_OK) {
if (resultData != null) {
String UID = resultData.getStringExtra("UID");
Log.d("UID", UID);
}
}
}
The layout placement
Note
Your startActivityForResult() will only give result of the selected image in the form of Uri. Which means, whatever extras you sent via the intent is useless.
So to solve your issue, one thing you can do is first get the result of the startActivityForResult(), i.e. image Uri, then combine that with the "UID" and then pass these to he MainActivity.

Not able to connect a Video Call - Agora.io

I am trying to make a video calling app for the first time. I am using Agora.io in android studio for video calling. The problem I am facing is I am not able to see the video of the person I am calling. I am perfectly getting my own from the front camera.
I am stuck on this issue for days.
Here is the code of Dashboard.java.
public class Dashboard extends AppCompatActivity {
private static final String TAG = "1";
private static final int PERMISSION_REQ_ID = 22;
// Permission WRITE_EXTERNAL_STORAGE is not mandatory
// for Agora RTC SDK, just in case if you wanna save
// logs to external sdcard.
private static final String[] REQUESTED_PERMISSIONS = {
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private RtcEngine mRtcEngine;
private boolean mCallEnd;
private boolean mMuted;
private FrameLayout mLocalContainer;
private RelativeLayout mRemoteContainer;
private SurfaceView mLocalView;
private SurfaceView mRemoteView;
private ImageView mCallBtn;
private ImageView mMuteBtn;
private ImageView mSwitchCameraBtn;
/**
* Event handler registered into RTC engine for RTC callbacks.
* Note that UI operations needs to be in UI thread because RTC
* engine deals with the events in a separate thread.
*/
private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
#Override
public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
#Override
public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
runOnUiThread(new Runnable() {
#Override
public void run() {
setupRemoteVideo(uid);
}
});
}
#Override
public void onUserOffline(final int uid, int reason) {
runOnUiThread(new Runnable() {
#Override
public void run() {
onRemoteUserLeft();
}
});
}
};
private void setupRemoteVideo(int uid) {
// Only one remote video view is available for this
// tutorial. Here we check if there exists a surface
// view tagged as this uid.
int count = mRemoteContainer.getChildCount();
View view = null;
for (int i = 0; i < count; i++) {
View v = mRemoteContainer.getChildAt(i);
if (v.getTag() instanceof Integer && ((int) v.getTag()) == uid) {
view = v;
}
}
if (view != null) {
return;
}
mRemoteView = RtcEngine.CreateRendererView(getBaseContext());
mRemoteContainer.addView(mRemoteView);
mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView, VideoCanvas.RENDER_MODE_HIDDEN, uid));
mRemoteView.setTag(uid);
}
private void onRemoteUserLeft() {
removeRemoteVideo();
}
private void removeRemoteVideo() {
if (mRemoteView != null) {
mRemoteContainer.removeView(mRemoteView);
}
mRemoteView = null;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
initUI();
// Ask for permissions at runtime.
// This is just an example set of permissions. Other permissions
// may be needed, and please refer to our online documents.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[2], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[3], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
}
private void initUI() {
mLocalContainer = findViewById(R.id.local_video_view_container);
mRemoteContainer = findViewById(R.id.remote_video_view_container);
mCallBtn = findViewById(R.id.btn_call);
mMuteBtn = findViewById(R.id.btn_mute);
mSwitchCameraBtn = findViewById(R.id.btn_switch_camera);
}
private boolean checkSelfPermission(String permission, int requestCode) {
if (ContextCompat.checkSelfPermission(this, permission) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
return false;
}
return true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQ_ID) {
if (grantResults[0] != PackageManager.PERMISSION_GRANTED ||
grantResults[1] != PackageManager.PERMISSION_GRANTED ||
grantResults[2] != PackageManager.PERMISSION_GRANTED ||
grantResults[3] != PackageManager.PERMISSION_GRANTED) {
showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO +
"/" + Manifest.permission.CAMERA + "/" + Manifest.permission.WRITE_EXTERNAL_STORAGE
+ "/" + Manifest.permission.READ_PHONE_STATE);
finish();
return;
}
// Here we continue only if all permissions are granted.
// The permissions can also be granted in the system settings manually.
initEngineAndJoinChannel();
}
}
private void showLongToast(final String msg) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
});
}
private void initEngineAndJoinChannel() {
// This is our usual steps for joining
// a channel and starting a call.
initializeEngine();
setupVideoConfig();
setupLocalVideo();
joinChannel();
}
private void initializeEngine() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.app_id_agora), mRtcEventHandler);
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
private void setupVideoConfig() {
// In simple use cases, we only need to enable video capturing
// and rendering once at the initialization step.
// Note: audio recording and playing is enabled by default.
mRtcEngine.enableVideo();
// Please go to this page for detailed explanation
// https://docs.agora.io/en/Video/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#af5f4de754e2c1f493096641c5c5c1d8f
mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
VideoEncoderConfiguration.VD_640x360,
VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
VideoEncoderConfiguration.STANDARD_BITRATE,
VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
}
private void setupLocalVideo() {
// This is used to set a local preview.
// The steps setting local and remote view are very similar.
// But note that if the local user do not have a uid or do
// not care what the uid is, he can set his uid as ZERO.
// Our server will assign one and return the uid via the event
// handler callback function (onJoinChannelSuccess) after
// joining the channel successfully.
mLocalView = RtcEngine.CreateRendererView(getBaseContext());
mLocalView.setZOrderMediaOverlay(true);
mLocalContainer.addView(mLocalView);
mRtcEngine.setupLocalVideo(new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
}
private void joinChannel() {
// 1. Users can only see each other after they join the
// same channel successfully using the same app id.
// 2. One token is only valid for the channel name that
// you use to generate this token.
String token = "12312323123123wedsa";
mRtcEngine.joinChannel(token, "brolChannelbrobro", "Extra Optional Data", 0);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (!mCallEnd) {
leaveChannel();
}
RtcEngine.destroy();
}
private void leaveChannel() {
mRtcEngine.leaveChannel();
}
public void onLocalAudioMuteClicked(View view) {
mMuted = !mMuted;
mRtcEngine.muteLocalAudioStream(mMuted);
int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_unmute;
mMuteBtn.setImageResource(res);
}
public void onSwitchCameraClicked(View view) {
mRtcEngine.switchCamera();
}
public void onCallClicked(View view) {
if (mCallEnd) {
startCall();
mCallEnd = false;
mCallBtn.setImageResource(R.drawable.btn_endcall);
} else {
endCall();
mCallEnd = true;
mCallBtn.setImageResource(R.drawable.btn_startcall);
}
showButtons(!mCallEnd);
}
private void startCall() {
setupLocalVideo();
joinChannel();
}
private void endCall() {
removeLocalVideo();
removeRemoteVideo();
leaveChannel();
}
private void removeLocalVideo() {
if (mLocalView != null) {
mLocalContainer.removeView(mLocalView);
}
mLocalView = null;
}
private void showButtons(boolean show) {
int visibility = show ? View.VISIBLE : View.GONE;
mMuteBtn.setVisibility(visibility);
mSwitchCameraBtn.setVisibility(visibility);
}
}
I had the same issue. In my case it was a layout problem, as I wasn't making the local video view gone and remote video view visible. I don't know if it still helps after all these years.

Retrofit 2.0 Conditional Logic in onResponse not working

I am trying to make a login logic using post request with retrofit, here is my code
Button btnLogin = (Button) findViewById(R.id.btn_login);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showProgress(true,"Sedang login... ");
String username = inputUsername.getText().toString();
String password = inputPassword.getText().toString();
apiService.login(new LoginParam(username,password)).enqueue(new Callback<AuthResponse>() {
#Override
public void onResponse(Call<AuthResponse> call, Response<AuthResponse> response) {
if(response.isSuccessful()){
showProgress(false,null);
Editor ed = sp.edit();
ed.putString("token",response.body().getToken());
Boolean login = response.body().getLogin();
Log.d("Login",response.body().getLogin().toString());
ed.putBoolean("login",response.body().getLogin().booleanValue());
ed.putString("username",response.body().getUser().getUsername());
ed.commit();
//startActivity(new Intent(getBaseContext(), MainActivity.class));
if(!login){
TextView infologin = (TextView) findViewById(R.id.loginInfo);
infologin.setText("Username dan password salah, coba lagi");
infologin.setVisibility(View.VISIBLE);
return;
}
else{
Intent i = new Intent(getBaseContext(),MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.putExtra("route","afterlogin");
startActivity(i);
finish();
}
}
}
#Override
public void onFailure(Call<AuthResponse> call, Throwable t) {
LoginActivity.this.showProgress(false, null);
Toast.makeText(LoginActivity.this, "Gagal koneksi ke server, periksa jaringan internet anda error: " + t.toString(), Toast.LENGTH_LONG).show();
}
});
}
});
it was working when username and password are correct, but when it was not, it only shows a loading animation, the block that handle if login is false remains inexecuted. what's going wrong?

Unable to find AppLovin SDK key. Please add meta-data android:name="applovin.sdk.key" android:value="YOUR_SDK_KEY_HERE" into AndroidManifest.xml

Hello everyone today I was busy with camera actions just applied rutin camera action on my application and apploving sdk key error actualy application is working but I need to know why I have this this warming on my android monitor
1. Here is my class where I start action and putExtra into intend
public class CameraActionFragment extends Fragment
{
private static final int REQUEST_CODE_IMG = 2;// for image
private static final int REQUEST_CODE_VIDEO = 1;// for video
public static final int RESULT_OK = -1;
Button btn_frag_camera_image;
Button btn_frag_camera;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_camera_action_3, container, false);
//return inflater.inflate(R.layout.fragment_camera_action_3, container, false);
btn_frag_camera_image = (Button) view.findViewById(R.id.btn_frag_camera_image);
btn_frag_camera = (Button) view.findViewById(R.id.btn_frag_camera);
// Image Action
btn_frag_camera_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Hello From Image", Toast.LENGTH_SHORT).show();
Intent intenImatToSec = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intenImatToSec, REQUEST_CODE_IMG);
}
});
// Camera Action
btn_frag_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intenImatToSec = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intenImatToSec, REQUEST_CODE_VIDEO);
//intenImatToSec.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//intenImatToSec.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
//Toast.makeText(getActivity(), "Hello From Camera", Toast.LENGTH_SHORT).show();
}
});
return view;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CODE_IMG) {
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
Intent intentBitMap = new Intent(getActivity(), DisplayImage.class);
// aldıgımız imagi burda yonlendirdiğimiz sınıfa iletiyoruz
ByteArrayOutputStream _bs = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, _bs);
intentBitMap.putExtra("byteArray", _bs.toByteArray());
startActivity(intentBitMap);
} else if (requestCode == REQUEST_CODE_VIDEO) {
Uri videoUrl = data.getData();
Intent intenToDisplayVideo = new Intent(getActivity(), DisplayVideo.class);
intenToDisplayVideo.putExtra("videoUri", videoUrl.toString());
startActivity(intenToDisplayVideo);
}
}
} }
1. And I play my video here
public class DisplayVideo extends Activity
{
private static final int REQUEST_CODE_VIDEO = 100;
VideoView videoView;
Button btn_cancel;
Button btn_send_cahallenge;
Button btn_image_play;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_video_activity);
videoView = (VideoView) findViewById(R.id.videoview_display_video_actvity);
btn_cancel = (Button) findViewById(R.id.btn_display_image_cancel);
btn_send_cahallenge = (Button) findViewById(R.id.btn_display_image_send_cahallenge);
btn_image_play = (Button) findViewById(R.id.btn_display_image_play);
// CameraActionFragmentten gelen uri
Bundle extras = getIntent().getExtras();
Uri myUri = Uri.parse(extras.getString("videoUri"));
videoView.setVideoURI(myUri);
btn_image_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
videoView.start();
}
});
btn_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences shp = getSharedPreferences("pref", MODE_PRIVATE);
SharedPreferences.Editor editor = shp.edit();
editor.putInt("frag_no", 2);
editor.commit();
startActivity(new Intent(getApplicationContext(), HomeActivity.class));
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_VIDEO && resultCode == RESULT_OK) {
Uri videoUrl = data.getData();
videoView.setVideoURI(videoUrl);
//videoView.setMediaController(new MediaController(getApplicationContext()));
//videoView.requestFocus();
}
}
}
3. Cant find some usefull guide about AppLovin SDK key. Lately I
defined facebook sdk key and everything was good and after camera
actions ı have this problem
Error is
E/AppLovinSdk: Unable to find AppLovin SDK key. Please add meta-data android:name="applovin.sdk.key" android:value="YOUR_SDK_KEY_HERE" into AndroidManifest.xml.
07-29 16:24:26.390 12911-12911/? E/AppLovinSdk: Called with an invalid SDK key from: java.lang.Throwable:
at com.applovin.impl.sdk.AppLovinSdkImpl.a(Unknown Source)
at com.applovin.sdk.AppLovinSdk.b(Unknown Source)
at com.applovin.sdk.AppLovinSdk.c(Unknown Source)
at com.applovin.sdk.AppLovinSdk.b(Unknown Source)
at com.qihoo.security.SecurityApplication.onCreate(360Security:263)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1014)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4806)
at android.app.ActivityThread.access$1600(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1452)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:234)
at android.app.ActivityThread.main(ActivityThread.java:5526)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
you have an invalid SDK key you need to setup AppLovin correctly
please try to add:
<meta-data android:name="applovin.sdk.key"
android:value="YOUR_SDK_KEY_HERE"/>
to your AndroidManifest file inside application tag.
Please check below link to find AppLovin SDK Key
Click Here To open AppLovin's Key Window

Resources