How to: Use DisplayManager to get displays and set a bool - java

My understanding of Java is basically nonexistent .. I only really understand Dart.
However, I need to use DisplayManager and getDisplays() in order to set a boolean.
I need something like this (I know this isn't really java, it's just so someone can get an understanding):
DisplayManager displayManager = DisplayManager();
List<Display> displays = [];
bool hasDisplays = false;
void _getDisplays(){
displays = DisplayManager.getDisplays();
}
void _displayBool(){
if(displays.length > 1){
hasDisplays = true;
} else {
hasDisplays = false;
}
if someone could show me how the hell I'm supposed to do something like that, inside of this, it would be amazing
public class MainActivity extends FlutterActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

You need to get the DisplayManager with the context.getSystemService() function. Then you get the list of Displays (Display[]) from the displayManager.getDisplays() function. Then if you want to know if there are one or more displays in the list, set the statement to the boolean.
DisplayManager displayManager = (DisplayManager) getApplicationContext().getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = displayManager.getDisplays();
boolean hasDisplays = displays.length >= 1;

Well you can try this code:
class TestScreenCount {
public static void main(String[] args) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] allScreens = env.getScreenDevices();
System.out.println(Arrays.toString(allScreens));
}
}
This will output the connected displays, for my case (I have an external screen and a laptop screen):
[X11GraphicsDevice[screen=0], X11GraphicsDevice[screen=1]]

Related

View.onClickListener - how to get view properties

I m new here and I've got a question for which I haven't found answer yet.
I am trying to get some variable value from a clicked object using onClickListener.
This view is an object (actually its a ConstraintLayout) created previously with a boolean value.
Code (that is not the current code I've got but you get the idea hopefully):
public class layoutView extends ConstraintLayout {
boolean bool = false;
public layoutView (Context context) {
super(context);
}
...
}
I am adding this layoutView into my main layout and its working fine but I need to get this boolean value when i click the layout view.
layoutView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.setBackgroundColor(Color.GREEN); //this works fine
boolean check = v.bool //this wouldnt work
if (v.bool == true)... //this woulnt work
}
});
Is it possible at all. How to approach this?
Thanks in advance!
You can try layoutView.setTag()/getTag() instead of keeping your own variable bool.
Note that you may need to use a Boolean object instead of primitive type, for example:
layoutView.setTag(new Boolean(true));
// inside on click listener
if (v.getTag() == true) {
// do something
}

Presentation Mode Android

I'm trying to create an App to stream a video on my secondary display connected via HDMI on my device using Android's Presentation mode.
I ran a simple Layout on Secondary display and I was able to do that.. But when I launch my app It blocks my Activity on Primary screen and I can't do anything except killing the app.
I found this code somewhere on Internet. It is simple code and it throws "R.layout.presentation_with_media_router_content" on my secondary screen properly but I can't do anything on my primary screen at all until I kill this app from adb.
Both of my screen is connected through HDMI (HDMI 1 & HDMI 2). Any help on how to enable my Primary display while running presentation mode on secondary will help. Btw I'm using Android N for this development.
public class MainActivity extends AppCompatActivity {
ImageButton sendtoback;
private PresentationActivity presentationActivity;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init Presentation Class
DisplayManager displayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE);
Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if (presentationDisplays.length > 0) {
// If there is more than one suitable presentation display, then we could consider
// giving the user a choice. For this example, we simply choose the first display
// which is the one the system recommends as the preferred presentation display.
Display display = presentationDisplays[0];
PresentationActivity presentation = new PresentationActivity(this, display);
presentation.show();
this.presentationActivity = presentation;
}
}
public void changeText (String s) {
this.presentationActivity.setText(s);
}
public void SendOnBack(View view){
Log.i("VideoApp","StartVideoApp");
}
}
class PresentationActivity extends Presentation {
private TextView text;
private PresentationActivity presentation;
public PresentationActivity(Context outerContext, Display display) {
super(outerContext, display);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.presentation_with_media_router_content);
TextView text = (TextView) findViewById(R.id.textView1);
this.text = text;
text.setText("test");
}
public void setText(String s) {
this.text.setText(s);
}
}
Thanks, Satish
This is the code I use to start the Presentation on the secondary display. The method is called from onResume, and it works flawlessly.
#TargetApi(Build.VERSION_CODES.KITKAT)
private void doDisplay() {
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
Display[] displays = displayManager.getDisplays();
MediaRouter mediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
if (displays.length > 1) {
Display presentationDisplay = route.getPresentationDisplay();
if (presentationDisplay != null) {
presentation = new MyPresentation(MainActivity.this, presentationDisplay);
presentation.setAppListener(this);
presentation.show();
}
}
}
Did you try on a version of Android other than N? I have run my code on 4.4 and 6.0

