I tried to write a "login" App using MVP model. And I use WAMP to build up my server. I'm sure that my php documents have no problem.
Here is the structure of my App:
enter image description here
And here are the files:
User.java
package com.example.android.login.mvp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);
initViews();
}
private void initViews()
{
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.clear();
}
});
}
#Override
public String getUserName()
{
return mEtUsername.getText().toString();
}
#Override
public String getPassword()
{
return mEtPassword.getText().toString();
}
#Override
public void clearUserName()
{
mEtUsername.setText("");
}
#Override
public void clearPassword()
{
mEtPassword.setText("");
}
#Override
public void showLoading()
{
mPbLoading.setVisibility(View.VISIBLE);
}
#Override
public void hideLoading()
{
mPbLoading.setVisibility(View.GONE);
}
#Override
public void toMainActivity(User user)
{
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}
#Override
public void showFailedError()
{
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
IUserBiz.java
package com.example.android.login.mvp.biz;
/**
* Created by zhy on 15/6/19.
*/
public interface IUserBiz
{
public void login(String username, String password, OnLoginListener loginListener);
}
OnLoginListener.java
package com.example.android.login.mvp.biz;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public interface OnLoginListener
{
void loginSuccess(User user);
void loginFailed();
}
UserBiz.java
package com.example.android.login.mvp.biz;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public class UserBiz extends AppCompatActivity implements IUserBiz
{
private User user;
private OnLoginListener loginListener;
#Override
public void login(final String username, final String password, final OnLoginListener mLoginListener)
{
user = new User();
user.setUsername(username);
user.setPassword(password);
user.setStatus(0);
loginListener = mLoginListener;
LoginAsyncTask task = new LoginAsyncTask();
String test1Url = getString(R.string.server_ip)+"/server/login.php";
task.execute(test1Url);
}
/**
* Update the UI with the given earthquake information.
*/
private void updateUi(User mUser) {
if (mUser.getStatus()==1)
{
loginListener.loginSuccess(user);
} else
{
loginListener.loginFailed();
}
}
private class LoginAsyncTask extends AsyncTask<String, Void, User> {
#Override
protected User doInBackground(String... urls) {
if (urls.length < 1 || urls[0] == null) {
return null;
}
// Perform the HTTP request for earthquake data and process the response.
User mUser = Utils.fetchEarthquakeData(urls[0],user);
return mUser;
}
#Override
protected void onPostExecute(User result) {
if(result==null){
return;
}
updateUi(result);
}
}
}
Utils.java
package com.example.android.login.mvp.biz;
import android.text.TextUtils;
import android.util.Log;
import com.example.android.login.mvp.bean.User;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
/**
* Utility class with methods to help perform the HTTP request and
* parse the response.
*/
public final class Utils {
/** Tag for the log messages */
public static final String LOG_TAG = Utils.class.getSimpleName();
/**
* Query the USGS dataset and return an {#link User} object to represent a single earthquake.
*/
public static User fetchEarthquakeData(String requestUrl, User user) {
// Create URL object
URL url = createUrl(requestUrl);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url, user);
} catch (IOException e) {
Log.e(LOG_TAG, "Error closing input stream", e);
}
// Extract relevant fields from the JSON response and create an {#link User} object
User earthquake = extractFeatureFromJson(jsonResponse);
// Return the {#link User}
return earthquake;
}
/**
* Returns new URL object from the given string URL.
*/
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(URL url, User user) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
String params="app_user_name="+user.getUsername()+'&'+"app_password="+user.getPassword();
OutputStream out=urlConnection.getOutputStream();
out.write(params.getBytes());//post提交参数
out.flush();
out.close();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return an {#link User} object by parsing out information
* about the first earthquake from the input earthquakeJSON string.
*/
private static User extractFeatureFromJson(String earthquakeJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(earthquakeJSON)) {
return null;
}
try {
JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);
// If there are results in the features array
if (baseJsonResponse.length() > 0) {
int status = baseJsonResponse.getInt("status");
// Create a new {#link User} object
User user=new User();
user.setStatus(status);
return user;
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
}
UserLoginPresenter.java
package com.example.android.login.mvp.presenter;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.biz.IUserBiz;
import com.example.android.login.mvp.biz.OnLoginListener;
import com.example.android.login.mvp.biz.UserBiz;
import com.example.android.login.mvp.view.IUserLoginView;
/**
* Created by zhy on 15/6/19.
*/
public class UserLoginPresenter {
private IUserBiz userBiz;
private IUserLoginView userLoginView;
public UserLoginPresenter(IUserLoginView userLoginView) {
this.userLoginView = userLoginView;
this.userBiz = new UserBiz();
}
public void login() {
userLoginView.showLoading();
userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
#Override
public void loginSuccess(final User user) {
userLoginView.toMainActivity(user);
userLoginView.hideLoading();
}
#Override
public void loginFailed() {
userLoginView.showFailedError();
userLoginView.hideLoading();
}
});
}
public void clear() {
userLoginView.clearUserName();
userLoginView.clearPassword();
}
}
IUserLoginView.java
package com.example.android.login.mvp.view;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public interface IUserLoginView
{
String getUserName();
String getPassword();
void clearUserName();
void clearPassword();
void showLoading();
void hideLoading();
void toMainActivity(User user);
void showFailedError();
}
UserLoginActivity.java
package com.example.android.login.mvp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);
initViews();
}
private void initViews()
{
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.clear();
}
});
}
#Override
public String getUserName()
{
return mEtUsername.getText().toString();
}
#Override
public String getPassword()
{
return mEtPassword.getText().toString();
}
#Override
public void clearUserName()
{
mEtUsername.setText("");
}
#Override
public void clearPassword()
{
mEtPassword.setText("");
}
#Override
public void showLoading()
{
mPbLoading.setVisibility(View.VISIBLE);
}
#Override
public void hideLoading()
{
mPbLoading.setVisibility(View.GONE);
}
#Override
public void toMainActivity(User user)
{
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}
#Override
public void showFailedError()
{
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
But I got something wrong like this:
enter image description here
I have no idea about it. How to solve it?
the issue is here
this.userBiz = new UserBiz();
UserBiz is an activity so activity gets their context when they are being started with Intent (by OS) but creating an object of an activity will not provide any contenxt hence the null exception at
#Override
public void login(final String username, final String password, final OnLoginListener mLoginListener)
{
user = new User();
user.setUsername(username);
user.setPassword(password);
user.setStatus(0);
loginListener = mLoginListener;
LoginAsyncTask task = new LoginAsyncTask();
String test1Url = getString(R.string.server_ip)+"/server/login.php";
// no context here due to new UserBiz
// getString required context
task.execute(test1Url);
}
Solution : you can use enums or static final constants to avoid context and also would be wise to substitute UserBiz as separate class instead of an activity
Following is "TCP SERVER" code, when any client connect first time the code is run very well, but once that client disconnect and again connect with TCP SERVER, than client connects successfully but can not send data.
How to detect client is disconnected with server?
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
public class MainActivity extends AppCompatActivity {
TextView tvStatus;
EditText etPort, etMsg, etTransmit;
Button btnListen, btnServerSend;
Handler UIHandler;
private int SERVERPORT1;
private InetAddress addr;
private ServerSocket serverSocket;
private Socket clientSocket = null;
private BufferedReader in;
private PrintWriter out;
// public static final int SERVERPORT = 3000;
private WifiManager wifiManager = null;
private WifiManager.WifiLock lock = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifi();
UIHandler = new Handler();
tvStatus = (TextView) findViewById(R.id.tvStatus);
etMsg = (EditText) findViewById(R.id.etMsg);
etTransmit = (EditText) findViewById(R.id.etTransmit);
etPort = (EditText) findViewById(R.id.etPort);
btnListen = (Button) findViewById(R.id.btnListen);
btnServerSend = (Button) findViewById(R.id.btnServerSend);
// ******************* Register controls end ******************************
btnListen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new ServerClass().execute(etPort.getText().toString());
}
});
}
public String getLocalIpAddress() throws Exception {
String resultIpv6 = "";
String resultIpv4 = "";
for (Enumeration en = NetworkInterface.getNetworkInterfaces();
en.hasMoreElements(); ) {
NetworkInterface intf = (NetworkInterface) en.nextElement();
for (Enumeration enumIpAddr = intf.getInetAddresses();
enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = (InetAddress) enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
if (inetAddress instanceof Inet4Address) {
resultIpv4 = inetAddress.getHostAddress().toString();
} else if (inetAddress instanceof Inet6Address) {
resultIpv6 = inetAddress.getHostAddress().toString();
}
}
}
}
return ((resultIpv4.length() > 0) ? resultIpv4 : resultIpv6);
}
private class ServerClass extends AsyncTask<String, Object, String> {
private String input;
#Override
protected String doInBackground(String... params) {
try {
SERVERPORT1 = Integer.parseInt(params[0]);
addr = InetAddress.getByName(getLocalIpAddress());
serverSocket = new ServerSocket(SERVERPORT1, 0, addr);
while (true) {
clientSocket = serverSocket.accept();
clientSocket.setTcpNoDelay(true);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
tvStatus.setText(clientSocket.getInetAddress().toString() + " Client connected");
Toast.makeText(MainActivity.this, "Server started...", Toast.LENGTH_SHORT).show();
}
});
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
if (!Thread.currentThread().isInterrupted()) {
input = in.readLine();
if (input != null) {
UIHandler.post(new updateUIThread1(input.toString()));
out.println("Received from client: " + input);
} else {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
new ServerClass().execute(etPort.getText().toString());
}
});
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
private class updateUIThread1 implements Runnable {
private String input = null;
public updateUIThread1(String input) {
this.input = input;
}
#Override
public void run() {
if (input.getBytes().length != 0) {
etMsg.append("\n" + input.toString());
Toast.makeText(MainActivity.this, "Answer: " + input, Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this, "Empty", Toast.LENGTH_SHORT).show();
}
}
}
}
Log shows like:
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read
04-22 12:57:05.799 10857-10931/com.chat.admin.clientserver I/System.out: [CDS]shutdownInput in read
read: unexpected EOF!
Do not create a new server if a client disconnects.
Instead you should have a loop so you can call .accept() again to wait for a new client.
I am using telegram API to develop my application. Here is the whole code.
app_info.java:
package com.example.mytelegram;
import org.telegram.api.engine.AppInfo;
public class app_info extends AppInfo {
public app_info(int apiId, String deviceModel, String systemVersion,
String appVersion, String langCode) {
super(apiId, deviceModel, systemVersion, appVersion, langCode);
// TODO Auto-generated constructor stub
}
MemoryApiState.java:
package com.example.mytelegram;
import org.telegram.api.TLConfig;
import org.telegram.api.TLDcOption;
import org.telegram.api.engine.storage.AbsApiState;
import org.telegram.mtproto.state.AbsMTProtoState;
import org.telegram.mtproto.state.ConnectionInfo;
import org.telegram.mtproto.state.KnownSalt;
import java.util.ArrayList;
import java.util.HashMap;
public class MemoryApiState implements AbsApiState {
private HashMap<Integer, ConnectionInfo[]> connections = new HashMap<Integer, ConnectionInfo[]>();
private HashMap<Integer, byte[]> keys = new HashMap<Integer, byte[]>();
private HashMap<Integer, Boolean> isAuth = new HashMap<Integer, Boolean>();
private int primaryDc = 2; // I have tested application with primaryDc=0 to 10
public MemoryApiState(boolean isTest) {
connections.put(1, new ConnectionInfo[]{
new ConnectionInfo(1, 0, isTest ? "149.154.167.40" : "149.154.167.50", 443)
});
}
#Override
public synchronized int getPrimaryDc() {
return primaryDc;
}
#Override
public synchronized void setPrimaryDc(int dc) {
primaryDc = dc;
}
#Override
public synchronized boolean isAuthenticated(int dcId) {
if (isAuth.containsKey(dcId)) {
return isAuth.get(dcId);
}
return false;
}
#Override
public synchronized void setAuthenticated(int dcId, boolean auth) {
isAuth.put(dcId, auth);
}
#Override
public synchronized void updateSettings(TLConfig config) {
connections.clear();
HashMap<Integer, ArrayList<ConnectionInfo>> tConnections = new HashMap<Integer, ArrayList<ConnectionInfo>>();
int id = 0;
for (TLDcOption option : config.getDcOptions()) {
if (!tConnections.containsKey(option.getId())) {
tConnections.put(option.getId(), new ArrayList<ConnectionInfo>());
}
tConnections.get(option.getId()).add(new ConnectionInfo(id++, 0, option.getIpAddress(), option.getPort()));
}
for (Integer dc : tConnections.keySet()) {
connections.put(dc, tConnections.get(dc).toArray(new ConnectionInfo[0]));
}
}
#Override
public synchronized byte[] getAuthKey(int dcId) {
return keys.get(dcId);
}
#Override
public synchronized void putAuthKey(int dcId, byte[] key) {
keys.put(dcId, key);
}
#Override
public synchronized ConnectionInfo[] getAvailableConnections(int dcId) {
if (!connections.containsKey(dcId)) {
return new ConnectionInfo[0];
}
return connections.get(dcId);
}
#Override
public synchronized AbsMTProtoState getMtProtoState(final int dcId) {
return new AbsMTProtoState() {
private KnownSalt[] knownSalts = new KnownSalt[0];
#Override
public byte[] getAuthKey() {
return MemoryApiState.this.getAuthKey(dcId);
}
#Override
public ConnectionInfo[] getAvailableConnections() {
return MemoryApiState.this.getAvailableConnections(dcId);
}
#Override
public KnownSalt[] readKnownSalts() {
return knownSalts;
}
#Override
protected void writeKnownSalts(KnownSalt[] salts) {
knownSalts = salts;
}
};
}
#Override
public synchronized void resetAuth() {
isAuth.clear();
}
#Override
public synchronized void reset() {
isAuth.clear();
keys.clear();
}
}
MainActivity.java:
package com.example.mytelegram;
import java.io.IOException;
import org.telegram.api.TLAbsUpdates;
import org.telegram.api.TLConfig;
import org.telegram.api.TLNearestDc;
import org.telegram.api.auth.TLAuthorization;
import org.telegram.api.auth.TLSentCode;
import org.telegram.api.engine.ApiCallback;
import org.telegram.api.engine.AppInfo;
import org.telegram.api.engine.LoggerInterface;
import org.telegram.api.engine.RpcException;
import org.telegram.api.engine.TelegramApi;
import org.telegram.api.requests.TLRequestAuthSendCall;
import org.telegram.api.requests.TLRequestAuthSendCode;
import org.telegram.api.requests.TLRequestAuthSignIn;
import org.telegram.api.requests.TLRequestHelpGetConfig;
import org.telegram.api.requests.TLRequestHelpGetNearestDc;
import org.telegram.api.requests.TLRequestUpdatesGetState;
import org.telegram.api.updates.TLState;
import android.support.v7.app.ActionBarActivity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends ActionBarActivity {
static Context context;
private static AppInfo ai;
private static void createApi() throws IOException {
String res = "No test";
boolean useTest = res.equals("test");
apiState = new MemoryApiState(useTest);
ai=new AppInfo(App_ID, "Sony", "???", "???", "en");
api = new TelegramApi(apiState, ai, new ApiCallback() {
#Override
public void onAuthCancelled(TelegramApi api) {
}
#Override
public void onUpdatesInvalidated(TelegramApi api) {
}
#Override
public void onUpdate(TLAbsUpdates updates) {
Log.d("tlg", "onUpdate(TLAbsUpdates updates)");
}
});
}
private static void login() throws IOException {
//TLNearestDc dcInfo = api.doRpcCallNonAuth(new TLRequestHelpGetNearestDc());
// api.switchToDc(dcInfo.getNearestDc());
//************ Exception raises here ************
TLConfig config = api.doRpcCallNonAuth(new TLRequestHelpGetConfig()); // I have An IOException Here (e=timeout Exception)
apiState.updateSettings(config);
Log.d("tlg","completed.");
String phone = "+9891********"; // I have tested app with the phone without plus too
Log.d("tlg","Sending sms to phone " + phone + "...");
TLSentCode sentCode = null;
try {
api.doRpcCallNonAuth(new TLRequestAuthSendCode(phone, 1, app_id, "__hash__", "en"));
} catch (RpcException e) {
if (e.getErrorCode() == 303) {
int destDC;
if (e.getErrorTag().startsWith("NETWORK_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("NETWORK_MIGRATE_".length()));
} else if (e.getErrorTag().startsWith("PHONE_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("PHONE_MIGRATE_".length()));
} else if (e.getErrorTag().startsWith("USER_MIGRATE_")) {
destDC = Integer.parseInt(e.getErrorTag().substring("USER_MIGRATE_".length()));
} else {
throw e;
}
api.switchToDc(destDC);
sentCode = api.doRpcCallNonAuth(new TLRequestAuthSendCode(phone, 0, app_id, "__hash__", "en"));
} else {
throw e;
}
}
Log.d("tlg","Activation code:");
String code = "123";
TLAuthorization auth = api.doRpcCallNonAuth(new TLRequestAuthSignIn(phone, sentCode.getPhoneCodeHash(), code));
apiState.setAuthenticated(apiState.getPrimaryDc(), true);
Log.d("tlg","Activation complete.");
TLState state = api.doRpcCall(new TLRequestUpdatesGetState());
Log.d("tlg","loaded.");
}
static MemoryApiState apiState;
static TelegramApi api;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=getApplicationContext();
try {
createApi();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
login();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//workLoop();
}
}
I have added telegram-api library (telegram-api-1.1.127-shadow.jar) in my eclipse 'libs' folder. The problem is Timeout Exception in MainActivity.java when I want to call RPC. Where is the problem? What should I do? My OS is windows 8.1 . I am searching for 2 whole days. I have read github codes too. They are very complicated for me. I can not figure out what should I do?
I have added INTERNET and ACCESS_NETWORK_STATE permisions to AndroidManifest.xml. I allways check the network connection when my application runs.
I found the problem in your code:
In MemoryApiState you should put, in the 'connections' map, 'primaryDc' as key and not '1'.
i have developed android weather app that receives data from forecast weather site, i have a problem in casting the Relativelayout i cant figure it out,
here is my code :
Mainactivity.java
package synctc.me.stormy;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import butterknife.ButterKnife;
import butterknife.InjectView;
public class MainActivity extends ActionBarActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private CurrentWeather mCurrentWeather ;
#InjectView(R.id.timeLabel) TextView mTimeLabel;
#InjectView(R.id.temperatureLabel) TextView mTemperatureLabel;
#InjectView(R.id.humidityValue) TextView mHumidityValue;
#InjectView(R.id.precipValue) TextView mPrecipValue;
#InjectView(R.id.summaryLabel) RelativeLayout mSummaryLabel;
#InjectView(R.id.iconImageView) ImageView mIconImageView;
#InjectView(R.id.refreshImageView) ImageView mRefreshImageView;
#InjectView(R.id.progressBar)ProgressBar mProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
mProgressBar.setVisibility(View.INVISIBLE);
final double latitude = 37.8267;
final double longitude = -122.423;
mRefreshImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getForecast(latitude,longitude);
}
});
getForecast(latitude,longitude);
Log.d(TAG, "Main ui is running");
}
private void getForecast(double latitude, double longitude) {
String apiKey="37ee485ed1ec27026ef5ff8948b6f94b";
String forecastUrl="https://api.forecast.io/forecast/"+apiKey+"/"+latitude+","+longitude;
if(isNetworkAvailable()){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(forecastUrl)
.build();
Call call=client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
alertUserAboutError();
}
#Override
public void onResponse(Response response) throws IOException {
runOnUiThread(new Runnable() {
#Override
public void run() {
toggleRefresh();
}
});
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if(response.isSuccessful()){
mCurrentWeather = getCurrentDetails(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
}else{
alertUserAboutError();
}
} catch (IOException e) {
Log.e(TAG, "Exception Caught : ",e);
}
catch (JSONException e){
Log.e(TAG, "Exception Caught : ",e);
}
}
});}
else{
Toast.makeText(this
, getString(R.string.network_unavailable_messege)
, Toast.LENGTH_LONG).show();
}
}
private void updateDisplay() {
mTemperatureLabel.setText(mCurrentWeather.getTemperature()+"");
mTimeLabel.setText("At" +mCurrentWeather.getFormattedTime()+"it will be ");
mHumidityValue.setText(mCurrentWeather.getHumidity()+"");
mPrecipValue.setText(mCurrentWeather.getPrecipChane()+"%");
Drawable drawable = getResources().getDrawable(mCurrentWeather.getIconId());
mIconImageView.setImageDrawable(drawable);
}
private CurrentWeather getCurrentDetails(String jsonData) throws JSONException{
JSONObject forecast = new JSONObject (jsonData);
String timezone = forecast.getString("timezone");
Log.i(TAG,"From JSON To:"+timezone);
JSONObject currently = new JSONObject("currently");
CurrentWeather currentWeather = new CurrentWeather();
currentWeather.setHumidity(currently.getDouble("humidity"));
currentWeather.setTime(currently.getLong("time"));
currentWeather.setIcon(currently.getString("icon"));
currentWeather.setPrecipChane(currently.getDouble("precipProbability"));
currentWeather.setSummery(currently.getString("summery"));
currentWeather.setTemperature(currently.getDouble("temperature"));
currentWeather.setTimeZone(timezone);
Log.d(TAG, currentWeather.getFormattedTime());
return currentWeather;
}
private boolean isNetworkAvailable() {
toggleRefresh();
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if(networkInfo != null &&networkInfo.isConnected()){
isAvailable=true ;
}
return isAvailable;
}
private void toggleRefresh() {
if(mProgressBar.getVisibility()== View.INVISIBLE) {
mProgressBar.setVisibility(View.VISIBLE);
mRefreshImageView.setVisibility(View.INVISIBLE);
}else{
mProgressBar.setVisibility(View.INVISIBLE);
mRefreshImageView.setVisibility(View.VISIBLE);
}
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
}
//AlertDialogFragment.java
package synctc.me.stormy;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
public class AlertDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setTitle(context.getString(R.string.error_title))
.setMessage(context.getString(R.string.error_messege))
.setPositiveButton(context.getString(R.string.error_ok_button_text), null);
AlertDialog dialog = builder.create();
return dialog;
}
}
//CurrentWeather.java
package synctc.me.stormy;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class CurrentWeather {
private String mIcon;
private long mTime;
private double mTemperature;
private double mHumidity;
public String getTimeZone() {
return mTimeZone;
}
public void setTimeZone(String timeZone) {
mTimeZone = timeZone;
}
private double mPrecipChane;
private String mSummery;
private String mTimeZone;
public String getIcon() {
return mIcon;
}
public void setIcon(String icon) {
mIcon = icon;
}
public int getIconId(){
int iconId = R.mipmap.clear_day;
if (mIcon.equals("clear-day")) {
iconId = R.mipmap.clear_day;
}
else if (mIcon.equals("clear-night")) {
iconId = R.mipmap.clear_night;
}
else if (mIcon.equals("rain")) {
iconId = R.mipmap.rain;
}
else if (mIcon.equals("snow")) {
iconId = R.mipmap.snow;
}
else if (mIcon.equals("sleet")) {
iconId = R.mipmap.sleet;
}
else if (mIcon.equals("wind")) {
iconId = R.mipmap.wind;
}
else if (mIcon.equals("fog")) {
iconId = R.mipmap.fog;
}
else if (mIcon.equals("cloudy")) {
iconId = R.mipmap.cloudy;
}
else if (mIcon.equals("partly-cloudy-day")) {
iconId = R.mipmap.partly_cloudy;
}
else if (mIcon.equals("partly-cloudy-night")) {
iconId = R.mipmap.cloudy_night;
}
return iconId;
}
public long getTime() {
return mTime;
}
public String getFormattedTime(){
SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
formatter.setTimeZone(TimeZone.getTimeZone(getTimeZone()));
Date datetime = new Date(getTime()*1000);
String timeString = formatter.format(datetime);
return timeString;
}
public void setTime(long time) {
mTime = time;
}
public int getTemperature() {
return(int) Math.round(mTemperature);
}
public void setTemperature(double temperature) {
mTemperature = temperature;
}
public double getHumidity() {
return mHumidity;
}
public void setHumidity(double humidity) {
mHumidity = humidity;
}
public String getSummery() {
return mSummery;
}
public void setSummery(String summery) {
mSummery = summery;
}
public int getPrecipChane() {
double precipPercentage = mPrecipChane * 100;
return (int)Math.round(precipPercentage) ;
}
public void setPrecipChane(double precipChane) {
mPrecipChane = precipChane;
}
}
Here is the logcat:
03-29 06:32:43.596 1779-1797/synctc.me.stormy E/MainActivity﹕ Exception Caught :
org.json.JSONException: Value currently of type java.lang.String cannot be converted to JSONObject
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONObject.<init>(JSONObject.java:160)
at org.json.JSONObject.<init>(JSONObject.java:173)
at synctc.me.stormy.MainActivity.getCurrentDetails(MainActivity.java:153)
at synctc.me.stormy.MainActivity.access$400(MainActivity.java:37)
at synctc.me.stormy.MainActivity$2.onResponse(MainActivity.java:106)
at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:162)
at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
03-29 06:33:01.383 1838-1838/synctc.me.stormy D/MainActivity﹕ Main ui is running
03-29 06:33:01.399 1838-1859/synctc.me.stormy D/OpenGLRenderer﹕ Render dirty regions requested: true
03-29 06:33:01.474 1838-1838/synctc.me.stormy D/﹕ HostConnection::get() New Host Connection established 0xabb93d20, tid 1838
03-29 06:33:01.529 1838-1838/synctc.me.stormy D/Atlas﹕ Validating map...
03-29 06:33:01.647 1838-1859/synctc.me.stormy D/libEGL﹕ loaded /system/lib/egl/libEGL_emulation.so
03-29 06:33:01.648 1838-1859/synctc.me.stormy D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_emulation.so
03-29 06:33:01.665 1838-1859/synctc.me.stormy D/libEGL﹕ loaded /system/lib/egl/libGLESv2_emulation.so
03-29 06:33:01.687 1838-1859/synctc.me.stormy D/﹕ HostConnection::get() New Host Connection established 0xa3216120, tid 1859
03-29 06:33:01.718 1838-1859/synctc.me.stormy I/OpenGLRenderer﹕ Initialized EGL, version 1.4
03-29 06:33:01.843 1838-1859/synctc.me.stormy D/OpenGLRenderer﹕ Enabling debug mode 0
03-29 06:33:01.899 1838-1859/synctc.me.stormy W/EGL_emulation﹕ eglSurfaceAttrib not implemented
03-29 06:33:01.899 1838-1859/synctc.me.stormy W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa32192a0, error=EGL_SUCCESS
03-29 06:33:02.849 1838-1858/synctc.me.stormy V/MainActivity﹕ {"latitude":37.8267,"longitude":-122.423,"timezone":"America/Los_Angeles","offset":-7,"currently":{"time":1427625186,"summary":"Clear","icon":"clear-night","nearestStormDistance":61,"nearestStormBearing":104,"precipIntensity":0,"precipProbability":0,"temperature":52.49,"apparentTemperature":52.49,"dewPoint":48.34,"humidity":0.86,"windSpeed":4.19,"windBearing":299,"visibility":6.15,"cloudCover":0.02,"pressure":1019.36,"ozone":330.14},"minutely":{"summary":"Clear for the hour.","icon":"clear-night","data":[{"time":1427625180,"precipIntensity":0,"precipProbability":0},{"time":1427625240,"precipIntensity":0,"precipProbability":0},{"time":1427625300,"precipIntensity":0,"precipProbability":0},{"time":1427625360,"precipIntensity":0,"precipProbability":0},{"time":1427625420,"precipIntensity":0,"precipProbability":0},{"time":1427625480,"precipIntensity":0,"precipProbability":0},{"time":1427625540,"precipIntensity":0,"precipProbability":0},{"time":1427625600,"precipIntensity":0,"precipProbability":0},{"time":1427625660,"precipIntensity":0,"precipProbability":0},{"time":1427625720,"precipIntensity":0,"precipProbability":0},{"time":1427625780,"precipIntensity":0,"precipProbability":0},{"time":1427625840,"precipIntensity":0,"precipProbability":0},{"time":1427625900,"precipIntensity":0,"precipProbability":0},{"time":1427625960,"precipIntensity":0,"precipProbability":0},{"time":1427626020,"precipIntensity":0,"precipProbability":0},{"time":1427626080,"precipIntensity":0,"precipProbability":0},{"time":1427626140,"precipIntensity":0,"precipProbability":0},{"time":1427626200,"precipIntensity":0,"precipProbability":0},{"time":1427626260,"precipIntensity":0,"precipProbability":0},{"time":1427626320,"precipIntensity":0,"precipProbability":0},{"time":1427626380,"precipIntensity":0,"precipProbability":0},{"time":1427626440,"precipIntensity":0,"precipProbability":0},{"time":1427626500,"precipIntensity":0,"precipProbability":0},{"time":1427626560,"precipIntensity":0,"precipProbability":0},{"time":1427626620,"precipIntensity":0,"precipProbability":0},{"time":1427626680,"precipIntensity":0,"precipProbability":0},{"time":1427626740,"precipIntensity":0,"precipProbability":0},{"time":1427626800,"precipIntensity":0,"precipProbability":0},{"time":1427626860,"precipIntensity":0,"precipProbability":0},{"time":1427626920,"precipIntensity":0,"precipProbability":0},{"time":1427626980,"precipIntensity":0,"precipProbability":0},{"time":1427627040,"precipIntensity":0,"precipProbability":0},{"time":1427627100,"precipIntensity":0,"precipProbability":0},{"time":1427627160,"precipIntensity":0,"precipProbability":0},{"time":1427627220,"precipIntensity":0,"precipProbability":0},{"time":1427627280,"precipIntensity":0,"precipProbability":0},{"time":1427627340,"precipIntensity":0,"precipProbability":0},{"time":1427627400,"precipIntensity":0,"precipProbability":0},{"time":1427627460,"precipIntensity":0,"precipProbability":0},{"time":1427627520,"precipIntensity":0,"precipProbability":0},{"time":1427627580,"precipIntensity":0,"precipProbability":0},{"time":1427627640,"precipIntensity":0,"precipProbability":0},{"time":1427627700,"precipIntensity":0,"precipProbability":0},{"time":1427627760,"precipIntensity":0,"precipProbability":0},{"time":1427627820,"precipIntensity":0,"precipProbability":0},{"time":1427627880,"precipIntensity":0,"precipProbability":0},{"time":1427627940,"precipIntensity":0,"precipProbability":0},{"time":1427628000,"precipIntensity":0,"precipProbability":0},{"time":1427628060,"precipIntensity":0,"precipProbability":0},{"time":1427628120,"precipIntensity":0,"precipProbability":0},{"time":1427628180,"precipIntensity":0,"precipProbability":0},{"time":1427628240,"precipIntensity":0,"precipProbability":0},{"time":1427628300,"precipIntensity":0,"precipProbability":0},{"time":1427628360,"precipIntensity":0,"precipProbability":0},{"time":1427628420,"precipIntensity":0,"precipProbability":0},{"time":1427628480,"precipIntensity":0,"precipProbability":0},{"time":1427628540,"precipIntensity":0,"precipProbability":0},{"time":142762860
03-29 06:33:02.859 1838-1858/synctc.me.stormy I/MainActivity﹕ From JSON To:America/Los_Angeles
03-29 06:33:02.873 1838-1858/synctc.me.stormy E/MainActivity﹕ Exception Caught :
org.json.JSONException: Value currently of type java.lang.String cannot be converted to JSONObject
at org.json.JSON.typeMismatch(JSON.java:111)
at org.json.JSONObject.<init>(JSONObject.java:160)
at org.json.JSONObject.<init>(JSONObject.java:173)
at synctc.me.stormy.MainActivity.getCurrentDetails(MainActivity.java:153)
at synctc.me.stormy.MainActivity.access$400(MainActivity.java:37)
at synctc.me.stormy.MainActivity$2.onResponse(MainActivity.java:106)
at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:162)
at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
On MainActivity in getCurrentDetails(String jsonData) method the line having problem is below one:-
JSONObject currently = new JSONObject("currently");
The "currently" is just a string and your trying it to convert to json object which throwing error. "currently" is object in you jsonData String so
Instead of above line try below :-
JSONObject currently = new JSONObject(forecast.get("currently").toString());
I am trying out the WebSockets with Fallbacks transports for Android, Node.js and Atmosphere example. I get an the following error:
/home/mofa/NetBeansProjects/App/src/com/jullio/advisor/wAsyncChat.java:87: error: cannot access JsonParseException
return mapper.readValue(data, Message.class);
class file for org.codehaus.jackson.JsonParseException not found
/home/mofa/NetBeansProjects/App/src/com/jullio/advisor/wAsyncChat.java:68: error: cannot access ObjectCodec
return mapper.writeValueAsString(data);
class file for org.codehaus.jackson.ObjectCodec not found
Here is the androidchat code:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.atmosphere.wasync.ClientFactory;
import org.atmosphere.wasync.Decoder;
import org.atmosphere.wasync.Encoder;
import org.atmosphere.wasync.Event;
import org.atmosphere.wasync.Function;
import org.atmosphere.wasync.Request;
import org.atmosphere.wasync.RequestBuilder;
import org.atmosphere.wasync.impl.AtmosphereClient;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.util.Date;
public class wAsyncChat extends Activity {
private Button bt;
private TextView tv;
private String serverIpAddress = "http://10.0.2.2:8080";
private final static ObjectMapper mapper = new ObjectMapper();
private final Handler uiHandler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.main);
bt = (Button) findViewById(R.id.myButton);
tv = (TextView) findViewById(R.id.myTextView);
try {
AtmosphereClient client = ClientFactory.getDefault().newClient(AtmosphereClient.class);
RequestBuilder request = client.newRequestBuilder()
.method(Request.METHOD.GET)
.uri(serverIpAddress + "/chat")
.trackMessageLength(true)
.encoder(new Encoder<Message, String>() {
#Override
public String encode(Message data) {
try {
return mapper.writeValueAsString(data);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
})
.decoder(new Decoder<String, Message>() {
#Override
public Message decode(Event type, String data) {
data = data.trim();
// Padding
if (data.length() == 0) {
return null;
}
if (type.equals(Event.MESSAGE)) {
try {
return mapper.readValue(data, Message.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
})
.transport(Request.TRANSPORT.WEBSOCKET);
final org.atmosphere.wasync.Socket socket = client.create();
socket.on("message", new Function<Message>() {
#Override
public void on(final Message t) {
uiHandler.post(new Runnable() {
#Override
public void run() {
Date d = new Date(t.getTime());
tv.append("Author " + t.getAuthor() + "# " + d.getHours() + ":" + d.getMinutes() + ": " + t.getMessage() + "\n");
}
});
}
}).on(new Function<Throwable>() {
#Override
public void on(Throwable t) {
tv.setText("ERROR 3: " + t.getMessage());
t.printStackTrace();
}
}).open(request.build());
bt.setOnClickListener(new OnClickListener() {
String name = null;
public void onClick(View v) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
if (name == null) {
name = str;
}
socket.fire(new Message(name, str));
et.setText("");
Log.d("Client", "Client sent message");
} catch (Throwable e) {
tv.setText("ERROR 3: " + e.getMessage());
e.printStackTrace();
}
}
});
} catch (Throwable e) {
tv.setText("Unable to connect: " + e.getMessage());
e.printStackTrace();
}
}
}
I have the library for nodeserver connection. You can use it from git
SocketIO socketio = new SocketIO() {
#Override
public void onConnect() {
}
#Override
public void onDisconnect() {
}
#Override
public void onMessage(String message) {
Log.d("===Server Answer====",message);
}
};
socketio.Connect("192.168.0.1", 9000);
after onConnect() send the message:
socketio.send("Your message to socket");
it work with latest socketIO, and use RFC 6455 websocket protocol