Mark wallest Mark wallest - 3 months ago 10
Java Question

Can't get a fixed value on a final hashmap in android

I am developing a an android app that uses service discovery over wifi direct,based on the provided google sample code, the problem is i can't get a fixed value of the advertised TXT record even though i'm using a final hashmap to store the value, the Hashmap is modified every time the onDnsSdTxtRecordAvailable callback is called, even though i'm using a final hashmap declared globally to store the first value, it gets replaced by null. here is the code i'm using. thanks

private WifiP2pManager manager;

private final IntentFilter intentFilter = new IntentFilter();
private Channel channel;
private BroadcastReceiver receiver = null;
private WifiP2pDnsSdServiceRequest serviceRequest;
private TextView statusTxtView;
private TextView services;
private Button register;
private Button broadcast;
private LocationManager locationManager;
final HashMap<String, String> buddies = new HashMap<String, String>();
private TextView locationTxt;
public String value1;
private Button loc;
private final String name = new String();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

statusTxtView = (TextView) findViewById(R.id.status);
services = (TextView) findViewById(R.id.services);
register = (Button) findViewById(R.id.discover);
broadcast = (Button) findViewById(R.id.bd);
locationTxt = (TextView)findViewById(R.id.location);

loc = (Button)findViewById(R.id.loc);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter
.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter
.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
startRegistrationAndDiscovery();
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startRegistrationAndDiscovery();
}
});

broadcast.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
discoverService();
}
});

loc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
doIt();
}
});


}


@Override
public void onResume() {
super.onResume();
receiver = new MyReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
}

@Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}

public void appendStatus(String status) {
String current = statusTxtView.getText().toString();
statusTxtView.setText(current + "\n" + status);
}

//service discvery handllng methods
private void startRegistrationAndDiscovery() {
Map<String, String> record = new HashMap<String, String>();
record.put(TXTRECORD_PROP_AVAILABLE, "visible");
WifiP2pDnsSdServiceInfo service = WifiP2pDnsSdServiceInfo.newInstance(
SERVICE_INSTANCE, SERVICE_REG_TYPE, record);
manager.addLocalService(channel, service, new ActionListener() {

@Override
public void onSuccess() {
appendStatus("Added Local Service");
}

@Override
public void onFailure(int error) {
appendStatus("Failed to add a service");
}
});

discoverService();

}

private void discoverService() {
/*
* Register listeners for DNS-SD services. These are callbacks invoked
* by the system when a service is actually discovered.
*/

manager.setDnsSdResponseListeners(channel,
new DnsSdServiceResponseListener() {

@Override
public void onDnsSdServiceAvailable(String instanceName,
String registrationType, WifiP2pDevice srcDevice) {

// A service has been discovered. Is this our app?

if (instanceName.equalsIgnoreCase(SERVICE_INSTANCE)) {

// update the UI and add the item the discovered
// device.

/* WiFiP2pService service = new WiFiP2pService();
service.device = srcDevice;
service.instanceName = instanceName;
service.serviceRegistrationType = registrationType;*/
//put data to textview here
services.setText(srcDevice.status+" Instance name " + instanceName + " type " + registrationType);
Log.d(TAG, "onBonjourServiceAvailable "
+ instanceName);
Http_client http_client = new Http_client(SERVICE_INSTANCE);
appendStatus("data sent to server successfully");


}

}
}, new DnsSdTxtRecordListener() {

/**
* A new TXT record is available. Pick up the advertised
* buddy name.
*/
@Override
public void onDnsSdTxtRecordAvailable(String fullDomainName, Map<String, String> record,WifiP2pDevice device) {
Log.d(TAG, device.deviceName + " is " + record.get(TXTRECORD_PROP_AVAILABLE));
buddies.put("mm",record.get(TXTRECORD_PROP_AVAILABLE));

Toast.makeText(getBaseContext(),record.get(TXTRECORD_PROP_AVAILABLE),Toast.LENGTH_LONG).show();
//
}
});

// After attaching listeners, create a service request and initiate
// discovery.
serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
manager.addServiceRequest(channel, serviceRequest,
new ActionListener() {

@Override
public void onSuccess() {
appendStatus("Added service discovery request");
}

@Override
public void onFailure(int arg0) {
appendStatus("Failed adding service discovery request");
}
});
manager.discoverServices(channel, new ActionListener() {

@Override
public void onSuccess() {
appendStatus("Service discovery initiated");
}

@Override
public void onFailure(int arg0) {
appendStatus("Service discovery failed");

}
});
}
public void doIt(){
buddies.put("mm","value1");
Toast.makeText(getBaseContext(),buddies.get("mm"),Toast.LENGTH_LONG).show();
buddies.put("mm","value2");
Toast.makeText(getBaseContext(),buddies.get("mm"),Toast.LENGTH_LONG).show();

}

Answer

A final variable will not help you, as I have commented. Based on your question, what you need to do is to always check if the value is set in your hashmap, before saving the new returned variable. Something like

if (!buddies.containKey("mm"))
    buddies.put("mm", .....)