How to add unityplayer as subview in android layout? - android

Iam trying to add unityview as subview in android layout.
I create relative layout in android xml file and added unityview to relativelayout.
But the unityview is appearing as small image at left bottom of relative layout.
The black portion is my relativelayout but unity view not occupying enter relative layout.
The code is as follows:
public class MainActivity extends UnityPlayerActivity {
public static Context mContext;
private Handler handler=new Handler();
private UnityPlayer m_UnityPlayer;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
mContext = this;
m_UnityPlayer = new UnityPlayer(this);
int glesMode = m_UnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
m_UnityPlayer.init(glesMode, trueColor8888);
setContentView(R.layout.activity_main);
//This is my relative layout
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relativelayout2);
//Relativelayout width is 750dp and height is 640dp.
LayoutParams lp = new LayoutParams (750, 640);
//Iam adding unityview to layout here
layout.addView(m_UnityPlayer.getView(), 0, lp);
}
}

Finally I got the solution.
MainActivity should be extend as Activity, not UnityPlayerActivity.
Add these two lines to activity in android manifest
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
The working code is:
public class MainActivity extends Activity implements OnTouchListener {
public static Context mContext;
private Handler handler=new Handler();
protected UnityPlayer mUnityPlayer;
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mContext = this;
getWindow().takeSurface(null);
setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
getWindow().setFormat(PixelFormat.RGB_565);
mUnityPlayer = new UnityPlayer(this);
if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
mUnityPlayer.init(glesMode, trueColor8888);
View playerView = mUnityPlayer.getView();
setContentView(R.layout.activity_main);
FrameLayout layout = (FrameLayout) findViewById(R.id.frameLayout2);
LayoutParams lp = new LayoutParams (750, 630);
layout.addView(playerView, 0, lp);
}
protected void onDestroy ()
{
mUnityPlayer.quit();
super.onDestroy();
}
// onPause()/onResume() must be sent to UnityPlayer to enable pause and resource recreation on resume.
protected void onPause()
{
super.onPause();
mUnityPlayer.pause();
}
protected void onResume()
{
super.onResume();
mUnityPlayer.resume();
}
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
}
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
}
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
return super.dispatchKeyEvent(event);
}
}
The result:

Related

Android TextView.getLayout() returns null

I get null in Layout object which I try to obtain from a Textview each time after configuration change.
The method containing the code is called from onResume().
I suspect I need to do some additional setup for it.
I have studied similar questions, but there isn't a clear answer to it.
What is the event which signals that Layout is ready after configuration changes?
Is there some documentation for it?
EDITED:
public class BookDisplayAct extends Activity implements View.OnClickListener {
...
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.textViewMain);
textView.setPadding(15, 15, 15, 15);
...
}
#Override
protected void onResume() {
...
renderBookView();
}
public void renderBookView() {
...
justifyText(spannable, textView);
...
}
private Spannable justifyText(Spannable spannable, TextView textView) {
Layout layout = textView.getLayout();
int line_count = layout.getLineCount();
...
}
I get the NullPointer exception with the last line.
Just change your justifyText method as below
private Spannable justifyText(Spannable spannable, TextView textView) {
ViewTreeObserver observer= textView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Layout layout = textView.getLayout();
int line_count = layout.getLineCount();
}
});
...
}

onClickListener set on Activity

I have a class SomeView that extends View and that is displayed in a class Controls that extends linear layout.
The linear layout is instantiated onCreate of an activity.
I would like to call a method in the activity every time I click on this view SomeView.
I have tried to set an onClickListener in the activity like this
public class MainActivity extends AppCompatActivity implements
SomeView.OnClickListener {
private Controls menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
menu = new Controls(this);
menu.getSomeView().setOnClickListener(this);
setContentView(menu);
}
#Override
public void onClick(View view) {
System.out.println("Hello");
}
}
The controls class looks like this
public class Controls extends LinearLayout {
private SomeView aview;
public Controls(Context context) {
super(context);
this.setOrientation(LinearLayout.HORIZONTAL);
aview = new SomeView(context);
this.addView(aview, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
public SomeView getSomeView() {
return aview;
}
}
and the SomeView class looks like this (it just draws an oval)
public class SomeView extends View {
public SomeView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF aRect = new RectF();
aRect.left = getPaddingLeft();
aRect.top = getPaddingTop();
aRect.right = getWidth() - getPaddingRight();
aRect.bottom = getHeight() - getPaddingBottom();
Paint aPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
aPaint.setColor(Color.GREEN);
canvas.drawOval(aRect, aPaint);
}
}
But I am missing something because clicks are not calling the onClick method.
What else do I need to set up?
it seems like you did only mistake in your MainActivity class, where you forgot to call the super method. Try doing this, hope it will work, since it works from here in my mobile.
Main Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
menu = new Controls(this);
menu.getSomeView().setOnClickListener(this);
setContentView(menu);
}
And in your callback method, instead using System.out.println(), use Log.d() as below:
#Override
public void onClick(View view) {
Log.d(TAG, "Hello");
}
and it is working from here, look at the image below as well.

