Show interstitialAd after 30 seconds Audience Network Facebook - android-studio

I want to use Facebook Audience Network for my Android app, I have integrated interstitialAd in-app and it works fine but it appears as Activity launch. I want to show ad after 30 seconds. this is my code
interstitialAd = new InterstitialAd(this, "1555910157949688_1556058954601475");
interstitialAd.setAdListener(new InterstitialAdListener() {
#Override
public void onAdLoaded(Ad ad) {
// Interstitial ad is loaded and ready to be displayed
Log.d(TAG, "Interstitial ad is loaded and ready to be displayed!");
// Show the ad
interstitialAd.show();
}
});
interstitialAd.loadAd();
and I have tried this to schedule my ad but it did not work.
private void showAdWithDelay() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// Check if interstitialAd has been loaded successfully
if(interstitialAd == null || !interstitialAd.isAdLoaded()) {
return;
}
// Check if the ad is already expired or invalidated, and do not show ad if that is the case. You will not get paid to show an invalidated ad.
if(interstitialAd.isAdInvalidated()) {
return;
}
// Show the ad
interstitialAd.show();
}
}, 3000);
}

I prefer to do this:
Handler handler = new Handler();
interstitialAd = new InterstitialAd(this, "XXX");
interstitialAd.setAdListener(new InterstitialAdListener() {
#Override
public void onAdLoaded(Ad ad) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
interstitialAd.show();
}
}, YOUR_TIME);
}
});
interstitialAd.loadAd();
And if you want to be more precise, do it:
final long lastTime = System.currentTimeMillis();
Handler handler = new Handler();
interstitialAd = new InterstitialAd(this, "XXX");
interstitialAd.setAdListener(new InterstitialAdListener() {
#Override
public void onAdLoaded(Ad ad) {
long now = System.currentTimeMillis();
long timeWait;
if (now - lastTime >= YOUR_TIME){
timeWait = 0;
}else {
timeWait = YOUR_TIME-(now-lastTime);
}
handler.postDelayed(new Runnable() {
#Override
public void run() {
interstitialAd.show();
}
}, timeWait);
}
});
interstitialAd.loadAd();

I think your implementation is breaking AdMob policies and could get you some trouble.
Check this page for help on right/wrong Interstitial implementations (Specially the "Interstitials that unexpectedly launch" point): https://support.google.com/admob/answer/6201362?hl=en&ref_topic=2936214
To comply with AdMob policies I suggest you only show Interstitials in activity/app natural transitions, different implementations could lead you to get banned from Admob.
To do so, you could change your code to first just load the Ad and keep track of its loaded status like this:
boolean isAdLoaded = false;
interstitialAd = new InterstitialAd(this, "1555910157949688_1556058954601475");
interstitialAd.setAdListener(new InterstitialAdListener()
{
#Override
public void onAdLoaded(Ad ad)
{
// Interstitial ad is loaded and ready to be displayed
Log.d(TAG, "Interstitial ad is loaded and ready to be displayed!");
// The ad has been loaded
isAdLoaded = true;
}
});
interstitialAd.loadAd();
And then show it in a natural transition of the app, for example when the user taps a button to go to a different activity:
shareButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Show interstitial if it is loaded
if(isAdLoaded)
interstitialAd.show();
//Open Activity
startActivity(new Intent(this,OtherActivity.class));
}
});

Related

Toggle TextToSpeech on and off using a togglebutton?

So i have an app connected to firebase. The app retrieves data(a string) from firebase into a text view and then the TextToSpeech feature reads the text out(not from the textView but it itself retrieves the same data from firebase real-time database). I have used onDataChange() meathod so the texttospeech feature reads the text out as soon as any change in the data occurs on firebase, and not on the click of any button. Now i want to place a toggle button in my app and use it to either turn the tts feature on or off but i cant get it to work. When the toggle button is off, i want the texttospeech feature to stop and when the button state is on, i want the texttospeech feature to turn back on.This is what ive tried:
mtts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR){
mtts.setLanguage(Locale.US); }else{
Toast.makeText(MainActivity.this, "Couldnt initialize speech function!", Toast.LENGTH_SHORT).show();
}
}
}); mIvToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
reff = FirebaseDatabase.getInstance().getReference().child("Match").child("Screen1");
reff.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String tts= dataSnapshot.getValue().toString();
mtts.speak(tts, TextToSpeech.QUEUE_FLUSH, null);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}else{
mtts.stop();
mtts.shutdown();
}
}
});
TIA !
When you attach a valueEventListener the listener will trigger as long as there is change in the data, even though you checked the toggle to off. So the thing that you should do is to remove the listener when you are done:
Directly under this:
mtts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR){
mtts.setLanguage(Locale.US);
}else{
Toast.makeText(MainActivity.this, "Couldnt initialize speech function!", Toast.LENGTH_SHORT).show();
}
}
});
Add these:
//the reference
reff=FirebaseDatabase.getInstance().getReference().child("Match").child("Screen1");
//make a listener
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String tts= dataSnapshot.getValue().toString();
mtts.speak(tts, TextToSpeech.QUEUE_FLUSH, null);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
}
};
//toggle
mIvToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
//add listener
reff.addValueEventListener(listener);
}else{
//remove listener
reff.removeEventListener(listener);
mtts.stop();
mtts.shutdown();
}
}
});

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.

