getApplicationContext() returns null with Belkin WeMo SDK - java

I'm trying to create an app on Android Studio that uses the Belkin WeMo SDK to control the devices around my house. I initialized the mWeMoSDKContext object in the onCreate method as was given in the documentation. However, when I went to run the app I kept getting a NullPointerException and after debugging I found that it was in the lines where I initialized the object. Is there any way to fix this? Also any advice on the app would also be appreciated!
public class MyActivity extends AppCompatActivity implements NotificationListener {
private WeMoSDKContext mWeMoSDKContext = null;
private EditText devicesDisp = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Button onButton = (Button)findViewById(R.id.button);
Button offButton = (Button)findViewById(R.id.button2);
devicesDisp = (EditText)findViewById(R.id.textView2);
TextView device = (TextView) findViewById(R.id.textView);
**mWeMoSDKContext = new WeMoSDKContext(getApplicationContext());
mWeMoSDKContext.addNotificationListener(this);**
}
public class TextTask extends AsyncTask <String, String, String>{
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
mWeMoSDKContext.refreshListOfWeMoDevicesOnLAN();
}
}
public void onNotify(final String event, final String udn) {
ArrayList<String> udns = mWeMoSDKContext.getListOfWeMoDevicesOnLAN();
int length = udns.size();
if (event.equals(WeMoSDKContext.REFRESH_LIST)) {
if(udns.size() == 0){
devicesDisp.setText("No Devices Detected");
}
else {
for (int i = 0; i < length; i++) {
WeMoDevice device = mWeMoSDKContext.getWeMoDeviceByUDN(udns.get(i));
String tempName = device.getFriendlyName();
devicesDisp.setText(tempName);
}
}
}
}
else if(event.equals(WeMoSDKContext.SET_STATE)) {
int numDevices = udns.size();
if(hourlyPrice > hourlyPriceLimit) {
for (int i = 0; i < numDevices; i++) {
String checkState = "WEMO_DEVICE_OFF";
WeMoDevice checkDevice = mWeMoSDKContext.getWeMoDeviceByUDN(udns.get(i));
if (!checkDevice.getState().equalsIgnoreCase("WEMO_DEVICE_OFF")){
devicesDisp.setText("Device state not changed for" + checkDevice);
}
}
}
else{
for (int i = 0; i < numDevices; i++) {
String checkState = "WEMO_DEVICE_ON";
WeMoDevice checkDevice = mWeMoSDKContext.getWeMoDeviceByUDN(udns.get(i));
if (!checkDevice.getState().equalsIgnoreCase("WEMO_DEVICE_ON")){
devicesDisp.setText("Device state not changed for" + checkDevice);
}
}
}
}
}
public void turnON(View view){
ArrayList<String> devices = mWeMoSDKContext.getListOfWeMoDevicesOnLAN();
int length = devices.size();
for(int i = 0; i < length; i++){
String state = "WEMO_DEVICE_ON";
WeMoDevice deviceState = mWeMoSDKContext.getWeMoDeviceByUDN(devices.get(i));
String type = deviceState.getType();
if (type.equals(WeMoDevice.SWITCH) || type.equals(WeMoDevice.INSIGHT)) {
mWeMoSDKContext.setDeviceState(state, devices.get(i));
}
}
}
public void turnOFF(View view){
ArrayList<String> devices = mWeMoSDKContext.getListOfWeMoDevicesOnLAN();
int length = devices.size();
for(int i = 0; i < length; i++){
String state = "WEMO_DEVICE_OFF";
WeMoDevice deviceState = mWeMoSDKContext.getWeMoDeviceByUDN(devices.get(i));
String type = deviceState.getType();
if (type.equals(WeMoDevice.SWITCH) || type.equals(WeMoDevice.INSIGHT)) {
mWeMoSDKContext.setDeviceState(state, devices.get(i));
}
}
}
protected void onDestroy() {
super.onDestroy();
mWeMoSDKContext.stop();
}
}
UPDATE: Here's the stack trace of the error
java.lang.NullPointerException: Attempt to get length of null array
at org.cybergarage.upnp.ControlPoint.start(ControlPoint.java:976)
at org.cybergarage.upnp.ControlPoint.start(ControlPoint.java:1051)
at com.belkin.wemo.localsdk.WeMoSDKContext$1.run(WeMoSDKContext.java:125)
at java.lang.Thread.run(Thread.java:818)

Related

Cannot resolve constructor 'BaseBar(java.time.ZonedDateTime, java.lang.Double)'?

