Android MutlicastSocket constructor problems - android

I'm writing an app to do some basic communication via multicast. I'm running into a problem and can figure why. I'm defining the socket according to the constructor in the API, yet it's not actually setting the variables as specified. Here is a basic code snippet with a bunch of the extra stuff removed:
import java.net.MulticastSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
...
private InetAddress groupInetAddr = InetAddress.getByName("239.42.42.42");;
private int groupPort = 42000;
private MulticastSocket groupSocket;
netInt = NetInfo.getInterface();
//This is a custom method that chooses a candidate NetworkInterface
//from available options. Returns a NetworkInterface object
try{
groupSocket = new MulticastSocket(groupPort);
groupSocket.setNetworkInterface(netInt);
groupSocket.joinGroup(groupInetAddr);
groupSocket.setTimeToLive(64);
}
catch (Exception e){
Log.i(TAG, "FAILED");
}
I have some test code immediately following this code to confirm that the socket has been created properly, and it isn't...
Log.i(TAG, "groupInetAddr: " + groupInetAddr.toString());
Log.i(TAG, "groupPort: " + groupPort);
Log.i(TAG, "groupSocket.getInetAddress: " + groupSocket.getInetAddress());
Log.i(TAG, "groupSocket.getPort(): " + groupSocket.getPort());
The log results of the test:
GroupSender﹕ groupInetAddr: /239.42.42.42
GroupSender﹕ groupPort: 42000
GroupSender﹕ groupSocket.getInetAddress: null
GroupSender﹕ groupSocket.getPort(): -1
So, as you can see, the InetAddress is being created properly, so that's not the problem, but the socket isn't assigning the InetAddress as the destination. Additionally, when I check Wireshark, there is no IGMP message send out over the LAN to that address.
Additionally, I've added the following permissions to the AndroidManifest.xml to allow access to necessary services.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.wifi" />
Any ideas? Hopefully I'm just missing something small.

The socket has been constructed correctly. You didn't connect it, so its getInetAddress() returns null and its target port is -1.
That doesn't have anything to do with which multicast groups it has joined. Your expectations are at fault.
The IGMP message is only sent if this host isn't already a member of that group.

It turns out that this code works as intended. The problem is with the Android emulator. It doesn't send out the IGMP message as required.
I was trying to communicate between the emulator and an actual device. I installed the app on 2 devices and they are able to communicate between each other.

Related

Xamarin.Android i am getting Soap Service time out exception on my mobile phone

My main purpose is getting data from soap webservice on my android phone. Actually i implemented webservice references correctly. But i want to try some data from soap webservice on my android phone , i am getting time out exception like this ;
System.Net.WebException: The operation has timed out.
Here is my source code ;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
var service = new LifeService.LifeService();
var result = service.LifeService_getPersons("xxx#gmail.com","12345");
}
After adding some email and number to the LifeService_getPersons method it should return PersonList to me . Nevertheless it return an exception what i mentioned above. I run this service at windows form application and xamarin.android by using an emulator. Service works fine . It returns data correctly. However when i try to use it on my self phone , it is not working. Then i thought it might be some permission problem and added permissions to the Manifest.xml file such as ;
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Unfortunately it doesn't change anything.Please help . thanks.

Can I turn on WiFi-Direct from code? on API-16 (Android 4.2.2)