Am I doing something wrong when adding an ad unit on Admob

Hello I am a new developer and I have created my first app on Android Studios.
I used test ads made by Admob to test if my ads worked and they did. When I finally published my app with MY ad unit code for some reason it didn't work. I then checked online and found that it may take some time before they activate, so I waited and waited, until 3 days past and still it didn't work.
Here are the steps I took:
Follow the tutorial made by Admob to implement code for rewarded ads
Add network permissions
Linked my published app to Admob
Made an ad unit on Admob by clicking "ADD AD UNIT"
I was wondering whether or not I missed a step but if I did why would the test ads work but not the real ones.
I would have liked to contact Admob directly but they don't seem to have any customer service email. YOU ARE MY LAST HOPE PLEASE HELP. thank you
Code: MainActivity Class
public class MainActivity extends Activity implements RewardedVideoAdListener {
public static RewardedVideoAd mAd;
public static RewardedVideoAd mAd2;
public static MediaPlayer click;
public static MediaPlayer unlock;
public static MediaPlayer thud;
public static InterstitialAd mInterstitialAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(getWindow().FEATURE_NO_TITLE);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Constants.SCREEN_WIDTH = dm.widthPixels;
Constants.SCREEN_HEIGHT = dm.heightPixels;
setContentView(new GamePanel(this));
mAd = MobileAds.getRewardedVideoAdInstance(this);
mAd.setRewardedVideoAdListener(this);
mAd2 = MobileAds.getRewardedVideoAdInstance(this);
mAd2.setRewardedVideoAdListener(this);
loadAd();
click = MediaPlayer.create(getApplicationContext(), R.raw.click_sound);
unlock = MediaPlayer.create(getApplicationContext(), R.raw.unlock_sound);
thud = MediaPlayer.create(getApplicationContext(), R.raw.thud_sound);
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
}
private void click() {
click.start();
}
private void unlock() {
unlock.start();
}
private void thud() {
thud.start();
}
private void loadAd() {
if (!mAd.isLoaded()) {
mAd.loadAd("ca-app-pub-3940256099942544/5224354917", new AdRequest.Builder().build());
}
if (!mAd2.isLoaded()) {
mAd2.loadAd("ca-app-pub-3940256099942544/5224354917", new AdRequest.Builder().build());
}
}
// Required to reward the user.
#Override
public void onRewarded(RewardItem reward) {
if (GamePanel.Ad1 == 1) {
Toast.makeText(this, "Congrats 30 Survival Points Added!", Toast.LENGTH_SHORT).show();
}
if (GamePanel.Ad2 == 1) {
Toast.makeText(this, "Congrats 100 Survival Points Added!", Toast.LENGTH_SHORT).show();
}
}
// The following listener methods are optional.
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdClosed() {
if (GamePanel.Ad1 == 1) {
GamePanel.HighCoin = GamePanel.HighCoin + 30;
GamePanel.Ad1 = 0;
Toast.makeText(this, "Congrats 30 Survival Points Added!", Toast.LENGTH_SHORT).show();
}
if (GamePanel.Ad2 == 1) {
GamePanel.HighCoin = GamePanel.HighCoin + 100;
Toast.makeText(this, "Congrats 100 Survival Points Added!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onRewardedVideoAdFailedToLoad(int errorCode) {
}
#Override
public void onRewardedVideoAdLoaded() {
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
}
And to load the code i used:
MainActivity.mInterstitialAd.show();
if (MainActivity.mAd.isLoaded())
MainActivity.mAd.show();
The ad unit code shown above is the test ad code given by Admob, which does work but I'm having trouble with the codes I make on Admob myself.
Thanks for the help, But i figured it out.
i forgot to put in my billing info on admob.

Unexplained delay between ad onAdClosed and finish

After clicking back button, dialog is opened asking if user want to save his work before returning to menu activity (finishing current activity).
If there is ad loaded, it will show and the activity is finished on onAdClosed.
But there is unexplained delay between closing ad and returning to the menu. If the ad is displayed for some time, the delay disappear. When the ad is not loaded so it will not be shown, finishing is smooth too.
mInterstitialBack.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
finish();
}
});
builderSingle.setNegativeButton(getString(R.string.noSave),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (mInterstitialBack.isLoaded()) {
mInterstitialBack.show();
} else {
finish();
}
}
});

