Why this Android Socket program don't work? - android

I have connected my Android device to the wifi shared by my laptop. After I input the IP address and click "OK" in the Android app, I can not find any packets to/from the address in Wireshark (packet sniffer)
I have added this to the manifest of the Android Project:
<uses-permission android:name="android.permission.INTERNET"/>
Android Code:
private boolean attemptOpenDoor(){
// Store values at the time of the login attempt.
String studentId = mStudentIdView.getText().toString();
String password = mPasswordView.getText().toString();
final EditText et = new EditText(this);
new AlertDialog.Builder(this).setTitle("please input IP address")
.setIcon(android.R.drawable.ic_dialog_info).setView(et)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
IPAddr = et.getText().toString();
}
}).setNegativeButton("cancel", null).show();
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(IPAddr, 8866), 5000);
OutputStream ou = socket.getOutputStream();
ou.write((studentId+password).getBytes("UTF-8"));
ou.close();
socket.close();
}catch (SocketTimeoutException aa) {
//连接超时 在UI界面显示消息
AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
alertDialog.setMessage("服务器连接失败!请检查网络是否打开");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}

The program doesn't work because at the time that you're trying to open the socket using:
socket.connect(new InetSocketAddress(IPAddr, 8866), 5000);
the dialog is still up and value of IPAddr has not yet been set. Make sure that you only start connecting once the user has entered a valid input in the field.
Also, beware that the method above will block whichever thread it's running on until a connection is established or 5 seconds go by, meaning that it'd be unwise to call it directly inside of the OnClickListener. You should probably use an AsyncTask or similar to avoid blocking the UI thread while the connection is taking place.

You should move your connect codes after "onClick".
new AlertDialog.Builder(this).setTitle("please input IP address")
.setIcon(android.R.drawable.ic_dialog_info).setView(et)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
IPAddr = et.getText().toString();
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(IPAddr, 8866), 5000);
OutputStream ou = socket.getOutputStream();
ou.write((studentId+password).getBytes("UTF-8"));
ou.close();
socket.close();
}catch (SocketTimeoutException aa) {
//连接超时 在UI界面显示消息
AlertDialog alertDialog = new AlertDialog.Builder(LoginActivity.this).create();
alertDialog.setMessage("服务器连接失败!请检查网络是否打开");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}).setNegativeButton("cancel", null).show();

Related

how can i open location settings in android using phonegap

I am trying to open location settings in android using WebIntent plugin for phonegap. I use GPSDetector plugin for phonegap to detect if location is active and if it is not active i want to open Location Settings. After activate the location press Back button and go to index.html.
window.plugins.webintent.startActivity({
action: 'android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS'},
function() {},
function() {alert('Failed to open URL via Android Intent')}
);
In this case I don`t know which is the action, I have tried like this but did not work.
I have made an activity and there i added in onCreate method :
startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);
But in this way i don`t know how to send the user back to index.html after he turns on the Location(Gps).
Please help and Thanks a lot
I didn't use any available plugins. I wrote my own plugin and this is the java code of that plugin. Check if this is helpful. It works as your requirement for me.
if (CHECK_LOCATION_SERVICES_ENABLED.equals(action))
{
try
{ boolean locationServicesEnabled=false;
if(this.ctx.getContext()!=null)
{
//Location services not enabled
final Context context = this.ctx.getContext();
(new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
final Handler innerHandler = new Handler() {
#Override
public void handleMessage(Message message) {
/*Toast.makeText(myContext,android.os.Build.VERSION.RELEASE,
Toast.LENGTH_LONG).show();*/
LocationManager lm = null;
boolean gps_enabled=false,network_enabled=false;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try{
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}catch(Exception ex){}
try{
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}catch(Exception ex){}
if(!gps_enabled && !network_enabled){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
context);
alertDialog.setTitle("FindMe");
alertDialog
.setMessage("You must enable Location Services for using FindMe.\nDo you want to go to Location Sources Settings?");
alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
}
#Override
public void dispatchMessage(Message message) {
handleMessage(message);
}
};
Message message = innerHandler.obtainMessage();
innerHandler.dispatchMessage(message);
Looper.loop();
}
})).start();
}
return new PluginResult(PluginResult.Status.OK,"success ");
}
catch (Exception ex)
{
Log.d("FindMePlugin", ex.toString());
return new PluginResult(PluginResult.Status.ERROR, "error"+ex.toString());
}
}

"MultiUserChat.addInvitationListener" not being called