So I'm an amateur Android developer and have an issue.
My app uses this library (https://github.com/ta4j/ta4j) but after updating it to the latest stable release I'm having these errors!
Here's the error:
Cannot resolve constructor 'BaseBar(java.time.ZonedDateTime, java.lang.Double, java.lang.Double, java.lang.Double, java.lang.Double, java.lang.Double)'
Here's the java code of my class:
public class RVCardAdapter extends RecyclerView.Adapter<RVCardAdapter.CryptoViewHolder> {
//globals
private List<SingleCryptoData> mCryptos;
private int mExpandedPosition;
//private int previousExpandedPosition = -1;
//default constructor
public RVCardAdapter() {
super();
mCryptos = new ArrayList<>();
}
//this refreshes the list
public void clear() {
mCryptos.clear();
notifyDataSetChanged();
}
//this adds the POJO passed into the crypto list
public void addData(SingleCryptoData crypto) {
mCryptos.add(crypto);
notifyDataSetChanged();
}
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#NonNull
#Override
public CryptoViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cryptocurrency_card, viewGroup, false);
return new CryptoViewHolder(v);
}
//onBindViewHolder binds the data to the layout elements for each crypto
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull CryptoViewHolder cryptoViewHolder, int i) {
//loading animation
FiftyShadesOf fiftyShades = new FiftyShadesOf(cryptoViewHolder.mCardViewDetails.getContext());
fiftyShades.on(cryptoViewHolder.mSignal, cryptoViewHolder.mCardViewDetails, cryptoViewHolder.mSignalStrength);
fiftyShades.fadein(true);
fiftyShades.start();
//set up output formatting
Currency usd = Currency.getInstance("USD");
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
currencyFormat.setCurrency(usd);
NumberFormat twoDecimalFormat = DecimalFormat.getInstance(Locale.US);
twoDecimalFormat.setRoundingMode(RoundingMode.FLOOR);
twoDecimalFormat.setMinimumFractionDigits(0);
twoDecimalFormat.setMaximumFractionDigits(2);
//TODO get display POJO data
cryptoViewHolder.mCryptoName.setText(mCryptos.get(i).getName());
cryptoViewHolder.mCryptoValue.setText(currencyFormat.format(mCryptos.get(i).getRaw().getPrice()));
cryptoViewHolder.mCryptoSymbol.setText(mCryptos.get(i).getRaw().getFromSymbol());
cryptoViewHolder.mCryptoDetailsVolume.setText(twoDecimalFormat.format(mCryptos.get(i).getRaw().getVolume24Hour()) + " " + mCryptos.get(i).getRaw().getFromSymbol());
cryptoViewHolder.mCryptoDetailsLow.setText(currencyFormat.format(mCryptos.get(i).getRaw().getLow24Hour()));
cryptoViewHolder.mCryptoDetailsHigh.setText(currencyFormat.format(mCryptos.get(i).getRaw().getHigh24Hour()));
cryptoViewHolder.mCryptoDetailsOpen.setText(currencyFormat.format(mCryptos.get(i).getRaw().getOpen24Hour()));
cryptoViewHolder.mCryptoDetailsPercentChange.setText(twoDecimalFormat.format(mCryptos.get(i).getRaw().getChangePercent24Hour()) + " %");
//color percent change depending on value
if (mCryptos.get(i).getRaw().getChangePercent24Hour() >= 0) {
cryptoViewHolder.mCryptoDetailsPercentChange.setTextColor(Color.parseColor("#52BE80"));
} else {
cryptoViewHolder.mCryptoDetailsPercentChange.setTextColor(Color.RED);
}
//handles expanding animation
//TODO stop first card from expanding
final boolean isExpanded = cryptoViewHolder.getAdapterPosition() == mExpandedPosition;
cryptoViewHolder.mCardViewDetails.setVisibility((isExpanded) ? View.VISIBLE : View.GONE);
cryptoViewHolder.itemView.setActivated(isExpanded);
// if (isExpanded)
// previousExpandedPosition = cryptoViewHolder.getAdapterPosition();
cryptoViewHolder.itemView.setOnClickListener(v -> {
mExpandedPosition = (isExpanded) ? -1 : cryptoViewHolder.getAdapterPosition();
//notifyItemChanged(previousExpandedPosition); //this used to close the
notifyItemChanged(cryptoViewHolder.getAdapterPosition());
});
//HISTODATA API
CryptoCompareAPI service = ServiceFactory.createRetrofitRx(CryptoCompareAPI.class, CryptoCompareAPI.BASE_URL);
if (android.os.Build.VERSION.SDK_INT >= 26){
//DAYS OF HISTORY TO GET FOR EACH CRYPTO
int historyDays = 14;
service.getHistoricalData(mCryptos.get(i).getRaw().getFromSymbol(), "USD", historyDays, "CryptoAnalysis")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<HistoData>() {
#Override
public void onSubscribe(Disposable d) {
}
//in histodata, the last element is the newest, and is yesterday. it will be at position [days]
#Override
public void onNext(HistoData histoData) {
TimeSeries series = new BaseTimeSeries("Strategy");
//TODO make usable on API 21+
ZonedDateTime endTime = ZonedDateTime.now().minusDays(historyDays);
//loop for each day of results in histodata
for (int i = 0; i < histoData.getData().size(); i++) {
//create a new base bar
Bar bar = new BaseBar(
endTime.plusDays(i),
histoData.getData().get(i).getOpen(),
histoData.getData().get(i).getHigh(),
histoData.getData().get(i).getLow(),
histoData.getData().get(i).getClose(),
histoData.getData().get(i).getVolumeTo()
);
series.addBar(bar);
}
//RUN ANALYSIS
Signal signal = TechnicalAnalysis.getSignal(series);
//INFLATE LAYOUT STUFF
cryptoViewHolder.mSignal.setText(signal.getSignalResult());
cryptoViewHolder.mRsiValue.setVisibility(View.VISIBLE);
cryptoViewHolder.mRsiValue.setText(String.valueOf((int) signal.getRsiStrength()));
cryptoViewHolder.mMomentumValue.setVisibility(View.VISIBLE);
cryptoViewHolder.mMomentumValue.setText(String.valueOf((int) signal.getMomentumStrength()));
cryptoViewHolder.mEmaValue.setVisibility(View.VISIBLE);
cryptoViewHolder.mEmaValue.setText(String.valueOf((int) signal.getEmaStrength()));
//cryptoViewHolder.mSignalStrength.setText("(" + String.valueOf(signal.getSignalStrength()) + ")");
}
#Override
public void onError(Throwable e) {
if (e.getMessage() != null)
Log.e("Histo API Error", e.getMessage());
}
#Override
public void onComplete() {
fiftyShades.stop();
}
});
} else {
int historyDays = 14;
service.getHistoricalData(mCryptos.get(i).getRaw().getFromSymbol(), "USD", historyDays, "CryptoAnalysis")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<HistoData>() {
#Override
public void onSubscribe(Disposable d) {
}
//in histodata, the last element is the newest, and is yesterday. it will be at position [days]
#Override
public void onNext(HistoData histoData) {
TimeSeries series = new BaseTimeSeries("Strategy");
//RUN ANALYSIS
Signal signal = TechnicalAnalysis.getSignal(series);
//INFLATE LAYOUT STUFF
cryptoViewHolder.mSignal.setText(signal.getSignalResult());
}
#Override
public void onError(Throwable e) {
if (e.getMessage() != null)
Log.e("Histo API Error", e.getMessage());
}
#Override
public void onComplete() {
fiftyShades.stop();
}
});
}
}
#Override
public int getItemCount() {
return mCryptos.size();
}
static class CryptoViewHolder extends RecyclerView.ViewHolder {
CardView mCardView;
TextView mCryptoDetailsOpen;
TextView mCryptoDetailsHigh;
TextView mCryptoDetailsLow;
TextView mCryptoDetailsVolume;
TextView mCryptoDetailsPercentChange;
TextView mCryptoName;
TextView mCryptoValue;
TextView mCryptoSymbol;
ConstraintLayout mCardViewDetails;
TextView mSignal;
TextView mRsiValueLabel;
TextView mRsiValue;
TextView mEmaValueLabel;
TextView mEmaValue;
TextView mMomentumValueLabel;
TextView mMomentumValue;
TextView mSignalStrength;
TextView mLowerApi;
CryptoViewHolder(View itemView) {
super(itemView);
mCryptoDetailsHigh = itemView.findViewById(R.id.crypto_details_high);
mCryptoDetailsOpen = itemView.findViewById(R.id.crypto_details_open);
mCryptoDetailsLow = itemView.findViewById(R.id.crypto_details_low);
mCryptoDetailsVolume = itemView.findViewById(R.id.crypto_details_volume);
mCryptoDetailsPercentChange = itemView.findViewById(R.id.crypto_details_percent_change);
mCardViewDetails = itemView.findViewById(R.id.card_view_details);
mCardView = itemView.findViewById(R.id.card_view);
mCryptoName = itemView.findViewById(R.id.crypto_name);
mCryptoValue = itemView.findViewById(R.id.crypto_value);
mCryptoSymbol = itemView.findViewById(R.id.crypto_symbol);
mSignal = itemView.findViewById(R.id.signal);
if (android.os.Build.VERSION.SDK_INT >= 26) {
mRsiValue = itemView.findViewById(R.id.rsi_indicator_value);
mRsiValue.setVisibility(View.VISIBLE);
mEmaValue = itemView.findViewById(R.id.ema_indicator_value);
mEmaValue.setVisibility(View.VISIBLE);
mMomentumValue = itemView.findViewById(R.id.momentum_indicator_value);
mMomentumValue.setVisibility(View.VISIBLE);
mRsiValueLabel = itemView.findViewById(R.id.rsi_value_label);
mRsiValueLabel.setVisibility(View.VISIBLE);
mEmaValueLabel = itemView.findViewById(R.id.ema_value_label);
mEmaValueLabel.setVisibility(View.VISIBLE);
mMomentumValueLabel = itemView.findViewById(R.id.momentum_value_label);
mMomentumValueLabel.setVisibility(View.VISIBLE);
mLowerApi = itemView.findViewById(R.id.lowApi);
mLowerApi.setVisibility(View.GONE);
}
//mSignalStrength = itemView.findViewById(R.id.signal_strength);
}
}
}
The lines where the error is shown:
for (int i = 0; i < histoData.getData().size(); i++) {
//create a new base bar
Bar bar = new BaseBar(
endTime.plusDays(i),
histoData.getData().get(i).getOpen(),
histoData.getData().get(i).getHigh(),
histoData.getData().get(i).getLow(),
histoData.getData().get(i).getClose(),
histoData.getData().get(i).getVolumeTo()
);
series.addBar(bar);
}
Class 2:
public class TechnicalAnalysis {
//variables and their values, these dictate how likely the signal is to move one way or another.
//Eventually, these will be tweaked and changed to be more accurate.
private static double rsiOversold = 25;
private static double rsiOverbought = 75;
private static double rsiWeight = 0.35;
private static double momentumWeight = 0.3;
private static double emaWeight = 0.35;
public static Signal getSignal(TimeSeries series) {
int numBars = series.getBarCount(); //this is the number of days in the series
//create indicators from series
//in all of these, the LAST member is the latest
ClosePriceIndicator closePrices = new ClosePriceIndicator(series);
RSIIndicator rsi = new RSIIndicator(closePrices, numBars);
EMAIndicator shortEma = new EMAIndicator(closePrices, numBars / 4);
EMAIndicator longEma = new EMAIndicator(closePrices, numBars);
//init strength vars
int rsiStrength = 0;
int momentumStrength = 0;
int emaStrength = 0;
//RSI 35%
for (int i = 0; i < numBars; i++) {
if (rsi.getValue(i).isGreaterThanOrEqual(rsiOverbought)) {
rsiStrength += i;
} else if (rsi.getValue(i).isLessThanOrEqual(rsiOversold)) {
rsiStrength -= i;
}
}
//EMA 45%
for (int i = 0; i < numBars; i++) {
if (shortEma.getValue(i).isGreaterThan(longEma.getValue(i).multipliedBy(1.04))) {
emaStrength += i;
} else {
emaStrength -= i;
}
}
//MOMENTUM 20%
for (int i = 0; i < numBars; i++) {
if (series.getBar(i).getClosePrice().isGreaterThan(series.getBar(i).getOpenPrice())) {
momentumStrength += i;
} else {
momentumStrength -= i;
}
}
//finally, return the completed
double rsiValue = rsiStrength * rsiWeight;
double emaValue = emaStrength * emaWeight;
double momentumValue = momentumStrength * momentumWeight;
return new Signal(rsiValue, emaValue, momentumValue);
}
}
Class 2 error:
isGreaterThanOrEqual
(org.ta4j.core.num.Num)
in Num cannot be applied to (double)
Class 2 error line:
for (int i = 0; i < numBars; i++) {
if (rsi.getValue(i).isGreaterThanOrEqual(rsiOverbought)) {
rsiStrength += i;
} else if (rsi.getValue(i).isLessThanOrEqual(rsiOversold)) {
rsiStrength -= i;
}
}
Can someone help, please?

