i am trying to create group chat android application and used Websocket server written in php. this server work fine on Web browser but when i try to use it in android application application disconnect as soon as it connects.
here Android code:
public class MainActivty extends Activity{
private WebSocketClient mWebSocketClient;
private ListView mMessageListView;
private ArrayAdapter<String> mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_layout);
mMessageListView=(ListView)findViewById(R.id.listView);
mAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
mMessageListView.setAdapter(mAdapter);
connectWebSocket();
}
private void connectWebSocket(){
URI uri;
try {
uri=new URI("ws://192.168.0.102:9000");
mWebSocketClient=new WebSocketClient(uri){
#Override
public void onOpen(ServerHandshake serverHandshake) {
}
#Override
public void onMessage(String s) {
}
#Override
public void onClose(int i, String s, boolean b) {
}
#Override
public void onError(Exception e) {
}
};
mWebSocketClient.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
}
private void Append_Message(String log){
mAdapter.add(log);
mAdapter.notifyDataSetChanged();
}
}
server console:
server console shows client activity
when i rewrite this code using https://github.com/pavelbucek/tyrus-client-android-test i think i could not satisfied full requirement of previous library that i used. but tutorial on this link have solved my problem.
Related
I have added a simple non drop-in paypal integration in sandbox mode to my app. Here is a test activity with a single "Pay" button:
public class PaypalPaymentAcivity extends Activity implements PaymentMethodNonceCreatedListener {
private BraintreeFragment mBraintreeFragment;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_paypal);
findViewById(R.id.payButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startPayment();
}
});
}
private void startPayment() {
try {
mBraintreeFragment = BraintreeFragment.newInstance(this, "...");
PayPalRequest request = new PayPalRequest("1")
.currencyCode("USD")
.intent(PayPalRequest.INTENT_AUTHORIZE);
PayPal.requestOneTimePayment(mBraintreeFragment, request);
} catch (InvalidArgumentException e) {
e.printStackTrace();
}
}
#Override
public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) {
}
}
However once the PayPal browser window comes up after clicking the buttons it just keeps popping up over and over, and never returns to my activity.
Anyone had a successful integration like this?
I'm working with neura sdk in order to detect current data of a user(where he/she is, where were they 10 min ago etc).
I want to login to their api, and authenticate my user, however - when i call NeuraApiClient.authenticate(...) nothing happens.
I followed neura documentations, but still - nothing happens.
Here's my code :
public class MainActivity extends AppCompatActivity {
private ArrayList<Permission> mPermissions;
private AuthenticationRequest mAuthenticateRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Builder builder = new Builder(this);
NeuraApiClient neuraApiClient = builder.build();
neuraApiClient.setAppUid(getResources().getString(R.string.app_uid));
neuraApiClient.setAppSecret(getResources().getString(R.string.app_secret));
neuraApiClient.connect();
fetchPermissions(neuraApiClient);
neuraApiClient.authenticate(100, mAuthenticateRequest);
}
private void fetchPermissions(final NeuraApiClient client) {
client.getAppPermissions(new GetPermissionsRequestCallbacks() {
#Override
public void onSuccess(final List<Permission> permissions) throws RemoteException {
runOnUiThread(new Runnable() {
#Override
public void run() {
mPermissions = new ArrayList<>(permissions);
mAuthenticateRequest = new AuthenticationRequest();
mAuthenticateRequest.setAppId(client.getAppUid());
mAuthenticateRequest.setAppSecret(client.getAppSecret());
mAuthenticateRequest.setPermissions(mPermissions);
}
});
}
#Override
public void onFailure(Bundle resultData, int errorCode) throws RemoteException {
}
#Override
public IBinder asBinder() {
return null;
}
});
}
}
getAppPermissions is an asynchronous call, and the data is fetched on GetPermissionsRequestCallbacks.
in GetPermissionsRequestCallbacks you're initiating mAuthenticateRequest which is in use of authenticate method.
Which means you have to wait untill onSuccess of GetPermissionsRequestCallbacks is called, and only then you can call
neuraApiClient.authenticate(100, mAuthenticateRequest);
Basically, if you don't wait for mAuthenticateRequest to be fetched, you authenticate with mAuthenticateRequest = null, and neuraApiClient.authenticate(..) fails.
You can do something like this : call authenticate when the results are received -
private void fetchPermissions(final NeuraApiClient client) {
client.getAppPermissions(new GetPermissionsRequestCallbacks() {
#Override
public void onSuccess(final List<Permission> permissions) throws RemoteException {
runOnUiThread(new Runnable() {
#Override
public void run() {
mPermissions = new ArrayList<>(permissions);
mAuthenticateRequest = new AuthenticationRequest();
mAuthenticateRequest.setAppId(client.getAppUid());
mAuthenticateRequest.setAppSecret(client.getAppSecret());
mAuthenticateRequest.setPermissions(mPermissions);
client.authenticate(100, mAuthenticateRequest);
}
});
}
...
});
}
I am using one android project as a reference for my understanding,There i find this interface as:
public interface HttpCallback<T> {
void onSuccess(T var1);
void onHttpError(ResponseStatus var1);
}
I got reference to this interface in Main Activity which implements HttpCallback<UserDetails>.
My question is,am not able get what is T? Please suggest me what is T stands for in HttpCallback<T>.
//Main Activity Code:
public class MainActivity extends HttpCallback<UserDetails> {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
HttpCallback<UserDetails> userDetailCallback = new HttpCallback<UserDetails>() {
#Override
public void onSuccess(UserDetails userDetails) {
setProgressVisibility(R.id.button_find_user, View.INVISIBLE);
if(!"ok".equals(addressDetails.errorMsg)){
showErrorMessage("UserDetails Error", userDetails.errorMsg);
return;
}
}
#Override
public void onHttpError(ResponseStatus responseStatus) {
setProgressVisibility(R.id.button_find_user, View.INVISIBLE);
showErrorMessage("Internet Connection Problem", "Please check your Internet connection then try again.");
}
};
}
Thank you.
T is nothing but a Type....Its Generics..saying that it can accept any object of that Type...Read Generics in java for more details
I am new to Android dev and have the following design question when one makes an asnyc rest web request. In my main activity I have a button that does the request using an async task:
public class MainActivity extends ActionBarActivity {
final Context context=this;
.......
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
Button btn = (Button)findViewById(R.id.myshowbutton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WebRequest wr=new WebRequest(view.getRootView());
wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
}
});
}
Th async task class which is in a separate java file:
public class WebRequest extends AsyncTask<String, String, String> {
private View view;
public WebRequest(View v) {
this.view = v;
}
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
EditText et=(EditText)view.findViewById(R.id.editText);
et.setText(result);
}
}
As you can see I am setting the EditText box to the JSON which is returned. I pass a reference of the root view to my WebRequest class so that I can get hold of the EditText box.
Is there a better way of doing this? It does not seem very elegant. Perhaps a nice libary for web requests?
This way works fine, and it is good to know how to write this. There are a couple of things you can do to improve this, and there is also a library you can use to greatly simplify your code.
Option 1: Improve your code
First, you can use a Callback to set the text in the EditText in your Activity, instead:
Change these lines in WebRequest:
private View view;
public WebRequest(View v) {
this.view = v;
}
to
public interface Callback {
public void call(String result);
}
private Callback callback;
public WebRequest(Callback c) {
this.callback = callback;
}
Then in onPostExecute, just call:
callback.call(result);
Now, when you start the web service, your call will look like this:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WebRequest wr=new WebRequest(new Callback() {
#Override
public void call(String result) {
((EditText)view.findViewById(R.id.editText)).setText(result);
}
});
wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
}
});
Option 2: Use a library
If, however, you do want to use a library, I recommend droidQuery. Using this, you can simplify your code from this:
Button btn = (Button)findViewById(R.id.myshowbutton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WebRequest wr=new WebRequest(view.getRootView());
wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
}
});
to:
$.with(this, R.id.myshowbutton).click(new Function() {
#Override
public void invoke($ d, Object... args) {
$.ajax(new AjaxOptions().url("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1").success(new Function() {
#Override
public void invoke($ d, Object... args) {
$.with(MyActivity.this, R.id.editText).text(args[0].toString());
}
}));
}
});
and you no longer need your WebRequest class.
The main problem with handing in a reference to a view into your AsyncTask is what happens when the Activity is destroyed and recreated for example in case of an orientation change (turning the device). In this case you can leak a reference to the Activity, which can get expensive memory-wise.
There are a couple of libraries around that try to help with this kind of problems. Maybe have a look at RoboSpice also.
If you want to decouple the EditText from your WebRequest, consider making a callback interface for your MainActivity to implement.
MainActivity.java
public class MainActivity extends ActionBarActivity implements WebRequestCallback {
...
#Override
public void handleStringResult(String result) {
btn.setText(result);
}
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WebRequest wr = new WebRequest(this);
wr.execute("http://www.cheesejedi.com/rest_services/get_big_cheese?level=1");
}
});
}
...
}
WebRequestCallback.java
public interface WebRequestCallback {
public void handleStringResult(String result);
}
WebRequest.java
public class WebRequest extends AsyncTask<String, String, String> {
private WebRequestCallback callback;
public WebRequest(WebRequestCallback callback) {
this.callback = callback;
}
#Override
protected String doInBackground(String... uri) {
...
}
#Override
protected void onPostExecute(String result) {
callback.handleStringResult(result);
}
}
Also, while I have not used it myself, I have heard good things about Ion if you are looking for a more robust Android networking library.
I have my application that is using Koush's web-sockets/Socket.IO library for just one fragment. (https://github.com/koush/android-websockets)
I am having some problems getting the Socket.IO client to work correctly with the fragment lifecycle and its threads.
For the most part, my fragment looks like this:
public class ScoresFragment extends SherlockFragment {
public SocketIOClient socket;
#Override
public void onCreate(Bundle savedInstanceState) {
createSocket();
super.onCreate(savedInstanceState);
}
#Override
public void onPause() {
try {
this.socket.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
super.onPause();
}
#Override
public void onResume() {
socket.connect();
super.onResume();
}
public void createSocket() {
this.socket = new SocketIOClient(URI.create("http://blah-url"), new SocketIOClient.Handler() {
//Required methods here
}
}
#Override
public void onCreateView(LayoutInflater inflater, ViewGroup group, Bundle savedInstanceState) {
//Everything for the layout here
}
}
And the error I'm getting is in the onPause() method when I try to disconnect the socket.
The socket connects just fine, but as soon as I change fragments I get a crash.
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.codebutler.android_websockets.SocketIOClient.cleanup(SocketIOClient.java:195)
at com.codebutler.android_websockets.SocketIOClient.disconnect(SocketIOClient.java:188)
at edu.bgsu.asf.athletics.fragments.ScoresFragment.onPause(ScoresFragment.java:14)
I read somewhere that I may have to be wary of threads and I may have to use a handler for this, but the git page for web-sockets doesn't allude to having to use anything like that. Thanks in advance.
EDIT:
The sections of SocketIOClient.java:
public void disconnect() throws IOException {
cleanup(); //Line 188
}
/////////////////////////////////////////////
private void cleanup() {
mClient.disconnect();
mClient = null;
mSendLooper.quit(); //Line 195
mSendLooper = null;
mSendHandler = null;
}
Create static socket and connect it in parent activity in which your fragment lies. After that when your fragment created subscribe via emit method. And close socket in onStop method of parent activity. Follow these instructions to make it work.