I am working on a GroupChat process. I have successfully sent the invitation and using PSI i have received this invitation. But M unable to invoke my own "MultiUserChat.addInvitationListener". I have done this many ways but in-vain. Here is one of my attempt.
ProviderManager pm = ProviderManager.getInstance();
pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user", new MUCUserProvider());
MultiUserChat.addInvitationListener(mXmppConnection, MyClass.this);
And doing "MyClass extends Activity implements InvitationListener"
#Override
public void invitationReceived(final Connection conn,final String room, final String inviter, String reason, String password, Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(MyClass.this);
builder.setTitle("Room Invitation");
builder.setMessage(inviter + " sent you an invitation to join GroupChat saying \""+reason+" \". \n Do you want to join "+inviter+"?");
builder.setPositiveButton("Accept", new DialogInterface.OnClickListener() {
// Joining Room
#Override
public void onClick(DialogInterface dialog, int which) {
try {
MultiUserChat multiUserChat = new MultiUserChat(conn, room);
multiUserChat.join(myNickName);
if(multiUserChat.isJoined()){
dialog.cancel();
}
} catch (XMPPException e) {
e.printStackTrace();
}
}
});
builder.setNegativeButton("Decline", new DialogInterface.OnClickListener() {
// Declining Room Invitation
#Override
public void onClick(DialogInterface dialog, int which) {
MultiUserChat.decline(conn, room, inviter, "I'm busy right now");
dialog.cancel();
}
});
builder.show();
}

Do you know a better way to write this method?