What is the easiest way to update a textView from a service?

I am making an app which consists of an activity and a service. By pressing a button the service is started, it collects data in the background from a sensor and classifies it and outputs a string. I want to display the string in a textView. Right now I can see in the log that the variable is updated 2 times every second, but when I try and update the textView from the service class nothing is happening unless I press the button, whenever I press the button, the string is displayed in the textView.
What is the easiest solution here? I tried to make the textView static and it still can't update it. Can you make it so that the view is updated automatically every second? Can I add a listener somehow? Since I am not very experienced I would like an easy solution that does not have to be a "good" one.
Here is my code
Activity:
public class CollectorActivity extends Activity {
private enum State {
IDLE, COLLECTING, TRAINING, CLASSIFYING
};
private final String[] mLabels = { Globals.CLASS_LABEL_STANDING,
Globals.CLASS_LABEL_WALKING, Globals.CLASS_LABEL_RUNNING,
Globals.CLASS_LABEL_OTHER };
private RadioGroup radioGroup;
private final RadioButton[] radioBtns = new RadioButton[4];
private Intent mServiceIntent;
private File mFeatureFile;
public static TextView mCurrentLabel;
private State mState;
private Button btnDelete;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
radioGroup = (RadioGroup) findViewById(R.id.radioGroupLabels);
radioBtns[0] = (RadioButton) findViewById(R.id.radioStanding);
radioBtns[1] = (RadioButton) findViewById(R.id.radioWalking);
radioBtns[2] = (RadioButton) findViewById(R.id.radioRunning);
radioBtns[3] = (RadioButton) findViewById(R.id.radioOther);
btnDelete = (Button) findViewById(R.id.btnDeleteData);
mCurrentLabel = (TextView) findViewById(R.id.textView);
mState = State.IDLE;
mFeatureFile = new File(getExternalFilesDir(null),
Globals.FEATURE_FILE_NAME);
mServiceIntent = new Intent(this, SensorsService.class);
}
public void onCollectClicked(View view) {
if (mState == State.IDLE) {
mState = State.COLLECTING;
((Button) view).setText(R.string.ui_collector_button_stop_title);
btnDelete.setEnabled(false);
radioBtns[0].setEnabled(false);
radioBtns[1].setEnabled(false);
radioBtns[2].setEnabled(false);
radioBtns[3].setEnabled(false);
int acvitivtyId = radioGroup.indexOfChild(findViewById(radioGroup
.getCheckedRadioButtonId()));
String label = mLabels[acvitivtyId];
Bundle extras = new Bundle();
extras.putString(Globals.CLASS_LABEL_KEY, label);
mServiceIntent.putExtras(extras);
startService(mServiceIntent);
} else if (mState == State.COLLECTING) {
mState = State.IDLE;
((Button) view).setText(R.string.ui_collector_button_start_title);
btnDelete.setEnabled(true);
radioBtns[0].setEnabled(true);
radioBtns[1].setEnabled(true);
radioBtns[2].setEnabled(true);
radioBtns[3].setEnabled(true);
stopService(mServiceIntent);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancelAll();
}
}
public void onDeleteDataClicked(View view) {
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
if (mFeatureFile.exists()) {
mFeatureFile.delete();
}
Toast.makeText(getApplicationContext(),
R.string.ui_collector_toast_file_deleted,
Toast.LENGTH_SHORT).show();
}
}
#Override
public void onBackPressed() {
if (mState == State.TRAINING) {
return;
} else if (mState == State.COLLECTING || mState == State.CLASSIFYING) {
stopService(mServiceIntent);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel(Globals.NOTIFICATION_ID);
}
super.onBackPressed();
}
#Override
public void onDestroy() {
// Stop the service and the notification.
// Need to check whether the mSensorService is null or not.
if (mState == State.TRAINING) {
return;
} else if (mState == State.COLLECTING || mState == State.CLASSIFYING) {
stopService(mServiceIntent);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancelAll();
}
finish();
super.onDestroy();
}
And this is the "doInBackground" method in my service class. The line "CollectorActivity.mCurrentLabel.setText(classification);" is the problem. I want this to update the textView continously.
public class OnSensorChangedTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
Instance inst = new DenseInstance(mFeatLen);
inst.setDataset(mDataset);
Instance inst2 = new DenseInstance(65);
int blockSize = 0;
FFT fft = new FFT(Globals.ACCELEROMETER_BLOCK_CAPACITY);
double[] accBlock = new double[Globals.ACCELEROMETER_BLOCK_CAPACITY];
double[] re = accBlock;
double[] im = new double[Globals.ACCELEROMETER_BLOCK_CAPACITY];
double max = Double.MIN_VALUE;
while (true) {
try {
// need to check if the AsyncTask is cancelled or not in the while loop
if (isCancelled () == true)
{
return null;
}
// Dumping buffer
accBlock[blockSize++] = mAccBuffer.take().doubleValue();
if (blockSize == Globals.ACCELEROMETER_BLOCK_CAPACITY) {
blockSize = 0;
testList = new ArrayList<Double>();
// time = System.currentTimeMillis();
max = .0;
for (double val : accBlock) {
if (max < val) {
max = val;
}
}
fft.fft(re, im);
for (int i = 0; i < re.length; i++) {
double mag = Math.sqrt(re[i] * re[i] + im[i]
* im[i]);
inst.setValue(i, mag);
testList.add(i,mag);
im[i] = .0; // Clear the field
}
// Append max after frequency component
inst.setValue(Globals.ACCELEROMETER_BLOCK_CAPACITY, max);
inst2.setValue(Globals.ACCELEROMETER_BLOCK_CAPACITY, max);
testList.add(max);
classificationIndex = WekaClassifier.classify(testList.toArray());
classification = testLabel.get((int) classificationIndex);
CollectorActivity.mCurrentLabel.setText(classification);
inst.setValue(mClassAttribute, mLabel);
mDataset.add(inst);
Log.i("new instance", mDataset.size() + "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
In doInBackground(Void... arg0) change CollectorActivity.mCurrentLabel.setText(classification); to publishProgress(classification); then change second argument from Void to String: public class OnSensorChangedTask extends AsyncTask<Void, Srting, Void> and add onProgressUpdate().
Finally your code should looks like:
public class OnSensorChangedTask extends AsyncTask<Void, Srting, Void> {
#Override
protected Void doInBackground(Void... arg0) {
//...
publishProgress(classification);
//...
}
#Override
protected Void onProgressUpdate(String... classification) {
CollectorActivity.mCurrentLabel.setText(classification[0]);
}

how to access a variable from another class using interface in javafx?

I've two class autoCompleteTextfiled.java and BillingController.java.
AutocompleteTextFilled is a custom class. When I select a popup I'm getting result.
code is below:
private void populatePopup(List<String> searchResult) {
List<CustomMenuItem> menuItems = new LinkedList<>();
// If you'd like more entries, modify this line.
int maxEntries = 10;
int count = Math.min(searchResult.size(), maxEntries);
for (int i = 0; i < count; i++)
{
final String result = searchResult.get(i);
Label entryLabel = new Label(result);
CustomMenuItem item = new CustomMenuItem(entryLabel, true);
item.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent actionEvent) {
setText(result);
selectedTextFromMenu(result);
entriesPopup.hide();
}
});
menuItems.add(item);
}
entriesPopup.getItems().clear();
entriesPopup.getItems().addAll(menuItems);
}
private void selectedTextFromMenu(String result) {
AutoCompleteTextField autoCompleteTextField = new AutoCompleteTextField();
ItemSelectedListener mListener = new BillingController();
autoCompleteTextField.registerOnGeekEventListener(mListener);
autoCompleteTextField.selectItemListener(result);
}
public interface ItemSelectedListener
{
void getSelectedResult(String result);
}
public void registerOnGeekEventListener(ItemSelectedListener mListener)
{
this.itemSelectedListener = mListener;
}
public void selectItemListener(String result)
{
if (this.itemSelectedListener != null) {
itemSelectedListener.getSelectedResult(result);
}
}
but i trying to access a result from BillingControllerClass to AutoCompleteTextFiled returns null.
#Override
public void getSelectedResult(String result) {
System.out.println("The pin has been changed>"+billingItemDetails.size());//billingItemDetails retunes 0
for (int j= 0; j<billingItemDetails.size();j++)
{
ItemListRequestAndResponseModel.item_list item_list = billingItemDetails.get(j);
if (item_list.getItem_name().equals(result))
{
System.out.println("The pin has been changed---->"+result);
txtFieldId.setText(item_list.getShort_code());//Textfiledis retunes null
}
}
}
}
But billingItemDetails(Arraylist) retuns 0. But initially ArrayList have a data.
Please Help me.

Problems with Out of memory error

I get out of memory error if the function doesWifiExist is false if it is true every thing works normally.Can someone tell me what m i doing wrong
The idea is to get a list of wifi networks nearby and check if the inserted network exists in the list.
Here is the wifi network scanning code and the the function that checks if the wifi network exists.
MainActivity:
private WiFiConnection _wifiConnection = null;
static final int MY_PERMISSIONS_REQUEST = 1042;
private static final String PERMISSIONS_TAG = "PERMISSION";
...
#Override
protected void onStart() {
super.onStart();
_wifiConnection = new WiFiConnection(this);
startScan();
}
#Override
protected void onStop() {
super.onStop();
_wifiConnection.stopScan();
unregisterReceiver(_wifiScanReceiver);
}
void startScan() {
checkPermission(this);
registerReceiver(_wifiScanReceiver,
new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Thread t = new Thread(_wifiConnection.getWifiScanner());
t.start();
}
private final BroadcastReceiver _wifiScanReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
if (_wifiConnection != null && _wifiConnection.isWifiEnabled()) {
_wifiConnection.updateScanData();
}
}
}
};
public static boolean checkPermission(Activity activity) {
boolean permission = true;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<String> requiringList = new ArrayList<>();
permission = activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
Log.d(PERMISSIONS_TAG, "ACCESS_COARSE_LOCATION: " + permission);
if (!permission) {
requiringList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (requiringList.size() > 0) {
String[] stringArray = requiringList.toArray(new String[0]);
activity.requestPermissions(stringArray, MY_PERMISSIONS_REQUEST);
}
}
return permission;
}
private boolean doesWifiExist(String s){
String[] array = s.split(" ");
String ssid = array[0];
boolean flag = false;
//Check if wifi exists in the area
for(int i = 0 ; i < _wifiConnection.getListSSIDs().size(); i++){
if(_wifiConnection.getListSSIDs().get(i).equals(ssid)){
flag = true;
break;
}
}
return flag;
}
WiFiConnection class:
public class WiFiConnection
{
private static final int SCAN_INTERVAL = 5000;
final private List<String> _listSSIDs = new ArrayList<>();
private WifiManager _wifiManager;
private final WiFiScanner _startScan = new WiFiScanner();
private List<ScanResult> scanResults;
WiFiConnection(Activity activity) {
_wifiManager = (WifiManager) activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
//Puts wifi networks in a list
public List<String> getListSSIDs() {
for(int i = 0; i < scanResults.size(); i++)
{
_listSSIDs.add(scanResults.get(i).SSID);
}
return _listSSIDs;
}
WiFiScanner getWifiScanner() { return _startScan; }
void stopScan() { _startScan.stop(); }
boolean isWifiEnabled() { return _wifiManager.isWifiEnabled(); }
//Gets the wifi networks
void updateScanData() {
if ((_wifiManager != null && _wifiManager.isWifiEnabled())) {
scanResults = _wifiManager.getScanResults();
}
}
//Scans at an interval
private class WiFiScanner implements Runnable
{
private boolean _stop = false;
public void stop() {_stop = true;}
#Override
public void run() {
while (!_stop) {
_listSSIDs.clear();
_wifiManager.startScan();
try {
Thread.sleep(SCAN_INTERVAL);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
The code where doesWifiExist is used.
//Check if wifi exists in the area
if(doesWifiExist(barcode.displayValue)){
//Connects to wifi
WifiConnect(barcode.displayValue);
//Saves item in db
insertItem();
if(networkSecurity.equals("None")){
networkPass = empty;
}
//Adds item to recyclerview
historyItems.add(0, new HistoryItem(wifiName + " " + networkSSID, wifiPass + " " + networkPass));
adapter.notifyItemInserted(0);
} else
Snackbar.make(findViewById(R.id.main_activity), R.string.snackInvalidQrCode, Snackbar.LENGTH_SHORT).show();
This method is called many times, and it everytime adds all scanResults at the end of field _listSSIDS.
public List<String> getListSSIDs() {
for(int i = 0; i < scanResults.size(); i++)
{
_listSSIDs.add(scanResults.get(i).SSID);
}
return _listSSIDs;
}
Use a local variable with a new List or better Set there.
Instead replace
for(int i = 0 ; i < _wifiConnection.getListSSIDs().size(); i++){
if(_wifiConnection.getListSSIDs().get(i).equals(ssid)){
flag = true;
break;
}
}
with
flag = _wifiConnection.hasSSID(String ssid);
public boolean hasSSID(String ssid) {
for (int i = 0; i < scanResults.size(); i++) {
if (ssid.equals(scanResults.get(i).SSID)) {
return true;
}
}
return false;
}

My Android UI doesn't run?

I implemented AsyncTask to execute results. Here is the error I get...
FATAL EXCEPTION: AsyncTask #1
Process: ai69.psoui, PID: 3287
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Activity.<init>(Activity.java:754)
at android.support.v4.app.SupportActivity.<init>(SupportActivity.java:31)
at android.support.v4.app.BaseFragmentActivityGingerbread.<init>(BaseFragmentActivityGingerbread.java:37)
at android.support.v4.app.BaseFragmentActivityHoneycomb.<init>(BaseFragmentActivityHoneycomb.java:29)
at android.support.v4.app.BaseFragmentActivityJB.<init>(BaseFragmentActivityJB.java:30)
at android.support.v4.app.FragmentActivity.<init>(FragmentActivity.java:79)
at android.support.v7.app.AppCompatActivity.<init>(AppCompatActivity.java:61)
at ai69.psoui.MainActivity.<init>(MainActivity.java:0)
at android_tests.CustomUseCase.<init>(CustomUseCase.java:19)
at android_tests.TestFactory.getTest(TestFactory.java:15)
at ai69.psoui.ParticleActivity.runTest(ParticleActivity.java:91)
at ai69.psoui.ParticleActivity$runTests.doInBackground(ParticleActivity.java:53)
at ai69.psoui.ParticleActivity$runTests.doInBackground(ParticleActivity.java:50)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
I have looked at different SOF posts about "Looper.prepare()" but the thing is, prior to a few changes in changing static variables to getter/setter methods, my UI was working fine.
Here is my code...
public class ParticleActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = "PSOUI.MESSAGE";
private ProgressDialog pd;
private double[] results = {-1.0, -1.0, -1.0};
EditText particles;
EditText iterations;
EditText userSol;
EditText userBatt;
private double battery;
private double solution;
//int numberOfDimensions = MainActivity.dimensions.size();
//public ArrayList<Double> costData = MainActivity.costDATA; //costs that
the user enters for each resource
//public ArrayList<Double> costWlan = MainActivity.costWLAN;
//public ArrayList<Double> costUtilities = MainActivity.costUTILITY;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_particle);
particles = (EditText) findViewById(R.id.particles);
iterations = (EditText) findViewById(R.id.iterations);
userSol = (EditText) findViewById(R.id.solution);
userBatt = (EditText) findViewById(R.id.battery);
pd = null;
runPSOButton();
}
#Override
public void onPause(){
super.onPause();
if(pd != null)
pd.dismiss();
}
public class runTests extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) { //sort this out
results = runTest("CustomUseCase"); //i only want to run this one!!!
return null;
}
#Override
protected void onPostExecute(Void v) {
if (results != null && results.length > 0 && results[0] != -1) {
loadIntent(results);
} //otherwise it will evaluate the next logic statement results[0] != -1 with no chance of NulLPointerException
}
#Override
protected void onPreExecute() {
pd = ProgressDialog.show(ParticleActivity.this, "Busy", "Algorithm is currently executing");
pd.setCancelable(true);
pd.show();
}
}
public void runPSOButton() {
final Button runPSO = (Button) findViewById(R.id.runpso);
runPSO.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
new runTests().execute();
}
});
}
public double[] runTest(String test) {
int noPart = Integer.parseInt(particles.getText().toString());
int noIter = Integer.parseInt(iterations.getText().toString());
return new TestFactory(noPart, noIter).getTest(test).test();
}
public void loadIntent(double[] result) {
double[] results = result;
Intent intent = new Intent(this, SolutionActivity.class);
intent.putExtra(EXTRA_MESSAGE, results);
startActivity(intent);
}
public double setBatteryCost(){
battery = Double.parseDouble(userBatt.getText().toString());
return battery;
}
public double getBatteryCost(){return setBatteryCost();}
public double setUserSolution(){
solution = Double.parseDouble(userSol.getText().toString());
return solution;
}
public double getUserSolution(){return setUserSolution();}
}
Can someone explain whats happening? New to Android Studio and have been developing for only 3 months in Java, so for any solutions can I kindly request an explanation for it too? Much appreciated thank you
UPDATE:
Here is my mainActivity...
public class MainActivity extends AppCompatActivity {
//declare variables
EditText name;
EditText data;
EditText wlan;
EditText utility;
Button addservice;
ListView lv;
ListView lv2;
ListView lv3;
ListView lv4;
public ArrayList<String> servicenames;
public ArrayList<String> dimensions;
public ArrayList<Double> costDATA;
public ArrayList<Double> costWLAN;
public ArrayList<Double> costUTILITY;
ArrayAdapter<String> namesAdapter;
ArrayAdapter<Double> dataAdapter;
ArrayAdapter<Double> wlanAdapter;
ArrayAdapter<Double> utilityAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//map the components to the variables
name = (EditText) findViewById(R.id.servicename);
data = (EditText) findViewById(R.id.data);
wlan = (EditText) findViewById(R.id.wlan);
utility = (EditText) findViewById(R.id.utility);
addservice = (Button) findViewById(R.id.addservice);
lv = (ListView) findViewById(R.id.lv);
lv2 = (ListView) findViewById(R.id.lv2);
lv3 = (ListView) findViewById(R.id.lv3);
lv4 = (ListView) findViewById(R.id.lv4);
//create arraylists for each component
servicenames = new ArrayList<String>();
dimensions = new ArrayList<String>();
costDATA = new ArrayList<Double>();
costWLAN = new ArrayList<Double>();
costUTILITY = new ArrayList<Double>();
//create adapters to pass on the arraylist
namesAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, servicenames);
dataAdapter = new ArrayAdapter<Double>(MainActivity.this, android.R.layout.simple_list_item_1, costDATA);
wlanAdapter = new ArrayAdapter<Double>(MainActivity.this, android.R.layout.simple_list_item_1, costWLAN);
utilityAdapter = new ArrayAdapter<Double>(MainActivity.this, android.R.layout.simple_list_item_1, costUTILITY);
//display each arraylist in the listviews
lv.setAdapter(namesAdapter);
lv2.setAdapter(wlanAdapter);
lv3.setAdapter(dataAdapter);
lv4.setAdapter(utilityAdapter);
namesAdapter.notifyDataSetChanged();
dataAdapter.notifyDataSetChanged();
wlanAdapter.notifyDataSetChanged();
utilityAdapter.notifyDataSetChanged();
dimensions.add("DATA");
dimensions.add("WLAN");
onClickBtn();
}
public void onClickBtn() { //when user clicks button, the user input is added to the listview, and cleared for the next service
addservice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String namesOfService = name.getText().toString(); //user input for service names
String costOfData = data.getText().toString(); //user input for data costs
String costOfWLAN = wlan.getText().toString(); //user input for wlan costs
String costOfUtility = utility.getText().toString(); //user input for utility costs
Double doubleWLAN = Double.parseDouble(costOfWLAN); //convert user input into double
Double doubleData = Double.parseDouble(costOfData);
Double doubleUtility = Double.parseDouble(costOfUtility);
costDATA.add(doubleData); //add the double costs to each resource arraylist
costWLAN.add(doubleWLAN);
costUTILITY.add(doubleUtility);
servicenames.add(namesOfService);
dimensions.add(namesOfService);
namesAdapter.notifyDataSetChanged();
dataAdapter.notifyDataSetChanged();
wlanAdapter.notifyDataSetChanged();
utilityAdapter.notifyDataSetChanged();
name.setText(""); //empty the edit text fields when button is clicked
wlan.setText("");
data.setText("");
utility.setText("");
}
});
}
public void nextButton(View view) //next button, onto the next activity
{
Intent intent = new Intent(MainActivity.this, ParticleActivity.class);
startActivity(intent);
}
public int getDimensions(){ return dimensions.size();}
public ArrayList<String> getElements(){ return servicenames;}
public ArrayList<Double> getCostDATA(){;return costDATA;}
public ArrayList<Double> getCostWLAN(){return costUTILITY;}
public ArrayList<Double> getCostUTILITY(){return costUTILITY;}
}
As you can see, the arraylists that store the user input is accessible using getters and setters rather than setting the arraylists static (which I did before). I access these arraylists in another class called CustomUseCase and CustomService. Here is the code for customUseCase:
public class CustomUseCase extends Test {
MainActivity mainActivity = new MainActivity();
ParticleActivity particleActivity = new ParticleActivity();
private int numberOfDimensions = mainActivity.getDimensions();
private ArrayList<Double> costData = mainActivity.getCostDATA(); //costs that the user enters for each resource
private ArrayList<Double> costWlan = mainActivity.getCostWLAN();
private ArrayList<Double> costUtilities = mainActivity.getCostUTILITY();
private double batteryCost = particleActivity.getBatteryCost();
private int maxIter;
private int noParticles;
public CustomUseCase(int noParticles, int maxIterations) {
this.noParticles = noParticles;
this.maxIter = maxIterations;
}
#Override
public double[] test() {
long max = 10000; //maximum number of iterations, override //2 bits for the WLAN/DATA and the rest for the amount of services the user inputs
double[] results = new double[numberOfDimensions]; //new array of results with numOfBits as number of elements
for (int i = 1; i <= max; i++) {
BinaryPso bpso = new BinaryPso(noParticles,
numberOfDimensions);
ParticleActivity getUserInput = new ParticleActivity();
CustomService customService =
new CustomService(batteryCost, costData, costWlan, costUtilities);
long start = System.currentTimeMillis(); //start time
bpso.setSolution(getUserInput.getUserSolution()); //changed this to user selection
bpso.optimize(maxIter, customService, true);
this.found += (bpso.getFound() ? 1 : 0);
this.iterations += bpso.getSolIterations(); //use the method in bpso to get number of iterations taken
long end = System.currentTimeMillis() - start; //end time minus start time
this.sumTimes += end; //override the time spent variable
System.out.println("P-value: " + Particle.getValue(Particle.bestGlobal()));
System.out.println("P-bitCombo: " + Arrays.toString(Particle.bestGlobal()));
System.out.println("P-goodness: " + customService.getGoodness(Particle.bestGlobal()));
}
System.out.println("Time: " + sumTimes / max);
System.out.println("Iterations: " + iterations / max);
System.out.println("Success Rate: " + found);
boolean[] bestCombo = Particle.bestGlobal();
for (Boolean b : bestCombo) {
System.out.print(b + " ");
}
System.out.println();
results[0] = sumTimes / max;
results[1] = iterations / max;
results[2] = found;
return results;
}
public static List<Boolean> getBestComboArray() { //method to get best global array
boolean[] bestCombo = Particle.bestGlobal(); //calculate best global
List<Boolean> bestCombi = new ArrayList<>(bestCombo.length);
for (int x = 0; x < bestCombo.length; x++) {
bestCombi.add(bestCombo[x]);
}
return bestCombi;
}
}
And here is my CustomService class:
public class CustomService implements Goodness {
MainActivity mainActivity = new MainActivity();
private int numOfDimensions = mainActivity.getDimensions();
private ArrayList<String> serviceNames = mainActivity.getElements();
private ArrayList<Double> costData = mainActivity.getCostDATA();
private ArrayList<Double> costWlan = mainActivity.getCostWLAN();
private ArrayList<Double> costUtilities = mainActivity.getCostUTILITY();
private double batteryCost;
public void setBatteryCost(double batteryCost) {
this.batteryCost = batteryCost;
}
public CustomService(double batteryCost, ArrayList<Double> costData, ArrayList<Double> costWlan,
ArrayList<Double> costUtilities) {
if (costUtilities == null || costUtilities.size() < 1 || costData.size() < 1 || costWlan.size() < 1) {
throw new RuntimeException("Please add atleast 1 cost to Data, WLAN and Utility");
}
this.batteryCost = batteryCost; //make sure you add battery field to UI, user enters battery level
this.costData = costData;
this.costWlan = costWlan;
this.costUtilities = costUtilities;
}
public double getGoodness(boolean[] bits) {
double utility = 0.0;
double rcost = 0.0;
ArrayList<Double> resourceCost = new ArrayList<Double>();
Collections.sort(costUtilities); //sort the costUtilities arraylist
double maxValue = Collections.max(costUtilities); //get the maximum value from the costUtilities arraylist
if(bits[0] && bits[1]){
return -500;
}
if(!bits[0] || bits[1]){
return -1000;
}
for(int x = 1; x < numOfDimensions; x++){
if(bits[x] == costUtilities.contains(maxValue)){
return -1900;
}
}
if (bits[0]) {
resourceCost = costData;
} else if (bits[1]) {
resourceCost = costWlan;
}
for (int i = 2; i <= serviceNames.size(); i++) { //if i = 2, 2<=4
if (bits[i]) {
utility += costUtilities.get(i-2);
rcost += resourceCost.get(i-2);
}
}
if (rcost < batteryCost) {
return utility;
}
return utility * 0.50;
}
}
you can not update UI items on nonUIThread.
search usage of runOnUiThread on google.
call your method in runOnUiThread().
#Override
protected Void doInBackground(Void... params) { //sort this out
runOnUiThread (new Runnable() {
public void run() {
results = runTest("CustomUseCase");
}
}
return null;
}
This explains all: "Can't create handler inside thread that has not called Looper.prepare()" and it seems your TestFactory() method creates a Handler without a Looper.
Inside a secondary Thread a Handler should be like this
....
Looper.prepare();
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// do work with received messages
}
};
Looper.loop();
....
More info : What is the purpose of Looper and how to use it?

Categories

Resources