I am having problems with my remote device discovery code for bluetooth scanning.
It scans, and prints the MAC addresses if i uncomment the "system.out.print(devicesDiscovered);
But i want to be able to extract each MAC address from the Vector and place it in a String.
I have two differant FOR loops to do this, but neither of them seem to be executing.
Code:
import java.io.IOException;
import java.util.List;
import java.util.Vector;
import javax.bluetooth.*;
public class BluetoothDeviceDiscovery {
public static final Vector/*<RemoteDevice>*/ devicesDiscovered = new Vector();
public static void main() throws IOException, InterruptedException {
final Object inquiryCompletedEvent = new Object();
devicesDiscovered.clear();
final DiscoveryListener listener = new DiscoveryListener() {
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
devicesDiscovered.addElement(btDevice);
//
String testingAgain = devicesDiscovered.toString();
System.out.println("What?? : " + testingAgain);
/*
* As far as i know, the following two FOR loops do the same thing
* But both of them are not being executed...
*/
//Its not executing this...
for(int i=0; i< devicesDiscovered.size(); i++) {
System.out.println("test if this gets output");
String test = (String) devicesDiscovered.elementAt(i);
System.out.println("Test: " + test);
}
//Its not executing this....
for(int i=0; i> ((List) btDevice).size(); i++){
System.out.println("test if this gets output 1");
String testing = (String) devicesDiscovered.toString();
System.out.print("Test1: " + testing);
}
//Prints the MAC addresses [macaddress, macaddress, macaddress, etc]
// System.out.println(devicesDiscovered);
/*
* Now need to extract each macaddress from devicesDiscovered
* and convert from a Vector to a String
*/
}
public void inquiryCompleted(int discType) {
System.out.println("Device Inquiry completed!");
synchronized(inquiryCompletedEvent){
inquiryCompletedEvent.notifyAll();
}
}
public void serviceSearchCompleted(int transID, int respCode) {
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
}
};
synchronized(inquiryCompletedEvent) {
boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, listener);
if (started) {
System.out.println("wait for device inquiry to complete...");
inquiryCompletedEvent.wait();
System.out.println(devicesDiscovered.size() + " device(s) found");
}
}
}
}
Can anyone spot any reason(s) as to why these two for loops are not working?
Thanks a lot
- Ryan
In this line
//Its not executing this....
for(int i=0; i > ((List) btDevice).size(); i++) {
You have turned the > the wrong way... try
for(int i=0; i < ((List) btDevice).size(); i++) {
instead.
(The reason it doesn't iterate, is because the initial value, 0, is not greater than the size of the list!)
In your first loop:
//Its not executing this...
for(int i=0; i< devicesDiscovered.size(); i++) {
System.out.println("test if this gets output");
it must be the case that devicesDiscovered is empty. I suggest you do
System.out.println(devicesDiscovered.size());
before the loop to debug.
The execution of your code in my machine is the following:
BlueCove version 2.1.0 on bluez
wait for device inquiry to complete...
What?? : [...]
test if this gets output
Test: ...
Device Inquiry completed!
1 device(s) found
BlueCove stack shutdown completed
With the following for loop:
for(int i=0; i< devicesDiscovered.size(); i++)
{
System.out.println("test if this gets output");
String test = (String) devicesDiscovered.elementAt(i).toString();
System.out.println("Test: " + test);
}
I've noticed that you were testing which one of the for loops was generating the output that you wanted. I can say that the above one works but the second generates an exception. You are trying to cast a RemoteDevice object to a List and iterate through it (for(int i=0; i < ((List) btDevice).size(); i++)). That's the reason for not working and therefore the exception.
Related
Playing around with yield and Task.
The following simple example runs fine.
class Program
{
private static void Main(string[] args)
{
string[] messages = { "First task", "Second task", "Third task", "Fourth task" };
var taskList = CreateTaskList(messages).ToList();
taskList.ForEach(task => task.Start());
Task.WaitAll(taskList.ToArray());
Console.WriteLine("Main method complete. Press enter to finish.");
Console.ReadLine();
}
static IEnumerable<Task> CreateTaskList(string[] messages)
{
foreach (var message in messages)
{
yield return new Task(obj => PrintMessage((string)obj!), message);
}
}
static void PrintMessage(object message)
{
Console.WriteLine("Message: {0}", message);
}
}
But the following does not. Is some deadlock at play? Its stuck at Task.WaitAll. So all that I get from Console is Before wait all
class SimpleClass
{
public int Counter { get; set; }
}
class Program
{
private static void Main(string[] args)
{
// create the simple object
var simpleObject = new SimpleClass();
var taskList = CreateTaskEnumerable(simpleObject, 10);
// Start all of the tasks
foreach (var task in taskList)
task.Start();
Console.WriteLine("Before wait all");
// wait for all of the tasks to complete
Task.WaitAll(taskList.ToArray());
Console.WriteLine("After wait all");
foreach (var task in taskList)
simpleObject.Counter += task.Result;
// write out the counter value
Console.WriteLine("Expected value {0}, Counter value: {1}", 10000, simpleObject.Counter);
// wait for input before exiting
Console.WriteLine("Press enter to finish");
Console.ReadLine();
}
private static IEnumerable<Task<int>> CreateTaskEnumerable(SimpleClass simpleObject, int numberOfTasks)
{
for (int i = 0; i < numberOfTasks; i++)
{
yield return new Task<int>((stateObject) =>
{
// get the state object
var localCounter = (int)stateObject!;
// enter a loop for 1000 increments
for (int j = 0; j < 1000; j++)
// increment the counters
localCounter++;
return localCounter;
}, simpleObject.Counter);
}
}
}
If I remove yield altogether, the above will be as follows, and works. It gives the output as follows. I am expecting the same output from the above as well, but thats stuck. Why?
Before wait all
After wait all
Expected value 10000, Counter value: 10000
Press enter to finish
The program.
class SimpleClass
{
public int Counter { get; set; }
}
class Program
{
private static void Main(string[] args)
{
// create the bank account instance
var simpleObject = new SimpleClass();
// create an list of tasks
var taskList = new List<Task<int>>();
for (int i = 0; i < 10; i++)
{
// create a new task
var task = new Task<int>((stateObject) =>
{
// get the state object
var localCounter = (int)stateObject!;
// enter a loop for 1000 increments
for (int j = 0; j < 1000; j++)
// increment the counters
localCounter++;
return localCounter;
}, simpleObject.Counter);
taskList.Add(task);
}
// Start all of the tasks
foreach (var task in taskList)
task.Start();
Console.WriteLine("Before wait all");
// wait for all of the tasks to complete
Task.WaitAll(taskList.ToArray());
Console.WriteLine("After wait all");
foreach (var task in taskList)
simpleObject.Counter += task.Result;
// write out the counter value
Console.WriteLine("Expected value {0}, Counter value: {1}", 10000, simpleObject.Counter);
// wait for input before exiting
Console.WriteLine("Press enter to finish");
Console.ReadLine();
}
}
In the first example you are calling CreateTaskList(messages).ToList() which forces CreateTaskList to yield all tasks before continuing. In the second example you do not call ToList(), and the tasks are yielded in the foreach and then started. The problem is in line Task.WaitAll(taskList.ToArray());. It takes the IEnumerable and yields the tasks again, and you are waiting for them to finish, but they are not started. In other words, every time you call foreach or ToList() on your 'yielded' IEnumerable, it will run the method CreateTaskEnumerable and create new tasks.
One solution is to call var taskList = CreateTaskEnumerable(simpleObject, 10).ToList() or you could just manualy create list in CreateTaskEnumerable and return it.
P.S. I would suggest you read how yield return works, or test it in https://sharplab.io/. It basically creates IEnumerable that gets its data from your method. This means your method will be executed every time your IEnumerable is enumerated.
I have a number of pizzas. that number is defined by the user. the for loop will run for that length of time. each time the for loop runs I want a new class for that pizza to be made. in order to do this (as far as I know) the names need to be different. I want the default name to be "pizza" and then for each reiteration of the for loop I want it to tack on a number to pizza. i.e "pizza1" "pizza2"
using System;
namespace PizzaCalculator
{
public class Pizza
{
public double size{get;set;}
public double price{get;set;}
public double squarInch;
public double pricePerInch;
public double radius;
public double radius2;
public string brand{get;set;}
public void calculate()
{
radius = (size/2);
radius2 = Math.Pow(radius, 2);
squarInch = radius2*3.14159;
pricePerInch = Math.Round((price/squarInch),2);
}
}
class Program
{
static void Main(string[] args)
{
double pizzaNum;
Console.WriteLine("How many pizza's do you want to compair?");
pizzaNum = Convert.ToInt32(Console.ReadLine());
for (int i = 0; i < pizzaNum; i++)
{
Console.Write("\nPlease enter the brand of the pizza: ");
Pizza pizza = new Pizza() {brand = Console.ReadLine()};
}
Console.ReadKey();
}
}
}
I've tried to attach [i] to the end of "pizza" but I don't really know for sure how to go about doing this.
You can use a List<Pizza>to store your pizzas.
List<Pizza> pizzas = new List<Pizza>();
for (int i = 0; i < pizzaNum; i++)
{
Console.Write("\nPlease enter the brand of the pizza: ");
Pizza pizza = new Pizza() {brand = Console.ReadLine()};
pizzas.Add(pizza);
}
To read the data, you can use a foreach loop:
foreach(Pizza pizza in pizzas)
{
Console.WriteLine(pizza.brand);
}
Or to access a specific pizza, you can use the indexer:
Console.WriteLine(pizzas[0].brand);
Why is in this program BufferedReader taking infinite input?
Below is the code which is taking input infinitely. To avoid this I have added condition
while((!(s1=br.readLine().trim()).equals(null))&&(!s1.isEmpty())){
but it didn't work out.
import java.io.*;
import java.util.*;
public class skylerStudent {
public static void main(String []args)throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s1="";String s="";
while((!(s1=br.readLine().trim()).equals(null))&&(!s1.isEmpty())){
s+=s1.trim()+" ";
}
StringTokenizer st=new StringTokenizer(s.trim());
int i=0,n=0,q=0;
while(st.hasMoreTokens()){
if(i==0)n=Integer.parseInt(st.nextToken());
if(i==1)q=Integer.parseInt(st.nextToken());
i++;
}
int ar[]=new int[n];i=0;
while(st.hasMoreTokens()){
if(i<n)ar[i]=Integer.parseInt(st.nextToken());
i++;
}
i=0;
while(st.hasMoreTokens()){
StringTokenizer st1=new StringTokenizer(st.nextToken());
while(st.hasMoreTokens()){
if(i<q){
int a=Integer.parseInt(st1.nextToken());
int b=Integer.parseInt(st1.nextToken());
System.out.println(a);System.out.println(b);}
i++;
}
}
}
}
The condition !(s1 = br.readLine().trim()).equals(null) is not correct. If you can call .trim on string then it can never be null. You can check
(s1 = br.readLine()) != null
Also the infinite loop is not in the reading the input, its in the one of the later loops of the code.
while (st.hasMoreTokens()) {
if (i == 0)
n = Integer.parseInt(st.nextToken());
if (i == 1)
q = Integer.parseInt(st.nextToken());
i++;
}
You are not moving forward to nextToken() if the i is not in (0,1). That's why it would never exit the loop.
Am trying to show someone over here how good I find the sonar
tool...
then I wrote a small java project and defined many intentionally smelly methods,
2 of those are exactly the same (copy+paste) do1 and do2
surprisenly, after running the sonnar, there is no duplication error nor warnings...
public void do1() {
for (int i = 0; i < 10; i++) {
if (i != 0) {
System.out.println("Hello");
System.out.println(new Date());
}
}
}
public void do2() {
for (int i = 0; i < 10; i++) {
if (i != 0) {
System.out.println(new Date());
System.out.println("Hello");
}
}
}
what is the criteria for a java project to raise a warning on duplicates then?
Your methods are too short to show up as duplicated. Per the docs,
There should be at least 10 successive and duplicated statements whatever the number of tokens and lines.
I made two scripts in Unity3D that should check names and count of objects in folder. The thing is, that it is doing it's job infinitely. Don't you know where is the problem?
First Script
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MenuSetup : MonoBehaviour {
public static List<Texture2D> UnitIconTextures = new List<Texture2D>();
public static List<string> UnitNames = new List<string>();
public static List<string> UnitPaths = new List<string>();
void OnGUI(){
for(int i = 0; i < UnitNames.Count; i++){
Debug.Log (UnitNames[i]);
}
}
}
Second script
using UnityEngine;
using System.Collections;
public class World : MonoBehaviour {
void Start(){
string path = "Prefabs/Units";
Object[] Units = Resources.LoadAll (path);
if(Units.Length > 0){
for(int i = 0; i < Units.Length; i++){
GameObject unit = Units[i] as GameObject;
Texture2D unitIcon = unit.GetComponent<Unit>().MenuIcon;
MenuSetup.UnitIconTextures.Add (unitIcon);
MenuSetup.UnitNames.Add (unit.name);
MenuSetup.UnitPaths.Add (path+"/"+unit.name);
}
}
}
}
Ok. Nothing is looping infinitely. The problem is with this code:
void OnGUI(){
for(int i = 0; i < UnitNames.Count; i++){
Debug.Log (UnitNames[i]);
}
}
This method might be called several times per frame. So that's why you see a lot of debug info. While Start method is called only once. So actually, in World the Start method is called once. This method adds all info to MenuSetup class only once. And then you call Debug.Log on every frame.
Read more info about OnGUI on unity doc. Also you should read about Start method here.
Little suggestion
Probably you don't need the if check in
if(Units.Length > 0){
for(int i = 0; i < Units.Length; i++){
GameObject unit = Units[i] as GameObject;
Texture2D unitIcon = unit.GetComponent<Unit>().MenuIcon;
MenuSetup.UnitIconTextures.Add (unitIcon);
MenuSetup.UnitNames.Add (unit.name);
MenuSetup.UnitPaths.Add (path+"/"+unit.name);
}
}
Because when Units.Length == 0 for-block will not be executed. So probably you want to write
for(int i = 0; i < Units.Length; i++){
GameObject unit = Units[i] as GameObject;
Texture2D unitIcon = unit.GetComponent<Unit>().MenuIcon;
MenuSetup.UnitIconTextures.Add (unitIcon);
MenuSetup.UnitNames.Add (unit.name);
MenuSetup.UnitPaths.Add (path+"/"+unit.name);
}