Implementing Admob banner when setContentView() is used for the Surfaceview

I am struggling to implement an admob banner into my app because the setContentView() method is used for the surfaceView called gameView so creating the adView in xml cannot be applied to this framework as setContentView is already being used. And I don't know how to do this programmatically. Does anyone have a solution to this?
My main Activity:
public class GameMainActivity extends BaseGameActivity {
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
prefs = getPreferences(Activity.MODE_PRIVATE); // New line!
highScore = retrieveHighScore();
highScoreUnits = retrieveHighScoreUnits();
highScoreTens = retrieveHighScoreTens();
highScoreHundreds = retrieveHighScoreHundreds();
muteButton = retrieveMuteButton();
assets = getAssets();
sGame = new GameView(this, GAME_WIDTH, GAME_HEIGHT);
setContentView(sGame);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and my custom surfaceView code
public class GameView extends SurfaceView implements Runnable {
private Bitmap gameImage;
private Rect gameImageSrc;
private Rect gameImageDst;
private Canvas gameCanvas;
private Painter graphics;
private Thread gameThread;
private volatile boolean running = false;
private volatile State currentState;
private InputHandler inputHandler;
public GameView(Context context, int gameWidth, int gameHeight) {
super(context);
gameImage = Bitmap.createBitmap(gameWidth, gameHeight,
Bitmap.Config.RGB_565);
gameImageSrc = new Rect(0, 0, gameImage.getWidth(),
gameImage.getHeight());
gameImageDst = new Rect();
gameCanvas = new Canvas(gameImage);
graphics = new Painter(gameCanvas);
SurfaceHolder holder = getHolder();
holder.addCallback(new Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
initInput();
if (currentState == null) {
setCurrentState(new LoadState());
}
initGame();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
pauseGame();
}
});
}
Use a RelativeLayout or a FrameLayout as your parent layout, then just define the layout parameters for the adView to be positioned (for example at the bottom center of the screen like this):
public class GameMainActivity extends BaseGameActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
prefs = getPreferences(Activity.MODE_PRIVATE); // New line!
highScore = retrieveHighScore();
highScoreUnits = retrieveHighScoreUnits();
highScoreTens = retrieveHighScoreTens();
highScoreHundreds = retrieveHighScoreHundreds();
muteButton = retrieveMuteButton();
assets = getAssets();
// Create an ad.
AdView adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(AD_UNIT_ID);
// set background color of adview to force it to show
adView.setBackgroundColor(Color.TRANSPARENT);
// Add the AdView to the view hierarchy. The view will have no size
// until the ad is loaded.
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
// Create an ad request.
AdRequest adRequest = new AdRequest.Builder().build();
// Start loading the ad in the background.
adView.loadAd(adRequest);
// Request full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Create and set your game's view
sGame = new GameView(this, GAME_WIDTH, GAME_HEIGHT);
RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layout.addView(sGame);
layout.addView(adView, adParams);
setContentView(layout);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}

LibGDX ad control tutorial producing null pointer