Why my MediaRouteButton not available to find any cast devices?

following are my codes in main activity
public class MainActivity extends ActionBarActivity{
private MediaRouteButton mMediaRouteButton;
private MediaRouteSelector mMediaRouteSelector;
private MediaRouter mMediaRouter;
private CastDevice mSelectedDevice;
private MyMediaRouterCallback mMediaRouterCallback;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(this.checkGooglePlaySevices(this))
Log.v("cc5zhenhua","googleplayservice okay");
else
{
Log.v("cc5zhenhua","googleplayservice not ok");
//GooglePlayServicesUtil.getErrorDialog(0, this, 0).show();
}
//initialize media cast objects
mMediaRouter=MediaRouter.getInstance(getApplicationContext());
mMediaRouteSelector=new MediaRouteSelector.Builder()
.addControlCategory(CastMediaControlIntent.CATEGORY_CAST).build();
mMediaRouterCallback= new MyMediaRouterCallback();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback);
}
public void onStart() {
super.onStart();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback
);
MediaRouter.RouteInfo route = mMediaRouter.updateSelectedRoute(mMediaRouteSelector);
// do something with the route...
}
#Override
protected void onResume()
{
super.onResume();
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
super.onCreateOptionsMenu(menu);
//mMediaRouteButton.setRouteSelector(mMediaRouteSelector);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main, menu);
MenuItem mediaRouteItem = menu.findItem( R.id.action_mediaroute01 );
MediaRouteActionProvider mediaRouteActionProvider =
(MediaRouteActionProvider)MenuItemCompat.getActionProvider(
mediaRouteItem);
mediaRouteActionProvider.setRouteSelector(mMediaRouteSelector);
mMediaRouteButton = (MediaRouteButton) mediaRouteItem.getActionView();
return true;}
public boolean checkGooglePlaySevices(final Activity activity) {
final int googlePlayServicesCheck = GooglePlayServicesUtil.isGooglePlayServicesAvailable(
activity);
switch (googlePlayServicesCheck) {
case ConnectionResult.SUCCESS:
return true;
default:
Log.v("cc5zhenhua","test"); }
return false;
}
private class MyMediaRouterCallback extends MediaRouter.Callback
{
#Override
public void onRouteSelected(MediaRouter router, RouteInfo info) {
mSelectedDevice = CastDevice.getFromBundle(info.getExtras());
String routeId = info.getId();
Log.v("cc5zhenhua", "MainActivity.onRouteSelected");
}
#Override
public void onRouteUnselected(MediaRouter router, RouteInfo info) {
//teardown();
mSelectedDevice = null;
}
}
}
There's no build error. However when I run the main activity, the media route button can not be clicked at all. Please advise any where I missed? Thank you!
My chromecast is whitelisted registed with an APPID before the new SDK published.
I can't use that appID for the control category either, it throws not valida appID exception.
My cast device is also available for chromecast extension in my computer.
You need to start the scan by adding callbacks:
mMediaRouter.addCallback(mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
If you are already doing that and forgot to mention that in your post, then you need to register your app and device on the Developer Console. Your issue is, then, most likely due to the whitelisting of your device; try connecting to your device from a chrome browser at http://<chromecast-ip>:9222, if you can't, then your device is not whitelisted; follow the steps in this post to trouble shoot that
Finally get the issue point. Just because that my last app with old googlecast sdk works on the AVD, so I focused on my codes and new SDK setting.However, when I deploy the app on real phone ,the media route can be found. Thanks to Ali for his kindness and helping.

Resources