Telegram API RPC Timeout Exception - android

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'.

Related

Sending information to ubidots only if the condition are met

The Image shows the dashboard of the application
package com.example.leeyueloong.proximityapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import com.estimote.mustard.rx_goodness.rx_requirements_wizard.Requirement;
import com.estimote.mustard.rx_goodness.rx_requirements_wizard.RequirementsWizardFactory;
import com.estimote.proximity_sdk.proximity.EstimoteCloudCredentials;
import com.estimote.proximity_sdk.proximity.ProximityContext;
import com.estimote.proximity_sdk.proximity.ProximityObserver;
import com.estimote.proximity_sdk.proximity.ProximityObserverBuilder;
import com.estimote.proximity_sdk.proximity.ProximityZone;
import com.ubidots.ApiClient;
import com.ubidots.Variable;
import java.util.ArrayList;
import java.util.List;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
public class MainActivity extends AppCompatActivity {
private ProximityObserver proximityObserver;
private int send;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EstimoteCloudCredentials cloudCredentials =
new EstimoteCloudCredentials("tan-kok-hui-s-proximity-fo-07q", "d18623351c273ce3e09ffcc1f6201861");
// 2. Create the Proximity Observer
this.proximityObserver =
new ProximityObserverBuilder(getApplicationContext(), cloudCredentials)
.withOnErrorAction(new Function1<Throwable, Unit>() {
#Override
public Unit invoke(Throwable throwable) {
Log.e("app", "proximity observer error: " + throwable);
return null;
}
})
.withLowLatencyPowerMode()
.build();
// add this below:
ProximityZone zone = this.proximityObserver.zoneBuilder()
.forTag("desks")
.inNearRange()
.withOnEnterAction(new Function1<ProximityContext, Unit>() {
#Override
public Unit invoke(ProximityContext context) {
String deskOwner = context.getAttachments().get("desk-owner");
Log.d("app", "Welcome to " + deskOwner + "'s desk");
return null;
}
})
.withOnExitAction(new Function1<ProximityContext, Unit>() {
#Override
public Unit invoke(ProximityContext context) {
return null;
}
})
.withOnChangeAction(new Function1<List<? extends ProximityContext>, Unit>() {
#Override
public Unit invoke(List<? extends ProximityContext> contexts) {
List<String> deskOwners = new ArrayList<>();
for (ProximityContext context : contexts) {
deskOwners.add(context.getAttachments().get("desk-owner"));
}
for (int i = 0; i < deskOwners.size(); i++) {
if (deskOwners.get(i).contains("Peter")) {
send = 1;
Toast.makeText(MainActivity.this, "Alert:Unauthorized Zone", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "Sending information to ubidots..........", Toast.LENGTH_LONG).show();
} else if (deskOwners.get(i).contains("Alex")) {
send = 0;
Toast.makeText(MainActivity.this, "Device has entered this range", Toast.LENGTH_SHORT).show();
}
else if (deskOwners.get(i).contains("Paul"))
{
}
}
Log.d("app", "In range of desks: " + deskOwners);
return null;
}
})
.create();
this.proximityObserver.addProximityZone(zone);
ProximityZone innerZone = this.proximityObserver.zoneBuilder()
.forTag("treasure")
.inCustomRange(3.0)
.create();
ProximityZone outerZone = this.proximityObserver.zoneBuilder()
.forTag("treasure")
.inCustomRange(9.0)
.create();
RequirementsWizardFactory
.createEstimoteRequirementsWizard()
.fulfillRequirements(MainActivity.this,
// onRequirementsFulfilled
new Function0<Unit>() {
#Override
public Unit invoke() {
Log.d("app", "requirements fulfilled");
proximityObserver.start();
return null;
}
},
// onRequirementsMissing
new Function1<List<? extends Requirement>, Unit>() {
#Override
public Unit invoke(List<? extends Requirement> requirements) {
Log.e("app", "requirements missing: " + requirements);
return null;
}
},
// onError
new Function1<Throwable, Unit>() {
#Override
public Unit invoke(Throwable throwable) {
Log.e("app", "requirements error: " + throwable);
return null;
}
});
}
private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (send == 1 || send == 0) {
new ApiUbidots().execute(send);
}
}
};
#Override
protected void onStart() {
super.onStart();
registerReceiver(mBatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
// Stop the BroadcastReceiver
#Override
protected void onStop() {
unregisterReceiver(mBatteryReceiver);
super.onStop();
}
// In Charge of sending variable to ubidots
public class ApiUbidots extends AsyncTask<Integer, Void, Void> {
private final String API_KEY = "A1E-0109ebb46b4990a4ed82f74d2912a9e6b481";
private final String VARIABLE_ID = "5b62ab7ac03f97418ba1c28e";
#Override
protected Void doInBackground(Integer... params) {
ApiClient apiClient = new ApiClient(API_KEY);
Variable batteryLevel = apiClient.getVariable(VARIABLE_ID);
batteryLevel.saveValue(params[0]);
return null;
}
}
}
The problem is i am able to sending the data to the ubidots however i want to make it so that only if the condition has met, it will then send to the cloud. Other than that, it would not have send any data to the cloud.

Getting problems when using MVP model to write a "login" App

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

ACRA 4.9.0 : How can I write ACRA report to file (in Application data folder)

I want to write the crash report in text file using latest Acra 4.9.0.
I can,t example for this latest version.
I tried using available documentation.
Acra is enabled
but it,s not writing in the file.
myApp
package com.myApp;
import org.acra.ACRA;
import android.app.AlertDialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.KeyEvent;
import android.view.View;
import com.myApp.Application.AppLauncher;
import com.myApp.interfaces.AppEvents;
import com.myApp.R;
import com.utils.Config;
import com.utils.Constants;
import com.utils.DeviceValidator;
public class myApp extends FragmentActivity
{
private AppLauncher appLauncher = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(!ACRA.isACRASenderServiceProcess())
{
setContentView(R.layout.activity_myApp);
appLauncher = new AppLauncher();
appLauncher.registerEventListener(appEventsListener);
appLauncher.initApp(this);
}
}
#Override
public void onPause() {
super.onPause();
if(!DeviceValidator.isDeviceValid())
{
return;
}
appLauncher.activityOnPause();
}
#Override
protected void onRestart() {
super.onRestart();
}
#Override
protected void onStart()
{
super.onStart();
}
#Override
public void onResume()
{
super.onResume();
appLauncher.activityOnResume();
}
}
AcraApplication
package com.myAPP;
import org.acra.ACRA;
import org.acra.ReportField;
import org.acra.ReportingInteractionMode;
import org.acra.annotation.ReportsCrashes;
import org.acra.sender.HttpSender.Method;
import android.app.Application;
#ReportsCrashes(
formUri = "http://staging.jemtv.com/variable_dump/index.php",
customReportContent = { ReportField.REPORT_ID, ReportField.DEVICE_ID, ReportField.APP_VERSION_NAME, ReportField.ANDROID_VERSION, ReportField.STACK_TRACE, ReportField.CUSTOM_DATA, ReportField.LOGCAT },
httpMethod = Method.POST,
reportSenderFactoryClasses = org.acra.util.MyOwnSenderFactory.class,
mode = ReportingInteractionMode.SILENT
)
public class AcraApplication extends Application
{
public AcraApplication()
{
super();
}
#Override
public void onCreate() {
super.onCreate();
ACRA.init(this);
}
}
MyOwnSender
package org.acra.util;
import java.io.File;
import java.io.FileOutputStream;
import org.acra.ReportField;
import org.acra.collector.CrashReportData;
import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderException;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
public class MyOwnSender implements ReportSender {
private static final String FILE_NAME = "AcraReport.txt";
//private final Map<ReportField, String> mMapping = new HashMap<ReportField, String>();
//private FileWriter crashReport = null;
MyOwnSender(Context context, #NonNull ACRAConfiguration config)
{
Log.d("testAcra", "MyOwnSender created");
/* File logFile = new File(context.getFilesDir().getPath() + "/" + FILE_NAME, FILE_NAME);
try {
crashReport = new FileWriter(logFile, true);
} catch (IOException e) {
e.printStackTrace();
}*/
}
#Override
public void send(Context context, CrashReportData report) throws ReportSenderException
{
// Iterate over the CrashReportData instance and do whatever
// you need with each pair of ReportField key / String value
String finalReport = createCrashReport(report);
String tempFile = context.getFilesDir().getPath() + "/" + FILE_NAME;
try
{
File detailedFile = new File(tempFile);
if(!detailedFile.exists())
detailedFile.createNewFile();
FileOutputStream stream = new FileOutputStream(detailedFile, true);
stream.write(finalReport.getBytes());
Log.d("testAcra","adding to file: "+stream);
stream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
/*final Map<String, String> finalReport = remap(report);
try {
BufferedWriter buf = new BufferedWriter(crashReport);
Set<Entry<String, String>> set = reportBody.entrySet();
Iterator<Entry<String, String>> i = set.iterator();
while (i.hasNext()) {
Map.Entry<String, String> me = (Entry<String, String>) i.next();
buf.append("[" + me.getKey() + "]=" + me.getValue());
}
buf.flush();
buf.close();
} catch (IOException e) {
Log.e("TAG", "IO ERROR", e);
}*/
}
private String createCrashReport(CrashReportData crashReportData){
StringBuilder body = new StringBuilder();
body.append("ReportID : " + crashReportData.getProperty(ReportField.REPORT_ID))
.append("\n")
.append("DeviceID : " + crashReportData.getProperty(ReportField.DEVICE_ID))
.append("\n")
.append("AppVersionName : " + crashReportData.getProperty(ReportField.APP_VERSION_NAME))
.append("\n")
.append("Android Version : " + crashReportData.getProperty(ReportField.ANDROID_VERSION))
.append("\n")
.append("CustomData : " + crashReportData.getProperty(ReportField.CUSTOM_DATA))
.append("\n")
.append("STACK TRACE : \n" + crashReportData.getProperty(ReportField.STACK_TRACE))
.append("\n")
.append("LogCAT : \n" + crashReportData.getProperty(ReportField.LOGCAT));
return body.toString();
}
/* private Map<String, String> remap(Map<ReportField, String> report) {
Set<ReportField>fields = ACRA.getConfig().getReportFields();
final Map<String, String> finalReport = new HashMap<String, String>(report.size());
for (ReportField field : fields)
{
if (mMapping == null || mMapping.get(field) == null)
finalReport.put(field.toString(), report.get(field));
else
finalReport.put(mMapping.get(field), report.get(field));
}
return finalReport;
}*/
}
MyOwnSenderFactory
package org.acra.util;
import org.acra.config.ACRAConfiguration;
import org.acra.sender.ReportSender;
import org.acra.sender.ReportSenderFactory;
import android.content.Context;
import android.support.annotation.NonNull;
public class MyOwnSenderFactory implements ReportSenderFactory {
// NB requires a no arg constructor.
/*MyOwnSenderFactory()
{
Log.e("testAcra", "MyOwnSenderFactory created");
}*/
#Override
#NonNull
public ReportSender create(#NonNull Context context, #NonNull ACRAConfiguration config) {
// TODO Auto-generated method stub
return new MyOwnSender(context, config);
}
}
Because i was using jar file instead of aar
in my manifest i was missing
<service
android:name="org.acra.sender.SenderService"
android:exported="false"
android:process=":acra" />
enter code here
That,s why SendeService used in Acra was not starting.
I want to write in application data folder
That is called internal data
I have created my own saver class to handle all of those savings:
import android.content.Context;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
public class Saver {
static FileOutputStream fos;
static FileInputStream fis;
public static void save(String filename, String data, Context c){
try {
fos = c.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String file;
public String getFile(){return file;}
public void setFile(String loc){
file = loc;
}
String result;
private static String mainLoad(String fn, Context c){
String collected = null;
try{
fis = c.openFileInput(fn);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
collected = new String(dataArray);
}
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
try {
fis.close();
return collected;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
public static int loadInt(String fn, Context c){
if(mainLoad(fn,c) == null) return 0;
else return Integer.parseInt(mainLoad(fn,c));
}
public static double loadDouble(String fn, Context c){
if(mainLoad(fn,c) == null) return 0;
else return Double.parseDouble(mainLoad(fn,c));
}
public static float loadFloat(String fn, Context c){
return Float.parseFloat(mainLoad(fn,c));
}
public static String loadString(String fn, Context c){
return mainLoad(fn, c);
}
public static Boolean loadBoolean(String fn, Context c){
if(mainLoad(fn,c) == null) return false;
else return Boolean.parseBoolean(mainLoad(fn,c));
}
public static BigInteger loadBigInteger(String fn, Context c){
return new BigInteger(mainLoad(fn,c));
}
public static BigDecimal loadBigDecimal(String fn, Context c){
return new BigDecimal(mainLoad(fn,c));
}
}
I want to write the crash report in text file using latest Acra 4.9.0. I can,t example for this latest version.
If you want to write to a .txt file on server, try this backend. Uses the default sender:
<?php
// Outputs all POST parameters to a text file. The file name is the date_time of the report reception
$fileName = date('Y-m-d_H-i-s').'.txt';
$file = fopen($fileName,'w') or die('Could not create report file: ' . $fileName);
foreach($_POST as $key => $value) {
$reportLine = $key." = ".$value."\n";
fwrite($file, $reportLine) or die ('Could not write to report file ' . $reportLine);
}
fclose($file);
?>
If you only want to write locally, then the point of ACRA disappears as you cannot get the files.
If you create .txt files to transmit them, it is actually better to use the backend I linked. It transmits the raw data, and you can get all your fields in a .txt file

Can't create handler inside thread that has not called Looper.prepare()

EDIT: My solution was to have a constant class with this code:
static EditText Port = (EditText) MainActivity.mDialog.findViewById(R.id.txtPort); static int mPort = Integer.parseInt(Port.getText().toString()); public static final int PORT = mPort;
I've tried to see the other questions and I understand that I've gotta do something with the UIThread? Honestly, I understand nothing. Im new with android.
The app (chat app) worked fine until I wanted to have multiple ports options depending if I'm hosting (port 5050) or joining (port 80) a chat room. From the beginning i just had a constant value of the port (public static final int PORT) but now i cant have that ofc. If you guys have any other suggestions on how i can have two values of PORT, please share your tips.
Anyway, after trying EVERYTHING I decided to put a method in my main class, and just declare it in other classes. This is the mothod for the value of the port:
public int getPORT() {
txtPORT = (EditText) findViewById(R.id.txtPort);
//String txtPORTa = txtPORT.getText().toString();
int dennaPORT = 0;
if (mJoin.isChecked()) {
dennaPORT = Integer.parseInt(txtPORT.getText().toString());
return dennaPORT;
}
else if (mHost.isChecked()) {
dennaPORT = 5050;
return dennaPORT;
}
return dennaPORT;
}
This is my MainActivity
package chat.chris.android.se.chatup;
import android.app.Activity;
import android.app.Dialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import java.util.ArrayList;
import chat.chris.android.se.chatup.Listeners.ChatListener;
import chat.chris.android.se.chatup.Listeners.ConnectionListener;
import chat.chris.android.se.chatup.Networking.Client;
import chat.chris.android.se.chatup.Networking.Server;
import chat.chris.android.se.chatup.Utilities.ServerUtils;
import static chat.chris.android.se.chatup.R.id.rdioHost;
import static chat.chris.android.se.chatup.R.id.rdioJoin;
public class MainActivity extends Activity {
private Adapter chatAdapter;
private Button btnSendMessage;
private EditText txtMessage;
private ListView lstMessages;
private static Dialog mDialog;
private Client mClient;
private Server mServer;
private EditText txtPORT;
private RadioButton mJoin;
private RadioButton mHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
showChatSelection();
chatAdapter = new Adapter(this, new ArrayList<ChatItem>());
lstMessages = (ListView) findViewById(R.id.lstChat);
lstMessages.setAdapter(chatAdapter);
txtMessage = (EditText) findViewById(R.id.txtSay);
txtMessage.setOnEditorActionListener(txtMessageEditorActionListener);
btnSendMessage = (Button) findViewById(R.id.btnSend);
btnSendMessage.setOnClickListener(btnSendMessageClickListener);
Client.setOnChatListener(chatListener);
Client.setOnConnectionListener(connectionListener);
}
public void showChatSelection() {
mDialog = new Dialog(this);
mDialog.setContentView(R.layout.layout_chat_choose);
mDialog.setTitle("Chat Room");
mDialog.setCancelable(false);
final EditText txtServer = (EditText) mDialog.findViewById(R.id.txtAddress);
final TextView lblServer = (TextView) mDialog.findViewById(R.id.lblAddress);
final TextView txtPort = (EditText) mDialog.findViewById(R.id.txtPort);
final RadioButton mHost = (RadioButton) mDialog.findViewById(rdioHost);
final RadioButton mJoin = (RadioButton) mDialog.findViewById(rdioJoin);
try {
lblServer.setText(ServerUtils.getLocalIp(this));
} catch (NullPointerException e) {
mHost.setEnabled(false);
mHost.setChecked(false);
lblServer.setText("Wifi must be enabled to host");
mJoin.setChecked(true);
txtServer.setVisibility(View.VISIBLE);
txtPort.setVisibility(View.VISIBLE);
}
mDialog.findViewById(R.id.btnChoose).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mDialog.findViewById(R.id.progLoading).setVisibility(View.VISIBLE);
new SetupChat().execute(mHost.isChecked(), mJoin.isChecked() ? txtServer.getText().toString() : "");
}
});
mHost.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mJoin.setChecked(false);
txtServer.setVisibility(View.INVISIBLE);
txtPort.setVisibility(View.INVISIBLE);
lblServer.setVisibility(View.VISIBLE);
}
}
});
mJoin.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mHost.setChecked(false);
txtServer.setVisibility(View.VISIBLE);
txtPort.setVisibility(View.VISIBLE);
lblServer.setVisibility(View.INVISIBLE);
}
}
});
mDialog.show();
}
private final OnClickListener btnSendMessageClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();
}
};
private final OnEditorActionListener txtMessageEditorActionListener = new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int id, KeyEvent event) {
if (id == EditorInfo.IME_ACTION_NEXT || id == EditorInfo.IME_ACTION_DONE)
sendMessage();
return true;
}
};
private final ChatListener chatListener = new ChatListener() {
#Override
public void onChat(String message) {
chatAdapter.addItem(new ChatItem("<html>" + message + "</html>", "Friend"));
}
};
private final ConnectionListener connectionListener = new ConnectionListener() {
#Override
public void onDisconnect(Client client) {
chatAdapter.addItem(new ChatItem(client.getName() + " left the chat room", ""));
}
#Override
public void onJoin(Client client) {
chatAdapter.addItem(new ChatItem(client.getName() + " joined the chat room", ""));
}
};
public void sendMessage() {
String message = txtMessage.getText().toString();
if(message == null || message.isEmpty())
return;
message = message.replace(">", ">");
message = message.replace("<", "<");
try {
if (mServer != null) {
mServer.sendMessage(message);
chatAdapter.addItem(new ChatItem(message, "You"));
} else if (mClient != null) {
mClient.sendMessage(message);
chatAdapter.addItem(new ChatItem(message, "You"));
} else {
return;
}
} catch (Exception e) {
chatAdapter.addItem(new ChatItem(e.getMessage(), "<font color='red'>Error</font>"));
return;
}
txtMessage.setText("");
}
public int getPORT() {
txtPORT = (EditText) findViewById(R.id.txtPort);
//String txtPORTa = txtPORT.getText().toString();
int dennaPORT = 0;
if (mJoin.isChecked()) {
dennaPORT = Integer.parseInt(txtPORT.getText().toString());
return dennaPORT;
}
else if (mHost.isChecked()) {
dennaPORT = 5050;
return dennaPORT;
}
return dennaPORT;
}
private class SetupChat extends AsyncTask<Object,Void, Boolean> {
#Override
protected Boolean doInBackground(Object... args) {
try {
if ((Boolean)args[0]) {
mServer = new Server();
new Thread(mServer).start();
} else {
String address = args[1].toString();
mClient = Client.connect(address);
if (mClient == null)
return true;
new Thread(mClient).start();
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
return false;
}
#Override
protected void onPostExecute(Boolean errors) {
if (errors)
Toast.makeText(getApplicationContext(), "Någonting gick fel\nSkrev du in allting rätt?", Toast.LENGTH_LONG).show();
else
mDialog.dismiss();
}
}
}
This is the client class
package chat.chris.android.se.chatup.Networking;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import chat.chris.android.se.chatup.Listeners.ChatListener;
import chat.chris.android.se.chatup.Listeners.ConnectionListener;
import chat.chris.android.se.chatup.MainActivity;
import chat.chris.android.se.chatup.Utilities.Crypto;
public class Client implements Runnable {
private BufferedReader reader;
private DataOutputStream writer;
private boolean disconnecting;
private byte[] cryptoKey;
private String name;
private static ChatListener chatListener;
private static ConnectionListener connectionListener;
//Instansierar ny klient
public Client(Socket s) throws IOException {
cryptoKey = new byte[16];
try {
reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
writer = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
disconnect();
return;
}
}
//Ger klienten ett namn
public String getName() {
return name;
}
//Sätter namnet
public void setName(String name) {
this.name = name;
}
public static void setOnChatListener(ChatListener listener) {
chatListener = listener;
}
public static void setOnConnectionListener(ConnectionListener listener) {
connectionListener = listener;
}
public BufferedReader getReader() {
return reader;
}
public byte[] getKey(){
return cryptoKey;
}
public void setKey(byte[] key) {
cryptoKey = key;
}
#Override
public void run() {
if (connectionListener != null) {
connectionListener.onJoin(this);
}
try {
while (!disconnecting) {
String read;
if ((read = reader.readLine()) != null) {
if (chatListener != null) {
chatListener.onChat(Crypto.decrypt(read, cryptoKey));
}
}
else{
return;
}
Thread.sleep(5);
}
} catch (IOException e) {
disconnect();
} catch (Exception e) {
e.printStackTrace();
disconnect();
}
}
//Connectar till adressen och returnerar klienten
public static Client connect(String address) throws IOException {
MainActivity porten = new MainActivity();
int PORT;
PORT = porten.getPORT();
InetAddress localAddress = InetAddress.getByName(address);
InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress, PORT);
Socket socket = new Socket();
socket.connect(localSocketAddress, 5000);
Client client = new Client(socket);
socket.getInputStream().read(client.cryptoKey, 0, 16);
System.out.println("Client -> " + new String(client.cryptoKey));
return client;
}
public void sendMessage(String message) throws Exception {
if(message == null || message.isEmpty())
return;
writer.writeUTF(Crypto.encrypt(message, cryptoKey));
}
public void disconnect() {
if (connectionListener != null) {
connectionListener.onDisconnect(this);
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
reader = null;
writer = null;
}
}
And this is the server class
package chat.chris.android.se.chatup.Networking;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;
import chat.chris.android.se.chatup.MainActivity;
import static chat.chris.android.se.chatup.Utilities.Constants.MAX_USERS;
//import static chat.chris.android.se.chatup.Utilities.Constants.PORT;
public class Server implements Runnable {
private ArrayList<Client> clientList;
private ServerSocket mSocket;
private byte[] cryptoKey;
private boolean shuttingDown;
MainActivity porten = new MainActivity();
//Instansierar en ny server chatt
public Server() throws IOException {
int PORT = porten.getPORT();
mSocket = new ServerSocket(PORT);
clientList = new ArrayList<>();
Random mRand = new SecureRandom();
cryptoKey = new byte[16];
mRand.nextBytes(cryptoKey);
System.out.println("Server ->" + new String(cryptoKey));
}
public boolean isShuttingDown() {
return shuttingDown;
}
public void setShuttingDown(boolean shuttingDown) {
this.shuttingDown = shuttingDown;
}
#Override
public void run() {
while (!shuttingDown) {
Socket socket = null;
Client client;
try {
socket = this.mSocket.accept();
if (clientList.size() >= MAX_USERS) {
socket.close();
return;
}
socket.getOutputStream().write(cryptoKey);
client = new Client(socket);
client.setKey(cryptoKey);
new Thread(client).start();
clientList.add(client);
} catch (IOException e) {
e.printStackTrace();
try {
if (socket != null)
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public void sendMessage(String message) throws Exception {
for (Client client : clientList) {
if (shuttingDown)
return;
client.sendMessage(message);
}
}
public void shutdown() {
shuttingDown = true;
try {
mSocket.close();
} catch (IOException e) {
} finally {
mSocket = null;
}
}
}
With this setup im getting these errors:
05-04 00:41:58.969 12319-12370/chat.chris.android.se.chatup W/System.err﹕ java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-04 00:41:58.970 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.Handler.<init>(Handler.java:200)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.Handler.<init>(Handler.java:114)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.app.Activity.<init>(Activity.java:793)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity.<init>(MainActivity.java:32)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.Networking.Server.<init>(Server.java:21)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity$SetupChat.doInBackground(MainActivity.java:229)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity$SetupChat.doInBackground(MainActivity.java:221)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
NEVER create an instance of an Activity, Service, or ContentProvider yourself. Those are always created by the framework. Delete:
MainActivity porten = new MainActivity();
Pass the port into the strangely-named Server class by some other means, such as a constructor parameter or setter method.

Starting new activity through Runnable

I check if a string is NULL in a Thread, if its null, the Handler starts
a Runnable which starts a new Activity.
Everything works fine, but, after the new activity is displayed it switches back to the calling Activity and it crashes.
Here is a code snippet.
if(username==null)
{
dialogs.dismiss();
handlers.post(new MyRunable());
}
and Runnable is
public class MyRunable implements Runnable
{
public void run(){
Toast.makeText(ListActivity.this, "Your Connection is too slow",Toast.LENGTH_LONG).show();
startActivity(new Intent(ListActivity.this,Anim.class));
}
}
Here is my Full Source
package com.cram;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class BuddyListActivity extends Activity
{
String ss;
private static ProgressDialog dialogs,dialog;
private Thread downloadThreads;
boolean results=false;
Context ctx;
String[]ddd;
ListView lv1;
String [] icons;
BuddyDbAdapter adapter;
NetworkInfo netinfo;
Cursor cursor;
String values;
GetBuddy gb;
BuddyDB db;
String[] username;
String[] firstname;
String[] lastname;
String[] avatar;
String[] id;
File[] iconss;
Handler handlers;
boolean ready=false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.buddy);
db=new BuddyDB(BuddyListActivity.this);
Typeface font = Typeface.createFromAsset(getAssets(),"fonts/Fortheloveofhate.ttf");
TextView btxt = (TextView) findViewById(R.id.textbuddy);
btxt.setTypeface(font);
ctx=getApplicationContext();
lv1=(ListView)findViewById(R.id.list22);
netinfo=null;
adapter=new BuddyDbAdapter(BuddyListActivity.this);
netinfo=checkDataConnection(getApplicationContext());
handlers = new Handler();
adapter.open();
if(netinfo!=null)
{
downloadThreads = (Thread) getLastNonConfigurationInstance();
if (downloadThreads != null && downloadThreads.isAlive()) {
dialog = ProgressDialog.show(this, "Download", "downloading");
}
startdownload();
}
if(netinfo==null)
{
cursor=adapter.showBuddy();
if (cursor==null||cursor.moveToFirst()==false)
{
AlertDialog.Builder buddybox = new AlertDialog.Builder(this);
buddybox.setMessage("You have No Buddies Yet douche!!");
buddybox.setNeutralButton("Okay", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(getBaseContext(),Anim.class));
}
});
buddybox.setCancelable(false);
buddybox.show();
}
else
{
cursor.moveToFirst();
int j=0;
ddd=new String[cursor.getCount()];
icons=new String [cursor.getCount()];
do
{
String firstName = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_FISTNAME));
String lastname = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_LASTNAME));
String Avatar = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.AVATAR));
ddd[j]=firstName+" "+lastname;
Log.d("Test", ddd[j]);
icons[j]=Avatar;
Log.d("Test", icons[j]);
j++;
}while(cursor.moveToNext());
iconss= new File[icons.length];
Log.d("Test",icons.length+"");
for (int q = 0; q < icons.length; q++) {
iconss[q] = new File(Download.ROOT +"/"+ icons[q]+".jpg");
Log.d("Test", iconss[q].getAbsolutePath().toString());
}
//adapter.close();
lv1.setAdapter(new BuddyAdapter(BuddyListActivity.this,R.layout.list1,ddd,iconss));
onDestroy();
}
}
}
private void box() {
// TODO Auto-generated method stub
cursor=adapter.showBuddy();
if (cursor==null||cursor.moveToFirst()==false)
{
dialogs.dismiss();
AlertDialog.Builder buddybox = new AlertDialog.Builder(this);
buddybox.setMessage("You have No Buddies Yet ass!!");
buddybox.setNeutralButton("Okay", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(getBaseContext(),Anim.class));
}
});
buddybox.setCancelable(false);
buddybox.show();
}
}
private NetworkInfo checkDataConnection(Context applicationContext) {
final ConnectivityManager connMgr = (ConnectivityManager)BuddyListActivity.this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo=null;
final android.net.NetworkInfo wifi =connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile =connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(wifi.isConnected()||mobile.isConnected())
{networkinfo=connMgr.getActiveNetworkInfo();
return networkinfo;
}
else
{
return null;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (adapter != null) {
adapter.close();
}
}
#Override
protected void onStop()
{
super.onStop();
finish();
}
private void startdownload() {
dialogs = ProgressDialog.show(BuddyListActivity.this, "Contacting Our Servers", "Geting Your Buddies Avatar");
downloadThreads = new MyThread();
downloadThreads.start();
}
public class MyThread extends Thread {
#Override
public void run() {
try {
new Thread();
GetBuddy tt=new GetBuddy();
String xml=tt.get();
if(xml==null)
{ dialogs.dismiss();
handlers.post(new MyRunable());
ready=false;
//downloadThreads.suspend();
}
final Download cd = new Download();
results = cd.downloadBitmap();
if(results)
{
BuddyParse bp=new BuddyParse();
try {
username=bp.show(xml);
// if(username==null)
// { dialogs.dismiss();
// handlers.post(new MyRunable());
// //downloadThreads.suspend();
// }
firstname=bp.firstname();
lastname=bp.lastname();
avatar=bp.avatar();
id=bp.id();
adapter.deleteAll();
ready=true;
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
catch (SAXException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
// Log.d("len", username.length+"");
for(int k=0; k<username.length;k++)
{
adapter.insertBuddy(id[k], username[k], firstname[k], lastname[k], avatar[k]);
Log.d("Test", id[k]+username[k]+firstname[k]+lastname[k]+avatar[k]+"");
}
box();
cursor=adapter.showBuddy();
cursor.moveToFirst();
int i=0;
ddd=new String[cursor.getCount()];
icons=new String [cursor.getCount()];
do
{
String firstName = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_FISTNAME));
String lastname = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.BUDDY_LASTNAME));
String Avatar = cursor.getString(cursor.getColumnIndex(BuddyDbAdapter.AVATAR));
ddd[i]=firstName+" "+lastname;
Log.d("Test", ddd[i]);
icons[i]=Avatar;
Log.d("Test",icons[i]);
i++;
}while(cursor.moveToNext());
iconss= new File[avatar.length];
for (int k = 0; k < avatar.length; k++) {
iconss[k] = new File(Download.ROOT+"/"+avatar[k]+".jpg");
Log.d("Test", iconss[k].getAbsolutePath()+"thread");
//Log.d("Test", ddd[k]);
}
if (results&&ready)
{
dialogs.dismiss();
handlers.post(new MyRuns());
}
}
// else
// { dialogs.dismiss();
// handlers.post(new MyRunable());
//
// }
}finally {
}
}
}
public class MyRuns implements Runnable {
public void run() {
ready=true;
lv1.setAdapter(new BuddyAdapter(ctx,R.layout.list1,ddd,iconss));
onDestroy();
}
}
public class MyRunable implements Runnable {
public void run() {
//Toast.makeText(BuddyListActivity.this, "Your Connection is too slow", Toast.LENGTH_LONG).show();
startActivity(new Intent(BuddyListActivity.this,Anim.class));
}
}
}
use main thread to start your thread check runOnUiThread(Runnable action)
Setting RETURN in the try catch block and setting
android:noHistory="true" in Android Manifest for all activities fixed my problem
If you are trying to create an async task in a different thread I would recommend you to use the following class:
private final class MyRunnable extends
AsyncTask<Void, Void, Document> {
protected Document doInBackground(Void... params) {
}
protected void onPostExecute(Document result) {
}
}
You only have to change the parameters.
More info here:
http://developer.android.com/reference/android/os/AsyncTask.html
Finish your current activity when starting another activity from runnable .

Categories

Resources