I am developing an application with NFC and wifi direct. I get the MAC address using NFC and the Wifi Direct to transfer data. I call discoverpeers() and could get success. But there is no callback WIFI_P2P_PEERS_CHANGED_ACTION, the callback comes only when I go to settings and the select wifidirect.
This was discussed in the other question
Can I turn on WiFi-Direct from code? on Android API-14 (ICS)
"I'd like to add that WiFi direct on JB and above (at least on AOSP) is not active all the time - it only appears to be. If you look at listeners for WiFi direct, it turns itself off after some time. It turns itself back on if you open the wifi direct menu, however. You might have to have the host do a peer search or initialize itself in order to be able to be found. Likely a battery saving trick. I have also found that it's blocking, since as it accepts a connection, the entire system will lock up and fail to connect sometimes. (The system invitation) – Mgamerz "
Can anyone suggest the solution for the problem WIFI_P2P_PEERS_CHANGED_ACTION callback is not got and can get only when manually go to settings->wifi->tap on wifidirect
I used two devices Samsung galaxy nexus and nexus 7 both running on 4.2.2
There is no available API to enable wifiP2P but you can invoke method "enableP2p" from android settings 4.0.1
WifiP2pManager manager = (WifiP2pManager) getActivity().getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(getActivity(), getActivity().getMainLooper(), null);
try {
Method method1 = manager.getClass().getMethod("enableP2p", Channel.class);
method1.invoke(manager, channel);
//Toast.makeText(getActivity(), "method found",
// Toast.LENGTH_SHORT).show();
} catch (Exception e) {
//Toast.makeText(getActivity(), "method did not found",
// Toast.LENGTH_SHORT).show();
}
To disable wifiP2P use this method
Method method1 = manager.getClass().getMethod("disableP2p", Channel.class);
Not from code. The user has to. That's why the demo has the link to wifi settings in the action bar.
When you call manager.discoverPeers(channel, new WifiP2pManager.ActionListener()
define onFailure and look at the reasonCode. If it's 0, then either the Wifi or WiFi direct is off.
If you look at the WiFi Direct demo app, the WifiDirectBroadcast Reciever, this piece of code looks at whether p2p is enabled specifically
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
activity.setIsWifiP2pEnabled(true);
} else {
activity.setIsWifiP2pEnabled(false);
activity.resetData();
}
Then when discover peers is called it looks at the variable set by setIsWifiP2pEnabled
thanks user3093354. to continue with your solution, in order to disable the p2p you have to invoke:
Method method1 = manager.getClass().getMethod("disableP2p", Channel.class);
//Try this it may be help you
WifiManager wifiManager = (WifiManager)this.getSystemService(this.WIFI_SERVICE);
wifiManager.setWifiEnabled(true); //True - to enable WIFI connectivity .
//False -disable WIFI connectivity.
//add this permissions in Manifest file :
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
You can load the wifi driver from a command prompt with the desired concurrency level if you are rooted:
/system/bin/insmod /system/lib/modules/wlan.ko con_mode=3
These are the values:
typedef enum
{
VOS_STA_MODE=0,
VOS_STA_SAP_MODE=1,
VOS_P2P_CLIENT_MODE,
VOS_P2P_GO_MODE,
VOS_MONITOR_MODE,
VOS_FTM_MODE = 5,
VOS_IBSS_MODE,
VOS_P2P_DEVICE_MODE,
VOS_MAX_NO_OF_MODE
} tVOS_CON_MODE;
This is for an Atheros card.

Android BluetoothSocket.isConnected always returns false

