I use Native Templates: https://developers.google.com/admob/android/native/templates Everything works, but if I use app:gnt_template_type="#layout/gnt_small_template_view" Somewhere once in thirty an error pops up like on screenshots:
Although there is no MediaView in gnt_small_template_view at all. The questions are as follows:
Is it possible to leave it as it is, since this is a Google module or Google will swear?
Since this is a Google module, can I change the appearance of this View? It means again, will Google swear?
Is it generally possible to make a View for NativeAds without a MediaView? If possible, I would just make an analogue as in the module (Native Templates) but from the Native Advanced example: https://developers.google.com/admob/android/native/advanced
What else I don’t like, the module, although downloaded from official site lags behind the library version of the current com.google.android.gms:play-services-ads:21.2.0 and requires the com.google.firebase:firebase-crashlytics-buildtools:2.9.2 module to be added to Gradle, otherwise it will not compile, which also leads to the question, will Google have problems with this later?
Code:
<com.google.android.ads.nativetemplates.TemplateView
android:id="#+id/my_template"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="32dp"
app:gnt_template_type="#layout/gnt_small_template_view" />
And in fragment in onCreateView:
private fun initNativeTemplate(view: ConstraintLayout) {
val template = view.findViewById<TemplateView>(R.id.my_template)
val adLoader: AdLoader = AdLoader.Builder(requireActivity(), "/6499/example/native").withAdListener(object :
AdListener() {
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
super.onAdFailedToLoad()
Log.i("NativeAds", "onAdFailedToLoad")
}
override fun onAdLoaded() {
super.onAdLoaded()
Log.i("NativeAds", "onAdLoaded")
}
}).forNativeAd { nativeAd ->
val styles = NativeTemplateStyle.Builder().build()
template.setStyles(styles)
template.setNativeAd(nativeAd)
}.build()
adLoader.loadAd(AdRequest.Builder().build())
}
Related
I am working on SDK for android and later for ios. And this SDK should be added to the native android project as AAR and probably for ios as a pod.
I was following RN article integration with existing apps
and it is working completely fine but my problem is I don't want to run the whole activity up to the native project... I just need to open modal dialog with RN components and some logic
The third part of application write in Kotlin on android implementing my SDK
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val MySDK = MySdk(this, this, 'some other data')
...
btnOpenWalleePaymentModalReactNative.setOnClickListener {
MySDK.launchDialog()
}
and now my SDK opening RN activity (inside MySDK):
class MySDK(private val context: Context, val activity: Activity) {
fun launchDialog() {
val intent = Intent(context, MyReactActivity::class.java)
context.startActivity(intent)
}
and this part open standard activity where all RN exist but i don't want to have an activity i want to have dialogue
so I created a class with dialogue what I want to use for that (BottomSheetDialogFragment)
class TestDialog(context: Context, var activity: Activity): BottomSheetDialogFragment() {
private lateinit var reactRootView: ReactRootView
private lateinit var reactInstanceManager: ReactInstanceManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SoLoader.init(context, false)
reactRootView = ReactRootView(context)
val packages: List<ReactPackage> = PackageList(activity.application).packages
reactInstanceManager = ReactInstanceManager.builder()
.setApplication(activity.application)
.setCurrentActivity(activity)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackages(packages)
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build()
reactRootView?.startReactApplication(reactInstanceManager, "PaymentSDK", null)
activity.setContentView(reactRootView)
}
and when I init this class and open dialogue with react native it will change the activity from third party library and put there my react activity and blurred overlay from dialogue...
TestDialog(context, activity ).show(activity.supportFragmentManager, "tag")
like on the picture
any idea how to squeeze RN view/UI into fragment or dialogue view or any other idea how to do it? Or an article with something similar like writing an RN module for native android?
I've developed a RN native module as a bridge for a native SDK once. I've followed this old tutorial page https://archive.reactnative.dev/docs/native-modules-android.
From what I've understood from your situation, you will have a RN application trying to call a showDialog function from this native module, passing the RN activity to make sure it is opened from it, right? The snippets that you've posted confused me a little bit but I'll try to help with what I remember.
You'll have to have a JS/RN project for this native module, you can follow this https://reactnative.dev/docs/native-modules-setup and the following articles from the official docs to create it.
First, in the Android part of this created project you will need to have the .aar downloaded through gradle or locally in the project.
The Android part will have two important files: MySdkPackage and MySdkModule
MySdkPackage will just list your module for React Native to see it, something like:
package com.reactnativemysdk
import java.util.Arrays
import java.util.Collections
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import com.facebook.react.bridge.JavaScriptModule
class MySdkPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return Arrays.asList<NativeModule>(MySdkModule(reactContext))
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList<ViewManager<*, *>>()
}
}
and MySdkModule will indeed make the connection with your Android native .aar implementation, having a reference from the React Native context and activity. Something like:
package com.reactnativemysdk
class MySdkModule(private var reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
#ReactMethod
fun showMyDialog(promise: Promise) {
if (reactContext.hasCurrentActivity()) {
reactContext.currentActivity?.runOnUiThread {
MySdk.getInstance().showDialog(reactContext.currentActivity) //this activity and context are the references that
// you need to properly show the dialog as it was native
}
} else {
promise.reject(ERROR_STRING, "No activity found.")
}
}
}
this method annotated with #ReactMethod will need a JS counterpart, where things will be tied together and you will be able to call this JS 'bridge' code from your RN app JS code
the JS bridge will be something like this (the example I did was in TypeScript so I'm sorry):
import { Platform, NativeModules } from 'react-native';
type MySdkInterface = {
showMyDialog(): Promise<void>;
const { MySdk } = NativeModules;
export default MySdk as MySdkInterface;
Creating this native module and organizing things like this you will have a better integration between and RN and the native parts and you will be able to properly show the dialog and any rendering/layout issues would be solvable in your original Android SDK code
So you will have something like
RN App JS showDialog <-> RN Native Module JS showDialog <-> RN Native Module Android (or iOS) native code showDialog <-> MySdk (the .aar one) showDialog implementation
I'm pretty sure these links and references will be able to help you as well but I hope I was able to at least clarify the way for you
I'd recommend following the first link, the https://archive.reactnative.dev/docs/native-modules-android, and following and understanding this ToastModule structure, I think the most recent one doesn't help that much.
In the app is a Checkout.com 3DS screen and when I use Layout Inspector (Android Studio), I only see the web view but it has no subtrees. Do I need to use separate software to inspect elements in chrome web view?
I believe I have the correct code to interact with the elements but I'm just guessing the attributes at the moment and not having much luck. Using text/placeholder hasn't worked so far.
private val webView = withId(R.id.verifyByThreeDsWebView)
override fun isDisplayed() {
support.waitForViewDisplayed(webView, 20000)
}
fun enterPassword(password: String = "Checkout1!") {
onWebView(webView).forceJavascriptEnabled()
.withElement(findElement(Locator.XPATH,"//*[#placeholder='Hint: Checkout1!']"))
.perform(webKeys(password))
}
fun clickSubmit() {
onWebView(webView)
.withElement(findElement(Locator.XPATH,"\"//button[contains(text(),'Continue')]\""))
.perform(webClick())
}
The new API SplashScreen in Android 12 seems good but just like before the sample code in the documentation does not really help explaining the whole and proper implementation. There is also some cases where you might do some task during splash screen in our case this is to launch Firebase Auth so probably the best way is just to opt out on using this new featured API but according to lint warning it seems like it is mandatory and there is no way to opt out.
The application should not provide its own launch screen
Application-defined Launch Screen Starting in Android 12 (API 31+),
the application's Launch Screen is provided by the system and the
application should not create its own, otherwise the user will see two
splashscreen. Please check the SplashScreen class to check how the
Splash Screen can be controlled and customized.
How about the backward compatibility for older devices, how to handle it? Is there any codelab project to play and test with?
Can we opt out of SplashScreen?
It looks like we can't opt out as Android Team is trying to unify the app loading experience: https://9to5google.com/2021/04/21/android-12-dp3-all-apps-now-show-the-same-splash-screen-while-loading-gallery/
How to use it?
If you don't do anything then it will use windowBackground of the theme & your launcher icon & dismissed as soon as your app draws its first frame.
There are bunch of properties that you can modify like background, icon etc: https://developer.android.com/about/versions/12/features/splash-screen#set-theme
What if I want splash to stay longer? Like fetching a local DataBase.
You can use ViewTreeObserver.OnPreDrawListener & make a blocking call from your viewmodel return if it's ready to go ahead.
Activity:
// My Launcher Activity
class MainActivity : AppCompatActivity() {
private val viewModel : JustDelayViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val content: View = findViewById(android.R.id.content)
content.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
// Check if the initial data is ready.
return if (viewModel.getIsReady()) {
// The content is ready; start drawing.
content.viewTreeObserver.removeOnPreDrawListener(this)
true
} else {
// The content is not ready; suspend.
false
}
}
}
)
}
}
ViewModel:
class JustDelayViewModel : ViewModel() {
fun getIsReady(): Boolean {
val result = viewModelScope.runCatching {
runBlocking {
//do some blocking call check for Firebase result or something
delay(5000)
}
true //return the result
}
return result.isSuccess
}
}
You can read more about this: https://developer.android.com/about/versions/12/features/splash-screen#suspend-drawing
To complement Mayur's answer for older device support.
The new windowSplashScreen* attributes need to be added in the res/values-v31/style.xml file.
Then for the legacy splashscreen it depend of the current implementation of the app.
If the application simply uses a starting theme with a custom windowBackground there is nothing to do since the windowBackground isn't used for the new splash screen (only if it's a simple color).
If the application has some visible splash screen Activity, there will be a double splash screen on Android 12. To solve this, the application can migrate to the windowBackground solution.
If the application really need to keep its splash screen Activity, it can update the layout to match the system splash screen on Android 12 and/or create a smooth transition from the system splash screen to the app splash screen using the SplashScreen.setOnExitAnimationListener()
We can also use android's splash screen library - link
android {
compileSdk 31
...
}
dependencies {
...
implementation 'androidx.core:core-splashscreen:1.0.0-alpha02'
}
This will give splash screen options in style.xml, you just need to create 2 style.xmls 1 for android api 31 and above and one of below api 31
<style name="Theme.CustomSplashScreenTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">#color/white</item>
<item name="windowSplashScreenAnimatedIcon">#drawable/logo</item>
<item name="windowSplashScreenAnimationDuration">300</item>
<item name="postSplashScreenTheme">#style/Theme.YourAppTheme</item>
</style>
Learn more about this library using this example
you can add this line:
<item name="android:windowIsTranslucent">true</item>
in your style.xml file before close style tag. it`s make your default android splash transparent!
I'm trying to integrate Zoom SDK meetings in an Android app. I've struggled for a while now with using the custom meeting ui and learning how to use Zoom's video view called MobileRTCVideoView. Here's the interface I would like to create:
What I've tried:
Studied Zoom's sample apps on Github.
Studied Zoom's documentation for customized meeting ui.
Asked on the developer forum.
Read related threads on the developer forum.
However, I still don't understand how to implement it, and would very much appreciate some explanation as to how to use MobileRTCVideoView, and achieving the meeting ui illustrated on the image. The meetings should only hold up to two users at a time.
I initialize the Zoom SDK with API Key and Secret, and use email login. I enable the custom meeting ui with:
zoomSDK!!.meetingSettingsHelper.isCustomizedMeetingUIEnabled=true
I start an instant meeting with:
val meetingService=zoomSDK!!.meetingService
val opts=InstantMeetingOptions()
opts.no_driving_mode = true
opts.no_invite = false
opts.no_meeting_end_message = false
opts.no_titlebar = false
opts.no_bottom_toolbar = false
opts.no_dial_in_via_phone = true
opts.no_dial_out_to_phone = true
opts.no_disconnect_audio = true
meetingService.startInstantMeeting(this,opts)
I've tried to follow the sample apps by creating another activity for the custom meetings, but apparently the class and the code is not complete:
class CustomMeetingActivity: FragmentActivity() {
private var zoomSDK:ZoomSDK?=null
private var inflater:LayoutInflater?=null
private var normal_view:View?=null
private var video_view:MobileRTCVideoView?=null
private var video_manager:MobileRTCVideoViewManager?=null
private var meeting_service:MeetingService?=null
private var in_meeting_service:InMeetingService?=null
private var share_view:MobileRTCShareView?=null
private var meeting_video_view:FrameLayout?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
zoomSDK=ZoomSDK.getInstance()
meeting_service = ZoomSDK.getInstance().meetingService
in_meeting_service=ZoomSDK.getInstance().inMeetingService
if(meeting_service==null || in_meeting_service==null){finish();return}
setContentView(R.layout.custom_meeting_layout)
inflater=layoutInflater;
normal_view = inflater!!.inflate(R.layout.meeting_content_normal,null)
meeting_video_view = findViewById<View>(R.id.meetingVideoView) as FrameLayout
share_view = findViewById<View>(R.id.sharingView) as MobileRTCShareView
video_view=normal_view!!.findViewById(R.id.videoView) as MobileRTCVideoView
}
}
Added the activity in the manifest:
<activity
android:name="com.mypackage.appname.CustomMeetingActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="#style/ZMTheme.SubWindow">
</activity>
Solid advice I can give is:
Override or reuse their existing Sample to get started. (Though their sample app looks like it was done in a rush)
Don't user their styles, override their styles and use them.
Scan/Study the MyMeetingActivity. Most of the heavy lifting is done in it already.
Check both of their samples. If you cannot figure out sharedView from MyMeetingActivity, then it looks like you haven't studied hard enough
I have worked a lot on this over the last few weeks. Customized UI is working well. I am looking to make the Gallery view. We have loads of features and functionality that we added and reused. Over all it was a bumpy ride, but still went smooth as I spent time on it.
I don't understand why this question is not yet answered. Unfortunately I am too busy to actually write code out for you, especially since I am not even developing in Kotlin. Sorry. Hope you figure it. If I implement the gallery view, then maybe I can come back and give you some pointers. Good Luck
YouTubePlayerSupportFragment has a minimal style. loader color is green. You need to change the color of the loader to another
current loader
I created a player
private var player: YouTubePlayer? = null
var fragment: YouTubePlayerSupportFragment = YouTubePlayerSupportFragment.newInstance()
and initialized it.
Where set the minimal style of the player
fragment.initialize(DEVELOPER_KEY, object : YouTubePlayer.OnInitializedListener {
override fun onInitializationSuccess(p0: YouTubePlayer.Provider?, p1: YouTubePlayer?, p2: Boolean) {
player = p1
player?.setPlayerStyle(YouTubePlayer.PlayerStyle.MINIMAL)
if (!p2) {
player?.cueVideo(getIdVideo(uri))
}
}
override fun onInitializationFailure(p0: YouTubePlayer.Provider?, p1: YouTubeInitializationResult?) {
}
})
As a result, the video is loaded with a green progressBar.
Styles accent color is red
I looked in the YouTube documentation and did not find anything there that could help me.
All visual modification you could do with help of `YouTubePlayer.PlayerStyle But it is not so flexible as you want I guess and you could just choose some default styles like here
https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/YouTubePlayer.PlayerStyle
One more variant which is VERY flexible to play videos is ExoPlayer which i prefer better and here is an example. CHECK THIS LINK BELOW. Even Udacity and google forums recommend it
https://medium.com/fungjai/playing-video-by-exoplayer-b97903be0b33
Easy to customize it