Im missing some global variables

I've got 2 activities and a class that extends Application where I'm trying to store global variables with a kind of setter getter functions.
The main activity sets some views and a chart; then calls the second activity which should be setting values to be used afterwards on the previous chart.
Then pressing backbutton and returning to the previous activity onRestart is called and the chart is refreshed.
The problem is I lose my theorically global variables somewhere. Debugging i realized that the functions work perfectly fine while im adding values in the second activity but when I return to the first activity globalXCount returns '0' again. Why is that?
I think im missunderstanding some point regarding lifecycles.
I attach some fragments of the code.
First activity:
public class MainActivity extends Activity {
Global glObj = new Global();
CombinedChart mChart;
private int itemcount;
float displayed;
private final List<String> mMonthList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
mChart = (CombinedChart) findViewById(R.id.mchart);
populateHeaderList();
setChartSettings();
Intent intent = new Intent(MainActivity.this, QandA.class);
startActivity(intent);
}
#Override
protected void onRestart() {
super.onRestart();
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
populateHeaderList();
setChartSettings();
}
Second activity:
public class QandA extends Activity {
Global glObj = new Global();
ViewFlipper flipper;
private float lastX;
...
}else{
//TODO If all information if correctly filled
trainedmins = et1.getText().toString();
localLineValue = Integer.parseInt(trainedmins) * Integer.parseInt(statusQ1);
//Add values to lines
glObj.setLineXvalues(localLineValue);
// TODO Add new Bar value //
//Add 1 more value to count
glObj.addGlobalXCount();
}
...
Global class:
public class Global extends Application {
//TODO
public Integer globalXCount;
private List<Integer> lineXvalues = new ArrayList<>();
private List<Integer> barXvalues = new ArrayList<>();
//////
public Integer getGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
return this.globalXCount;
}else{
return this.globalXCount;
}
}
public void addGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
}else{
this.globalXCount = this.globalXCount + 1;
}
}
Thanks in advance.
First of all, register your custom Application context in AndroidManifest.xml within the <application>-tag.
<application
android:name="<your_package>.Global" ...>
Access the global application context within your activities like this:
Global glObj = (Global) getApplicationContext();
glObj.addGlobalXCount();
Do not create a new instance with new! Always retrieve the instance via getApplicationContext().
Furthermore, I would suggest you to initialize your class field glObj within the onCreate()-method of your Activities.

Android - Dynamic View Timing Issue?