I am trying to detect whether a bluetooth device is currently connected to an Android device using API 14 or better. It seems like I should be able to use the BluetoothSocket.isConnected() method, but no matter what I've done, so far I just get false back for anything, connected or not.
AndroidManifest includes these lines:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Locale 4.x supports API 14 or greater. -->
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
<uses-feature android:name="android.hardware.bluetooth" />
And the code in question:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : pairedDevices) {
Log.i(Constants.LOG_TAG, String.format(Locale.US, "Device: %s connected: %b", device.getName(), isConnected(device))); //$NON-NLS-1$z
}
}
private boolean isConnected(BluetoothDevice device) {
BluetoothSocket socket = null;
// Get a BluetoothSocket for a connection with the given BluetoothDevice
UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
} catch (IOException e) {
Log.e(Constants.LOG_TAG, e.getMessage()); //$NON-NLS-1$z
return false;
}
Log.i(Constants.LOG_TAG, socket.toString()); //$NON-NLS-1$z
return socket.isConnected();
}
No errors are thrown, it simply returns "false" 100% of the time. Is there something that I'm not doing right?
I believe that jkane001 already solved his problem, so I hope this answer will help someone else.
First of all after socket creation
socket = device.createRfcommSocketToServiceRecord(SPP_UUID);
you shall init connection by
socket.connect();
After that you'll be able to check connection state using socket.isConnected()
Since connect() method is not blocking, so immediately after socket may be not connected yet. I suggest to use something like this
while(!socket.isConnected() && trial++ < 3){
try {
Thread.sleep(300);
} catch (Exception e) {}
}
By the way, I found that on some android devices isConnected() always returns false. In such case just try to write something to socket and check if there is no exception.
Apparently there are devices and/or Android versions where isConnected() is implemented (i.e. the function exists and you can call it), but worse than useless because it always returns false. I have an Alcatel phone in on my desk running Android 4.2.2 which exhibits this behavior.
My code was assuming it was disconnected, and so killed my connection thread and this was driving me crazy for a long time. However, I removed the isConnected() call and assumed it was connected, and everything works fine! I haven't found a better way to check for a valid connection other than waiting for an error and declaring the connection dead. The blocked read() in the thread eventually does fail.
We have reports from the field that sound similar, and 2 of the 2 problem devices for which we know the version are also on 4.2.2. Haven't yet deployed the fix, so not sure if it fixed those cases yet.
First off, why are you using reflection?! That's a red flag to me. The APIs allow you to talk to another device via bluetooth, see this link so you should not use reflection.
A socket will always return not connected before its connect method is called. It seems that your code obtains the socket but never tries to make a connection with it. You first need to call this method.

Programmatically Connect and Disconnect Android Device