I created this method to handle 2 different way of creating alert dialog, depending on internet status. Do you know a better way to get the same result? Using .equals() on strings in if-else block do not seem a best-practices way... Am i right?
public void noInternetAlertDialog(String errorMsg) {
String title = null;
String msg = null;
if (errorMsg.equals("none")) {
title = "Connection failded";
msg = "Please check internet connection";
} else if (errorMsg.equals("slow")) {
title = "Connection timeout";
msg = "Connection is slow";
}
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(Main.this);
builder.setCancelable(false);
builder.setTitle(title);
builder.setMessage(msg);
builder.setPositiveButton("Retry", new DialogInterface.OnClickListener(){
#Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
downloadDialog();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
Use strings.xml for your strings to allow localization (Retry, Cancel, "Connection failded", "Please check internet connection", "Connection timeout", "Connection is slow")
If your values represent something create a data type for them. I mean: if your string will report if internet is available or slow, why keep it as String? A String can be everything and convert to something which says directly what values it can assume will improve your code a lot.
public enum InternetStatus {
Offline,
Slow
}
And a == will be faster than a equals call.
If you don't want to use the enum, consider using "none".equals(errorMessage)
String title = "Connection failded";
String msg = "Please check internet connection";
if ("slow".equals(errorMsg)) {
title = "Connection timeout";
msg = "Connection is slow";
}
You can chain calls to the builder and remove the variable dialog because you can call show() directly (If you still need the reference to the AlertDialog, show() still returns it).
You can go with your fantasy and do something like this
.setTitle(errorMsg == InternetStatus.Slow ? "Connection timeout" : "Please check internet connection")
.setMessage(errorMsg == InternetStatus.Slow ? "Connection failded" : "Connection is slow")
but it will make your code a mess if you want to add more InternetStatus.
You could create a method inside InternetStatus which returns the message (if it will be needed in other places too). But it highly depends on the project you are working with. You could an "extension" method which does it for you just where you need it without put it in the enum code (enums can have methods). You should consider every opportunity.
Maybe?
public enum InternetStatus {
Offline,
Slow
}
public void noInternetAlertDialog(InternetStatus errorMsg) {
String title = getString(R.string.internetfailed);
String msg = getString(R.string.checkyourinternet);
if (errorMsg == InternetStatus.Slow) {
title = getString(R.string.connectiontimeout);
msg = getString(R.string.slowinternet);
}
new AlertDialog.Builder(Main.this)
.setCancelable(false)
.setTitle(title)
.setMessage(msg)
.setPositiveButton(R.string.retry, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
downloadDialog();
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
})
.show();
}
It really is not a good idea to identify a state/result with a string! you should use an enum instead.
enum NoInternetResult {
slow, none
}
and then:
public void noInternetAlertDialog(NoInternetResult result) {
String title = "Connection failded";
String msg = "Please check internet connection";
if (result==NoInternetResult.slow) {
title = "Connection timeout";
msg = "Connection is slow";
}
btw. use strings.xml for you strings like "retry" and "Cancel" (http://developer.android.com/guide/topics/resources/string-resource.html)

Save data from edit Text within custom alertdialog to excel file with apache poi

This question might have been asked several times (about returning value from alert dialog) but i just couldn't get this thing to work (the flow in android application was fine but it just couldn't save the data to the excel files), I've tried several methods posted in SO but still no luck and in a deep frustration atm.
I have some suspicion though. I think it's because i accessed both etOne and etTwo from within the inner class that makes it somewhat unreadable?
The snippet of my code:
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
alertDialog.setTitle("Enter the data below");
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialog = inflater.inflate(R.layout.alertdialog, null);
//I think the problem comes from here?
final EditText etOne = (EditText) dialog.findViewById(R.id.etOne);
final EditText etTwo = (EditText) dialog.findViewById(R.id.etTwo);
//----------------------------------------------------------------
alertDialog.setView(dialog)
// Add action buttons
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// Save One and Two to excel file
try {
FileInputStream file;
HSSFWorkbook workbook;
file = new FileInputStream(new File(fileName));
workbook = new HSSFWorkbook(file);
HSSFSheet sheet2 = workbook.getSheetAt(2);
int row;
Cell cell;
row = ((KaryawanActivity) getActivity()).position;
cell = sheet2.getRow(row).getCell(1);
cell.setCellValue(etOne.getText().toString());
cell = sheet2.getRow(row).getCell(2);
cell.setCellValue(etTwo.getText().toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Open Semasa Activity
Intent intent = new Intent(getActivity().getBaseContext(), SemasaActivity.class);
intent.putExtra("filepath", fileName);
intent.putExtra("evaluator", evaluator);
intent.putExtra(THEME, theme);
intent.putExtra("KaryawanNo", KaryawanNo);
intent.putExtra("KaryawanPos", ((KaryawanActivity) getActivity()).position);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
alertDialog.show();
Thanks in advance.
Ah forget it, it's my own mistake anyway. I forgot to set the write the workbook of course it'll never save. My bad -_-
For those who need it, the complete code goes this way, and accessing the EditText from within inner class is doable (although i doubt this is a good way of doing it).
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
alertDialog.setTitle("Enter the data below");
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialog = inflater.inflate(R.layout.alertdialog, null);
//I think the problem comes from here?
final EditText etOne = (EditText) dialog.findViewById(R.id.etOne);
final EditText etTwo = (EditText) dialog.findViewById(R.id.etTwo);
//----------------------------------------------------------------
alertDialog.setView(dialog)
// Add action buttons
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
// Save One and Two to excel file
try {
FileInputStream file;
HSSFWorkbook workbook;
file = new FileInputStream(new File(fileName));
workbook = new HSSFWorkbook(file);
HSSFSheet sheet2 = workbook.getSheetAt(2);
int row;
Cell cell;
row = ((KaryawanActivity) getActivity()).position;
cell = sheet2.getRow(row).getCell(1);
cell.setCellValue(etOne.getText().toString());
cell = sheet2.getRow(row).getCell(2);
cell.setCellValue(etTwo.getText().toString());
file.close();
FileOutputStream outFile = new FileOutputStream(new File(fileName));
workbook.write(outFile);
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Open Semasa Activity
Intent intent = new Intent(getActivity().getBaseContext(), SemasaActivity.class);
intent.putExtra("filepath", fileName);
intent.putExtra("evaluator", evaluator);
intent.putExtra(THEME, theme);
intent.putExtra("KaryawanNo", KaryawanNo);
intent.putExtra("KaryawanPos", ((KaryawanActivity) getActivity()).position);
startActivity(intent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
alertDialog.show();

thread not running in background

i am calling this function from the menu and calls the upload(item) function to pass the index of the selected priority.
public void showPriorityDialog()
{
final CharSequence[] priority = {"1 Hour", "12 Hours", "24 Hours", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select Priority");
builder.setItems(priority, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if(item != 3)
upload(item);
}
});
AlertDialog alert = builder.create();
alert.show();
}
however, whenever i call the upload function, the thread doesn't run in background, and the OS thinks that the app is not responding due to executing timeout.
public void upload(int priority)
{
final int _priority = priority;
uploadThread = new Thread()
{
#Override
public void run()
{
try
{
super.run();
mHandler.post(new Runnable() {
#Override
public void run() {
try
{
//ftp commands...
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.toString() , Toast.LENGTH_SHORT).show();
}
}
});
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.toString() , Toast.LENGTH_SHORT).show();
}
}
};
uploadThread.start();
}
am i doing something wrong? TIA
When you do mHandler.post(), your entire Runnable executes on UI thread and your background thread just exits. To fix, do FTP before posting to handler. Then do mHandler.post() to have Toast appear. Note that you catch also need to display Toast via post.

Categories

Resources