I have been following this tutorial: https://github.com/libgdx/libgdx/wiki/Admob-in-libgdx
I'm sure i have implemented everything correctly and am still getting a null pointer for the handler. Is there something wrong with the code in the tutorial?
Here is my Android Launcher Code:
public class AndroidLauncher extends AndroidApplication implements IActivityRequestHandler{
protected AdView adView;
private final int SHOW_ADS = 1;
private final int HIDE_ADS = 0;
protected Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case SHOW_ADS:
{
adView.setVisibility(View.VISIBLE);
break;
}
case HIDE_ADS:
{
adView.setVisibility(View.GONE);
break;
}
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the layout
RelativeLayout layout = new RelativeLayout(this);
// Do the stuff that initialize() would do for you
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
// Create the libgdx View
View gameView = initializeForView(new PBGame(this));
// Create and setup the AdMob view
AdView adView = new AdView(this);
adView.setAdUnitId("Secret Key");
adView.setAdSize(AdSize.BANNER);
adView.loadAd(new AdRequest.Builder()
.addTestDevice("Test Device")
.build());
// Add the libgdx view
layout.addView(gameView);
// Add the AdMob view
RelativeLayout.LayoutParams adParams =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layout.addView(adView, adParams);
// Hook it all up
setContentView(layout);
}
#Override
public void showAds(boolean show) {
handler.sendEmptyMessage(show ? SHOW_ADS : HIDE_ADS);
}
}
My Game Class:
public static final int VIRTUAL_WIDTH = 800;
public static final int VIRTUAL_HEIGHT = 480;
public static final float ASPECT_RATIO =
(float)VIRTUAL_WIDTH/(float)VIRTUAL_HEIGHT;
public static final int zeroMakerX = 400, zeroMakerY = 240;
public static Camera camera;
public static Rectangle viewport;
private IActivityRequestHandler myRequestHandler;
public PBGame(IActivityRequestHandler handler) {
myRequestHandler = handler;
}
#Override
public void create() {
AssetHandler.load();
super.setScreen(new TitleScreen(this));
AssetHandler.music.play();
AssetHandler.music.setLooping(true);
}
#Override
public void dispose() {
super.dispose();
}
}
Finally the ReqestHandler:
public interface IActivityRequestHandler {
public void showAds(boolean show);
}
The problem is as follows:
Your AdView object is defined locally inside the onCreate() function of the AndroidLauncher class. You then attempt to access it outside of onCreate() in the Handler object. The AdView object is out of scope. You should declare the AdView in your AndroidLauncher class outside of onCreate():
AdView adView;
Then in onCreate() you can instantiate it as you did:
// Create and setup the AdMob view
adView = new AdView(this);
adView.setAdUnitId("Secret Key");
adView.setAdSize(AdSize.BANNER);
adView.loadAd(new AdRequest.Builder()
.addTestDevice("Test Device")
.build());

Inheritance issues with Android annotations and OnClickListener

This is the inheritance that I'm using
GenericActivity -> GraphGenericActivity -> NormalActivity
I have an options menu with contains a help button which show a help view over the current one and this works fine however it's the close button that doesn't work, with #Click I doesn't work on any of the views and if I register a onClickListener the old fashionned way It only workds on Activities that extend directly from "GenericActivity
GENERIC ACTIVITY
#EActivity
#OptionsMenu(R.menu.menu_generic)
public abstract class GenericActivity extends Activity{
public static final String TAG = "GenericActivity";
protected Context context;
protected LayoutInflater vi;
protected View helpView;
#ViewById
protected RelativeLayout rootLayout;
#ViewById
protected Button closeHelpButton;
protected abstract int getHelpLayoutInt();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#AfterViews
protected void afterViews() {
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
helpView = vi.inflate(this.getHelpLayoutInt(), null);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
helpView.setVisibility(View.GONE);
if (helpView != null) {
rootLayout.addView(helpView, layoutParams);
}
final Button button = (Button) findViewById(R.id.closeHelpButton);
button.setOnClickListener(new View.OnClickListener() {
#Override
#Trace
public void onClick(View v) {
Toast.makeText(context, "close help", Toast.LENGTH_SHORT).show();
if (helpView != null) {
helpView.setVisibility(View.GONE);
}
}
});
}
#OptionsItem
protected boolean menuHelp() {
if (helpView != null) {
if (helpView.getVisibility() == View.GONE) {
helpView.setVisibility(View.VISIBLE);
} else {
helpView.setVisibility(View.GONE);
}
}
return true;
}
}
CHILD ACTIVITY
#EActivity(R.layout.activity_start_screen)
public class StartScreen extends GenericActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(false);
CALog.i("onCreateFinished");
}
#Trace
#Override
protected void onDestroy() {
domboxTouchServiceManager.unbindFromDomboxService();
super.onDestroy();
}
#Override
protected int getHelpLayoutInt() {
return R.layout.layout_start_screen_help;
}
}

Categories

Resources