I am a beginner in android development, looking for how to make it verifiable code for server connection, ie if the user does not have a connection, and it connects to my server, in this case an error message will show "connection error" or nothing affair.
thank you for helping me :)
upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File f = new File(path);
Future uploading = Ion.with(MainActivity.this)
.load("http://x.x.x.x/upload_file") //->how to change this code for to verify the connection
.setMultipartFile("image",f)
//asJsonObject()
.asString()
.withResponse()
.setCallback(new FutureCallback<Response<String>>() {
#Override
public void onCompleted(Exception e, Response<String> result) {
try {
JSONObject jobj = new JSONObject(result.getResult());
Toast.makeText(getApplicationContext(), jobj.getString("response"), Toast.LENGTH_SHORT).show();
} catch (JSONException e1) {
e1.printStackTrace();
}
}
});
}
});
Based on the information you provided, I suggest you refer to this answer. It shows you how to check if the device is connected to the internet.
After checking if a connection is available or not, you can continue normally, or display an alert message (i.e. via Toast or Snackbar) to inform the user that no connection can be made.
Hope this helps.
Related
I'm developing an android app that uses Ion library for requesting API data.
Here is how I'm requesting
void getData(final OnDbData listener) {
Ion.with(context)
.load(BASE_URL + url)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject jsonObject) {
if (e == null) {
listener.OnDbDataReceived(jsonObject, false);
} else {
Log.d("DBDATA-IonDB", e.getMessage() + "");
listener.OnDbDataReceived(jsonObject, true);
}
}
});
}
I'm successfully login in to my application but when I send request for other data Ion library is opening new connection and API is returning UNAUTHORIZED error. From the server side the session time out is set to 2 hours. One more thing that is confusing me is that when I use my local server (API in my computer) it is working correctly but when I connect to remote server It is being disconnected. If you know how to handle this please help!
I am working on chat application and using ejabberd saas edition as xmpp server for it. I am using smack library ver-4.2.3. To keep connection alive I am using ping manager. Here is the code I am using:
ReconnectionManager.getInstanceFor(AppController.mXmpptcpConnection).enableAutomaticReconnection();
ServerPingWithAlarmManager.onCreate(context);
ServerPingWithAlarmManager.getInstanceFor(AppController.mXmpptcpConnection).setEnabled(true);
ReconnectionManager.setEnabledPerDefault(true);
//int i = 1;
// PingManager.setDefaultPingInterval(i);
PingManager.getInstanceFor(AppController.mXmpptcpConnection).setPingInterval(300);
I am using sticky-service also for connection, but when I keep my application open (ideal-state) for 15-20 mins then the connection is lost, so I am using ping manger to resolve this issue.
Is there any other better way of doing it or ping manager is the only option?
Insted of pinging chat server constantly, you better to use ConnectionListener() in smack library. You need to use something like this:
XMPPTCPConnection connection;
// initialize your connection
// handle the connection
connection.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection connection) {
}
#Override
public void authenticated(XMPPConnection connection, boolean resumed) {
}
#Override
public void connectionClosed() {
// when the connection is closed, try to reconnect to the server.
}
#Override
public void connectionClosedOnError(Exception e) {
// when the connection is closed, try to reconnect to the server.
}
#Override
public void reconnectionSuccessful() {
}
#Override
public void reconnectingIn(int seconds) {
}
#Override
public void reconnectionFailed(Exception e) {
// do something here, did you want to reconnect or send the error message?
}
});
Best way to keep the alive connection with XMPP server you should reconnect after every network change.
Like this:
public class NetworkStateChangeReceiver extends BroadcastReceiver {
private Context context;
private static NetworkStateChangeListener mListener;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
try {
if (!ApplicationHelper.isInternetOn(context)) {
if (mListener != null) {
mListener.OnInternetStateOff();
}
return;
} else {
XMPPTCPConnection xmpptcpConnection = XmppConnectionHelper.getConnection();
if(!StringHelper.isNullOrEmpty(new SessionManager(context).getAuthenticationToken())) {
Intent XmppConnectionServicesIntent = new Intent(context, XmppConnectionServices.class);
context.stopService(XmppConnectionServicesIntent);
context.startService(XmppConnectionServicesIntent);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//to initialize NetworkStateChangeListener because null pointer exception occurred
public static void setNetworkStateChangeListener(NetworkStateChangeListener listener) {
mListener = listener;
}
}
Yes, There is. Few points before the solution
Make your service STICKY, with a foreground notification as it would be necessary to work on or after Build.VERSION_CODES.O
This sticky service, you should start on every boot, via BOOT_COMPLETED intent action and starting this foreground service from receiver.
Yes, Now it is always there, Now you can always go for checking your connection
You can use google-volley for making connections and even you can communicate using it.
There is no good documentation on it, But i like it much, as it works flawlessly once added the dependency successfully.
Adding this dependency will take time as i said no good documentation..
For communication :
StringRequest stringRequest = new StringRequest(Request.Method.POST, "https://oniony-leg.000webhostapp.com/user_validation.php",
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
serverKeyResponse = response;
// get full table entries from below toast and writedb LICENSETABLE
//Toast.makeText(getActivity(),response,Toast.LENGTH_LONG).show();
showKeyResponse();
// Log.d("XXXXXX XXXXX", "\n SUCCESS : "+serverKeyResponse);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
serverKeyResponse = error.toString();
// show below toast in alert dialog and it happens on slow internet try again after few minutes
// on ok exit app
// Toast.makeText(getActivity(),error.toString(),Toast.LENGTH_LONG).show();
showKeyResponse();
//Log.d("YYYYYY YYYYYY", "\n FAILURE : "+serverKeyResponse);
}
})
{
#Override
protected Map<String,String> getParams()
{
Map<String,String> params = new HashMap<String, String>();
params.put("INPUT",LicenseKey.getText().toString());
params.put("USER", MainActivity.deviceid);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
You just have to reply ECHO "SUCCESS" from server using a php ( or whatever server side language you like ). In response check for SUCCESS presence, any any other cases.., Use other KEYWORDS YOU LIKE. You can handle Server response errors too. Even you can communicate from android in request - response handshake. But you have to implement few handshake on your own.
I Hope, It helps...
Use the ReconnectionManager class as described here.
ReconnectionManager manager = ReconnectionManager.getInstanceFor(connection);
manager.enableAutomaticReconnection();
It will automatically re-connect when necessary.
I am posting this question because I couldn't find any satisfactory answers online.
I am developing an Android App in which the data is fetched from the external server(in my case it's localhost MySQL server now) and displayed on the screen.
However, the constraint with this is that the person should always be connected to the internet to get all the data which can be viewed on the phone.
Now, what I would like to achieve is, once the data has been retrieved from the external server it should be stored on the device so that even though the user opens up the app without being connected to the internet, the previously fetched data should be showed to him.
In other words, I would like to have the offline capability.
How can I achieve this?
I have implemented the same for my app. Have a look at the code and you will understand how to do it. I have used Retrofit for the same. I have checked if the nursejson which is in sharedpreference is null. if it is null then continue further to hit API if not then load data from that sharedpreference.
To refresh the list, just check if you have internet connectivity and then delete that sharedpreference and call getnurse method again.
//After Oncreate
pref = getApplicationContext().getSharedPreferences("CachedResponse", 0);
editor = pref.edit();
editor.apply();
// Call getNurses method
getNurses();
//Method to get Nurses
public void getNurses() {
nurseJson = pref.getString("nurseJson", null);
if (nurseJson != null) {
progressBar.setVisibility(View.INVISIBLE);
gson = new Gson();
nurse = gson.fromJson(nurseJson, Nurse.class);
nurseList = nurse.getNurse();
namesArrayList.clear();
for (String nurses : nurseList) {
namesArrayList.add(nurses);
}
namesAdapter.notifyDataSetChanged();
} else {
Call<Nurse> call = apiInterface.getNursesList();
call.enqueue(new Callback<Nurse>() {
#Override
public void onResponse(Call<Nurse> call, Response<Nurse> response) {
progressBar.setVisibility(View.INVISIBLE);
onItemsLoadComplete();
if (response.isSuccessful()) {
nurse = response.body();
nurseJson = new Gson().toJson(nurse);
editor.putString("nurseJson", nurseJson);
editor.commit();
nurseList = nurse.getNurse();
namesArrayList.clear();
for (String nurses : nurseList) {
namesArrayList.add(nurses);
}
namesAdapter.notifyDataSetChanged();
} else {
utility.createSnackbar(coordinatorLayout, "Error Occurred, Please Try Again Later!");
}
}
#Override
public void onFailure(Call<Nurse> call, Throwable t) {
progressBar.setVisibility(View.INVISIBLE);
onItemsLoadComplete();
if (t.getLocalizedMessage() != null) {
if (t.getLocalizedMessage().contains("Unable to resolve host")) {
utility.createSnackbar(coordinatorLayout, "Please Check Internet Connection!");
} else {
utility.createSnackbar(coordinatorLayout, "Error Occurred, Please Try Again Later!");
}
} else {
utility.createSnackbar(coordinatorLayout, "Error Occurred, Please Try Again Later!");
}
}
});
}
}
I am trying to join a MultiUserChat using Smack on Android. Currently I can chat 1-on-1 perfectly fine, and I am connected to the server as I show online. I followed the examples provided here.
I have the following code to join a MultiUserChat (MUC).
final XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setUsernameAndPassword(user.getUsername(), user.getJabberPassword())
.setServiceName("app.buur.nu")
.setHost("app.buur.nu")
.setPort(5222)
.build();
AbstractXMPPConnection connection = new XMPPTCPConnection(config);
String room = "testroom";
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat muc = manager.getMultiUserChat(room + "#groups.app.buur.nu");
try {
muc.join(user.getUsername(), null, null, connection.getPacketReplyTimeout());
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
But this gives me
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 5000ms (~5s). Used filter: AndFilter: (FromMatchesFilter (full): testroom#groups.app.buur.nu/test, StanzaTypeFilter: org.jivesoftware.smack.packet.Presence).
I tried increasing the timeout to 10000 ms, but I still get a timeout. What could be wrong here? Creating 1-on-1 chats works fine and connection.isConnected()) returns True...
So it turns out that I get an error
<presence to="app.buur.nu/7c65be6" id="lgcSp-4" type="error"><x xmlns="http://jabber.org/protocol/muc"/><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://www.igniterealtime.org/projects/smack" ver="os2Kusj3WEOivn5n4iFr/ZEO8ls="/><error code="401" type="auth"><not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></presence>
Basically, the authentication is not completed when I am attempting to join the room. Can a listener be added to receive an update when the authentication has been completed? I saw https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/SASLAuthentication.html#authenticate%28java.lang.String,%20javax.security.auth.callback.CallbackHandler%29 but implementing my own authentication mechanism seems a little overkill...
Isn't there a onAuthenticationCompletedListener or something?
It turns out there is no need to implement the SASLMechanism, you can do the following:
connection.addConnectionListener(new ConnectionListener() {
#Override
public void connected(XMPPConnection connection) {
}
#Override
public void authenticated(XMPPConnection connection, boolean resumed) {
joinMUCRooms();
}
#Override
public void connectionClosed() {
}
#Override
public void connectionClosedOnError(Exception e) {
}
#Override
public void reconnectionSuccessful() {
}
#Override
public void reconnectingIn(int seconds) {
}
#Override
public void reconnectionFailed(Exception e) {
}
});
The error no longer shows now, while keeping the code "fairly" clean.
Does the room exist? If not then you need to create it first, using create() and sending a instant form. You should also report to the openfire developers that the MUC error presence is missing the 'from' attribute.
I make a app with FacebookSDK,and it can fetch friendList in android 4.4,but it didn't work in android5.0.
public static boolean isLogin(){
if(AccessToken.getCurrentAccessToken() == null){
Log.d("fb", "fb not login");
return false;
}else if(AccessToken.getCurrentAccessToken().isExpired()){
Log.d("fb", "fb token expired");
return false;
}
return true;
}
I debug this ,and found the accessToke is right : {AccessToken token:ACCESS_TOKEN_REMOVED permissions:[public_profile, user_friends]}
public static void makeInviteFriendsRequest(final String msg) {
// Make an API call to get user data and define a
// new callback to handle the response.
SuspensionButton.getInstance().getGameActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Log.d("fb","fb makeInviteFriendsRequest run");
GraphRequest request = GraphRequest.newMyFriendsRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONArrayCallback() {//Callback
#Override
public void onCompleted(JSONArray result, GraphResponse response) {
SuspensionButton.getInstance().removeLoading();
InviteGen.fbJAarry=result;
SuspensionButton.getInstance().showBoardActivity("1","");
}
});
request.executeAsync();
}
});
}
Then I debug at "newMyFriendsRequest",and found it's the same accessToke,have same id and content.But the response is occur an error:An active access token must be used to query information about the current user.
Does anyone know what am I missed?
Apologize for my English,hope I explain well.
I found my mistake finally.I edit the sdk code's 'MY_FRIENDS' attribute,change to 'me/invitable_friends?limit=50', and I remove the code that behind '?',then android 5.0 can get friends's data . But I don't know why,maybe someone can tell me.