I'm an Android newbie developer and having an issue with a tiny Android app I'm developing which I suspect is related to timing of dynamic view creation. It's a little scorekeeper app and it has dynamically generated player buttons and text fields, defined in a Player class. Here's an excerpt of how I'm doing this:
public Player(String name, int score, int number, boolean enabled, RelativeLayout mainScreen, List<Button> presetButtonList, Editor editor, Context context) {
super();
this.name = name;
this.score = score;
this.number = number;
this.enabled = enabled;
this.editor = editor;
// Get the lowest child on the mainScreen
Integer count = mainScreen.getChildCount(), lowestChildId = null;
Float lowestChildBottom = null;
for (int i = 0; i < count; i++) {
View child = mainScreen.getChildAt(i);
if ((lowestChildId == null || child.getY() > lowestChildBottom) &&
!presetButtonList.contains(child)) {
lowestChildId = child.getId();
lowestChildBottom = child.getY();
}
}
playerNameText = (EditText) setTextViewDefaults(new EditText(context), name);
playerNameText.setSingleLine();
// playerNameText.setMaxWidth(mainScreen.getWidth());
// playerNameText.setEllipsize(TextUtils.TruncateAt.END); //TODO: Prevent names which are too long for screen
playerNameText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable changedText) {
setName(changedText.toString());
updateScreen();
}
public void beforeTextChanged(CharSequence changedText, int start, int count, int after) {}
public void onTextChanged(CharSequence changedText, int start, int before, int count) {}
});
RLParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (lowestChildId != null) {
RLParams.addRule(RelativeLayout.BELOW, lowestChildId);
} else {
RLParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
RLParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
}
RLParams.setMargins(0, 10, 0, 10);
mainScreen.addView(playerNameText, RLParams);
the class further defines buttons and etc in a similar fashion, aligning tops with the name text view. I call this when a user clicks a button to add a player, and it works fine, displaying each player below the first on down the screen. The problem comes in when I'm loading a bunch of saved players at the start. Here's where i load the players:
public void loadData() {
RelativeLayout mainScreen = (RelativeLayout)findViewById(R.id.relativeLayout);
playerCount = savedData.getInt("playerCount", playerCount);
Player player;
String name;
playerList.clear();
for (int i=1; i<=playerCount; i++) {
name = savedData.getString("name" + i, null);
if (name != null) {
Log.v("name", name);
player = new Player(name, savedData.getInt("score" + i, 0), i, savedData.getBoolean("enabled" + i, false), mainScreen, presetButtonList, editor, this);
playerList.add(player);
player.updateScreen();
}
}
updateScreen();
}
Finally, I call the loadData() method when the app starts, here:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
savedData = this.getPreferences(Context.MODE_PRIVATE);
editor = savedData.edit();
presetButtonList.add((Button)findViewById(R.id.newGame));
presetButtonList.add((Button)findViewById(R.id.addPlayer));
presetButtonList.add((Button)findViewById(R.id.removePlayer));
loadData();
}
The result? When there are more than two players to load, all the players get loaded to the same spot, on top of Player 2.
I suspect somehow that the players are all being generated at the same time and thus all believing that the lowest player view is Player 1, and not checking each other. I've tried triggering the load later than onCreate() and it still happens. I also tried adding a 3 second sleep within the for loop of loadData() after each player loads to see if that helped, but no luck.
Am I making bad assumptions? What am I doing wrong and how might I fix it?
I suspect what is happening here is that you are attempting to position views that don't have IDs (it looks like you don't set them anywhere in your code). Dynamically created views don't automatically have IDs, so a call to getId() will return NO_ID (See documentation). If you want to use an ID you will have to set it yourself using View.setId().
It was a timing issue after all. I needed to wait for the main screen to load before I could add views to it. Unfortunately, it would never load until all activity on the UI thread was finished.
Thus, I needed threading. I ended up putting loadData() in a thread, like this:
new Thread(new loadDataAsync(this)).start();
class loadDataAsync implements Runnable {
MainActivity mainActivity;
public loadDataAsync(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
#Override
public void run() {
try {
Thread.sleep(700);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
loadData(mainActivity);
}
}
Then I created the players back on the UI thread after the initial sleep to give time for the UI to load.
runOnUiThread(new Runnable() {
Player player;
RelativeLayout mainScreen = (RelativeLayout)findViewById(R.id.relativeLayout);
#Override
public void run() {
player = new Player(savedData.getString("name" + playerNum, null), savedData.getInt("score" + playerNum, 0), playerNum, savedData.getBoolean("enabled" + playerNum, false), mainScreen, presetButtonList, editor, mainActivity);
playerList.add(player);
player.updateScreen();
mainScreen.invalidate();
}
});
Not the most elegant solution, but it works for now.

ImageView.setImageResource is not displaying correct drawable

I have this app, it's basically a 'make fun' app I made with a person's face and the ability to either shoot it with a pistol, automatic rifle, or grenade (more weapons to come :-)).
I have a Weapon class, with the following code. (I'm pretty new to java so forgive me if I failed to follow proven ways, or do things as efficiently as I should)
public class Weapon {
// Parent
public static MainActivity ma;
// Constants
public static final int BULLET_WIDTH = 97;
public static final int BULLET_HEIGHT = 92;
public static final int EXPLOD_WIDTH = 299;
public static final int EXPLOD_HEIGHT = 237;
public static final int PISTOL = 0;
public static final int RIFLE = 1;
public static final int GRENADE = 2;
protected static int[] position = {0, 0};
protected static RelativeLayout rl = null;
protected static MediaPlayer mp;
// Protected stuff
// Object variables.
protected int type;
protected int drawableEffect;
protected int soundEffect;
// Functionals
protected ImageView effectImage;
public void equipWeapon() {
// Clear any existing listeners and assign a new one.
MainActivity.mainImage.setOnTouchListener(null);
MainActivity.mainImage.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Which weapon are we using?
switch (type) {
case Weapon.PISTOL:
case Weapon.GRENADE:
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Fire the weapon.
fireWeapon(v, event);
}
case Weapon.RIFLE:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE: // This doesn't work ???
// Fire the weapon.
fireWeapon(v, event);
}
}
// perfomClick needed.
return v.performClick();
}
});
}
public void fireWeapon(View v, MotionEvent event) {
// Reference the layout.
Weapon.rl = (RelativeLayout)Weapon.ma.findViewById(R.id.relativeLayout);
// Define properties.
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
// Get the touch position.
Weapon.position[0] = (int)event.getX() - ((type == Weapon.PISTOL || type == Weapon.RIFLE) ? Weapon.BULLET_WIDTH:Weapon.EXPLOD_WIDTH);
Weapon.position[1] = (int)event.getY() - ((type == Weapon.PISTOL || type == Weapon.RIFLE) ? Weapon.BULLET_HEIGHT:Weapon.EXPLOD_HEIGHT);
// Set the position.
lp.setMargins(Weapon.position[0], Weapon.position[1], 0, 0);
effectImage.setLayoutParams(lp);
// Add the view to the layout.
Weapon.rl.addView(effectImage, lp);
// Play the sound.
Weapon.mp.seekTo(0);
Weapon.mp.start();
// Reload
reload();
}
public void reload() {
// Create the ImageView
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
And I have a Pistol class which extends Weapon
public class Pistol extends Weapon {
public Pistol() {
// First save the type.
this.type = Weapon.PISTOL;
// Fetch the sound effect and image.
this.soundEffect = R.raw.gunshot;
this.drawableEffect = R.drawable.bullet_hole1;
// Create the media player and initialize the sound.
Weapon.mp = MediaPlayer.create(Weapon.ma, this.soundEffect);
// Create the ImageView
this.effectImage = null;
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
As well as a Rifle class extending Weapon
public class Rifle extends Weapon {
public Rifle() {
// First save the type.
this.type = Weapon.RIFLE;
// Fetch the sound effect and image.
this.soundEffect = R.raw.gunshot;
this.drawableEffect = R.drawable.bullet_hole1;
// Create the media player and initialize the sound.
Weapon.mp = MediaPlayer.create(Weapon.ma, this.soundEffect);
// Create the ImageView
this.effectImage = null;
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
finally, I have a Grenade class extending, yep you guessed it, Weapon as well.
public class Grenade extends Weapon {
public Grenade() {
// First save the type.
this.type = Weapon.GRENADE;
// Fetch the sound effect and image.
this.soundEffect = R.raw.grenade;
this.drawableEffect = R.drawable.boom;
// Create the media player and initialize the sound.
Weapon.mp = MediaPlayer.create(Weapon.ma, this.soundEffect);
// Create the ImageView
this.effectImage = new ImageView(Weapon.ma);
this.effectImage.setImageResource(this.drawableEffect);
}
}
I have buttons in the main view which I have registered onClick listeners to so you can switch weapons to your liking.. Here is one for example:
grenadeButton = (ImageButton)findViewById(R.id.grenadeButton);
grenadeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (MainActivity.this.weapon != Weapon.GRENADE) {
// Change the background color.
resetButtons();
v.setBackgroundResource(R.drawable.background_selected);
// Change weapons.
MainActivity.this.currentWeapon = equipWeapon(Weapon.GRENADE);
}
}
});
and the equip weapon method in MainActivity.
public Weapon equipWeapon(int type) {
Weapon weapon = null;
switch (type) {
case Weapon.PISTOL:
weapon = new Pistol();
break;
case Weapon.RIFLE:
weapon = new Rifle();
break;
case Weapon.GRENADE:
weapon = new Grenade();
break;
}
// Play a sound and save changes.
MainActivity.this.weapon = type;
MainActivity.mp.seekTo(0);
MainActivity.mp.start();
return weapon;
}
Now, I appreciate you taking the time to review all this code. I know that's a lot to digest for what I'm assuming is a simple issue. I'm also aware of the rules of this forum and I have attempted to search for this issue already, but I'm not sure if I was using the right queries, as I did not find anything related to this issue.
Here we go:
When you start the app, the pistol is automatically equipped so you can start shooting immediately. It shoots fine, I get a bullet noise, and bullet holes all over the picture of the person's face ^_^. The rifle works fine as well (but it uses the same noise and graphic as the pistol, so it could very well be failing as well. Refer below).
When I switch to the grenade, I here a lovely explosion sound, but the image displayed is still a bullet hole and not an explosion.. I have no earthly idea how to fix this and I am stumped..
When I create the grenade object I specifically assign the drawable resource to the instance variable...
this.drawableEffect = R.drawable.boom;
Yet it still displays R.drawable.bullet_hole1....
Please let me know if you need more information and ask any questions you need to..
Thank you for your time..
I'm so stupid.....
MainActivity.equipWeapon
wasn't calling
Weapon.equipWeapon....
So the weapon wasn't changing... Oy' vey...

Categories

Resources