I need to find a way to (using an Android application) programmatically connect and disconnect an Android device from a host.
I am using a Galaxy Nexus. My goal is to keep everything as close to stock as possible, though I have already enabled verbose debug messages in the kernel and in order to view them have enabled root access on the phone to access /proc/kmsg (and the shell command dmesg).
I am certain that there is a way to leverage root access to do what I need to do, but all of my attempts have lead to nix.
Mess with /proc/bus/usb
Mess with /dev/bus/usb
Change between MTP/PTP (unable to do programatically)
Making the Android USB gadget driver into a module <- ???
I am going to try to figure out how to do the last object on the list, as then I would be able to rmmod and insmod the resulting *.ko in my application and that would connect and disconnect the phone. I am unsure of the feasibility of this option though.
Solution came when close to a deadline, so I am almost sure it is not the best way of doing things, but it met my requirements.
Build Modded kernel (to allow hooking of particular function)
Modify kernel config to support Kprobes (set CONFIG_KPROBES to Y)
Remove "static" keyword from android_setup() definition (driver/usb/gadget/android.c)
Build that kernel
Build kernel module (which gives the actual functionality of connecting and disconnecting)
Use Kallsyms to dynamically pull the absolute address of android_setup()
Using kprobes, hook android_setup()
Set up two timers to execute every time android_setup() is called
First timer set for 2 seconds from now, Second set for 2.005 seconds from now
Both timers take a pointer to the struct usb_gadget as their data
In respective callback functions, call usb_gadget_connect() and usb_gadget_disconnect(), which forces physical disconnect followed by reconnect on the Samsung Galaxy Nexus
Build Application
Gotta have a rooted device
Simply make a shell call with SU privilege - "insmod module_name." Until you call rmmod, the module will force the device into an enumeration cycle, disconnecting and reconnecting continuously.
If you are interested in repeating these results, read the document posted here and feel free to send me any questions.
https://docs.google.com/uc?export=download&id=0B9WchRkSOWwJbi10MGhLWUljT2s
You can try to enable/disable some secured settings like Settings.Secure.USB_MASS_STORAGE_ENABLED or Settings.Secure.ADB_ENABLED (depending on what you call "connect" !)
This code should work (disabling USB mass storage):
Settings.Secure.putInt(getContentResolver(),Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);
Settings.Secure.putInt(getContentResolver(),Settings.Secure.USB_MASS_STORAGE_ENABLED, 0);
InternetControl.java
public class InternetControl {
public static void EnableInternet(Context context)
{
try {
Log.i("Reached Enable", "I am here");
setMobileDataEnabled(context,true);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void DisableInternet(Context context)
{
try {
Log.i("Reached Disable", "I am here");
setMobileDataEnabled(context,false);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private static void setMobileDataEnabled(Context context , boolean enabled) throws Exception{
final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final Class connClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = connClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conn);
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
}
}
Manifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />
Enable or Disable function are static so you can call by using
classname.functionname();

Connecting to an OracleDB via an Android app

Thans for looking, I hope you could help me.
Currently, I want to get some data from an OracleDB server (on the LAN) from my Android app. I'm using JDBC with the ojdbc14.jar and the following code in my Android app and the stackTrace I have with the logcat :
http://pastebin.archlinux.fr/432118
As you can see, there is a big exception, and I'm not be able to fix it...
Has someone already succeeded in a OracleDB connection with his Android app and without webservices ?
Could someone help me fixing this Exception ?
For information : I've tried to change the ojdbc driver (the worst thing I've ever done >.>), and I checked the URL validity.
Thanks for helping...
EDIT : The application will have to get data from the OracleDB, and store it on the local SQLite DB of Android, because the Android device will be disconnected of the LAN (and I don't want to make the data accessible from web [3G]). Once disconnected, the app will work with the local data on SQLite. When the user's activity is finished, the device will be reconnected to the LAN and the app syncs the edited SQLite local data with the main Oracle DB server. SQLite <-- local --> App <-- when connected/sync ---> OracleDB
Oracle actually has a product specifically designed for syncing the Oracle Database with mobile devices. It's called mobile server.
However the usage model is slightly different from what you're describing; instead of connecting directly to Oracle Database, you would use a local Berkeley DB or SQLite database, and then mobile server would sync that with the Oracle Database.
It can run as a separate process that automatically handles sync, or you can use API calls to control sync from within your program. If that sounds like something that could be useful to you, check it out here.
You can download it from the download tab and try it out.
Best of luck with solving your problem.
Regards
Eric,
Oracle PM
I've found the answer ! The product Oracle Database Lite is the solution. I explain...
The Oracle Database Lite is a big product, with an unreadable documentation. Impossible for me to understand how it works. But, I've tried to install it. And, in the install folders, there is a jdbc folder.
There, you will find an ojdbc14.jar. Use it in your project instead of the ojdbc14.jar found on the classical Oracle webpage. And it works !
You will be able to connect an Oracle DB via your Android app, using JDBC.
Thanks for all,
Best regards,
Eriatolc
ORACLE DATABASE CONNECTION WITH ANDROID THROUGH LAN
Grant Some Manifest Permissions
<permission
android:name="info.android.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="info.android.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
MainActivity Class
package example.com.myapplication;
import java.sql.Connection;
import java.sql.DriverManager;
import android.os.StrictMode;
public class MainActivity extends AppCompatActivity {
private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DEFAULT_URL = "jdbc:oracle:thin:#192.168.0.1:1521:xe";
private static final String DEFAULT_USERNAME = "system";
private static final String DEFAULT_PASSWORD = "oracle";
private Connection connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
TextView tv = (TextView) findViewById(R.id.hello);
try {
this.connection = createConnection();
e.Log("Connected");
Statement stmt=connection.createStatement();
ResultSet rs=stmt.executeQuery("select * from cat");
while(rs.next()) {
System.out.println("hello : " + rs.getString(1));
}
connection.close();
}
catch (Exception e) {
e.Log(""+e);
e.printStackTrace();
}
}
public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
public static Connection createConnection() throws ClassNotFoundException, SQLException {
return createConnection(DEFAULT_DRIVER, DEFAULT_URL, DEFAULT_USERNAME, DEFAULT_PASSWORD);
}
}
Prerequisite are:
Note there is no need to add dependency lib ojdbc14.jar just copy ojdbc14.jar to your JAVA_HOME jre -> lib -> ext & paste here ojdbc14.jar
then first manually check jdbc connection by cmd/terminal
make any simple java program
http://www.javatpoint.com/example-to-connect-to-the-oracle-database

Categories

Resources