commit e35228c4e93509eee854153a3f755914127ff7c7 Author: Daniel Pollithy Date: Sat Dec 30 12:37:56 2017 +0100 initial commmmit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39fb081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..7ac24c7 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3963879 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3e60be5 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..a98b663 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.3" + defaultConfig { + applicationId "jenny.daniel.wifip2p" + minSdkVersion 22 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.android.support:design:25.3.1' + testCompile 'junit:junit:4.12' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..027fe0c --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\myPrograms\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/flashwifi/wifip2p/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/flashwifi/wifip2p/ExampleInstrumentedTest.java new file mode 100644 index 0000000..150f5a2 --- /dev/null +++ b/app/src/androidTest/java/com/flashwifi/wifip2p/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.flashwifi.wifip2p; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("jenny.daniel.wifip2p", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c91058d --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/AccessPointService.java b/app/src/main/java/com/flashwifi/wifip2p/AccessPointService.java new file mode 100644 index 0000000..183b9da --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/AccessPointService.java @@ -0,0 +1,77 @@ +package com.flashwifi.wifip2p; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.p2p.WifiP2pManager; +import android.os.Binder; +import android.os.IBinder; +import android.util.Log; + +import java.util.Random; + +public class AccessPointService extends Service { + public final static String TAG = "AccessPointService"; + + // Binder given to clients + private final IBinder mBinder = new LocalBinder(); + // Random number generator + private final Random mGenerator = new Random(); + + private boolean setup = false; + + // broadcast stuff + WifiP2pManager mManager; + WifiP2pManager.Channel mChannel; + BroadcastReceiver mReceiver; + IntentFilter mIntentFilter; + + // socket stuff + AccessPointTask apTask; + boolean apRuns; + + public void startAP() { + Log.d("", "start AP"); + if (!apRuns) { + apRuns = true; + apTask.execute(this); + } else { + Log.d("", "startSocketServer: ALREADY RUNNING"); + } + } + + + /** + * Class used for the client Binder. Because we know this service always + * runs in the same process as its clients, we don't need to deal with IPC. + */ + public class LocalBinder extends Binder { + AccessPointService getService() { + // Return this instance of LocalService so clients can call public methods + return AccessPointService.this; + } + } + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } + + @Override + public void onDestroy() { + super.onDestroy(); + unregisterReceiver(mReceiver); + } + + @Override + public void onCreate() { + super.onCreate(); + apTask = new AccessPointTask(); + } + + private void sendUpdateUIBroadcast(){ + Intent local = new Intent(); + local.setAction("jenny.daniel.wifip2p.update_ui"); + this.sendBroadcast(local); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/AccessPointTask.java b/app/src/main/java/com/flashwifi/wifip2p/AccessPointTask.java new file mode 100644 index 0000000..9850382 --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/AccessPointTask.java @@ -0,0 +1,106 @@ +package com.flashwifi.wifip2p; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.util.Log; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class AccessPointTask extends AsyncTask { + + private final static String TAG = "AccessPointTask"; + + @Override + protected String doInBackground(Context... params) { + String ssid = "iota-wifi-121431"; + Context context = params[0]; + WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + WifiInfo w = wifi.getConnectionInfo(); + Log.d("dsd", w.toString()); + + if (wifi.isWifiEnabled()) + { + wifi.setWifiEnabled(false); + } + Method[] wmMethods = wifi.getClass().getDeclaredMethods(); //Get all declared methods in WifiManager class + boolean methodFound = false; + + for (Method method: wmMethods){ + if (method.getName().equals("setWifiApEnabled")){ + methodFound = true; + WifiConfiguration netConfig = new WifiConfiguration(); + netConfig.SSID = "\""+ssid+"\""; + netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); + //netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN); + //netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA); + //netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); + //netConfig.preSharedKey = password; + //netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + //netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); + //netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + //netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); + + try { + boolean apstatus = (Boolean) method.invoke(wifi, netConfig,true); + //statusView.setText("Creating a Wi-Fi Network \""+netConfig.SSID+"\""); + for (Method isWifiApEnabledmethod: wmMethods) + { + if (isWifiApEnabledmethod.getName().equals("isWifiApEnabled")){ + while (!(Boolean)isWifiApEnabledmethod.invoke(wifi)){ + }; + for (Method method1: wmMethods){ + if(method1.getName().equals("getWifiApState")){ + int apstate; + apstate = (Integer)method1.invoke(wifi); + // netConfig = (WifiConfiguration)method1.invoke(wifi); + //statusView.append("\nSSID:"+netConfig.SSID+"\nPassword:"+netConfig.preSharedKey+"\n"); + } + } + } + } + + if(apstatus) + { + System.out.println("SUCCESSdddd"); + //statusView.append("\nAccess Point Created!"); + //finish(); + //Intent searchSensorsIntent = new Intent(this,SearchSensors.class); + //startActivity(searchSensorsIntent); + } + else + { + System.out.println("FAILED"); + + //statusView.append("\nAccess Point Creation failed!"); + } + } + catch (IllegalArgumentException e) { + e.printStackTrace(); + } + catch (IllegalAccessException e) { + e.printStackTrace(); + } + catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + if (!methodFound){ + //statusView.setText("Your phone's API does not contain setWifiApEnabled method to configure an access point"); + } + return null; + } + + @Override + protected void onPostExecute(String result) {} + + @Override + protected void onPreExecute() {} + + @Override + protected void onProgressUpdate(Void... values) {} +} \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java b/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java new file mode 100644 index 0000000..3765b9c --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/ChatActivity.java @@ -0,0 +1,203 @@ +package com.flashwifi.wifip2p; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.net.NetworkInfo; +import android.net.wifi.p2p.WifiP2pInfo; +import android.net.wifi.p2p.WifiP2pManager; +import android.os.Bundle; +import android.os.IBinder; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import java.net.InetAddress; +import java.util.ArrayList; + + +public class ChatActivity extends AppCompatActivity { + + ArrayList arrayList; + ArrayAdapter listAdapter; + ListView listView; + + String name; + String address; + + WiFiDirectBroadcastService mService; + AccessPointService apService; + boolean mBound = false; + InetAddress groupOwnerAddress; + + BroadcastReceiver updateUIReceiver; + + @Override + protected void onStart() { + super.onStart(); + + IntentFilter filter = new IntentFilter(); + filter.addAction("jenny.daniel.wifip2p.update_ui"); + + updateUIReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + updateUi(); + } + }; + registerReceiver(updateUIReceiver, filter); + + // Bind to LocalService + Intent intent = new Intent(this, WiFiDirectBroadcastService.class); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + } + + private void updateUi() { + NetworkInfo network_info = mService.getNetwork_info(); + WifiP2pInfo p2p_info = mService.getP2p_info(); + TextView connection_status = (TextView) findViewById(R.id.connection_status); + connection_status.setText(network_info.toString()); + if (network_info.getState() == NetworkInfo.State.CONNECTED) { + if (p2p_info.isGroupOwner) { + addMessageRight("Network", "You are the group owner"); + // start the socket on port 9999 + mService.startSocketServer(); + } else { + addMessageRight("Network", "You are a member of the group"); + // connect to the socket + groupOwnerAddress = p2p_info.groupOwnerAddress; + } + addMessageRight("Network", "Group owner address: " + p2p_info.groupOwnerAddress.getHostAddress()); + } + + } + + @Override + protected void onStop() { + super.onStop(); + unbindService(mConnection); + mBound = false; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_chat); + + // Get the Intent that started this activity and extract the string + Intent intent = getIntent(); + name = intent.getStringExtra("name"); + address = intent.getStringExtra("address"); + + initUI(); + + } + + + + private void connectToPeer(String address) { + if (mBound) { + mService.connect(address, new WifiP2pManager.ActionListener() { + @Override + public void onSuccess() { + Toast.makeText(getApplicationContext(), "Connected to peer", Toast.LENGTH_SHORT).show(); + } + @Override + public void onFailure(int reason) { + Toast.makeText(getApplicationContext(), "Error connecting to peer", Toast.LENGTH_SHORT).show(); + } + }); + } else { + Toast.makeText(getApplicationContext(), "Service not available", Toast.LENGTH_SHORT).show(); + } + } + + private void initUI() { + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setTitle(name); + setSupportActionBar(toolbar); + + final EditText input = (EditText) findViewById(R.id.chat_input); + Button button = (Button) findViewById(R.id.btn_send); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(final View view) { + addMessageRight(name, input.getText().toString()); + // send the message to the peer + mService.sendMessageToSocketServer(groupOwnerAddress, input.getText().toString()); + } + }); + + listView = (ListView) findViewById(R.id.peer_list); + arrayList = new ArrayList<>(); + + listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList); + listView.setAdapter(listAdapter); + } + + public void addMessageLeft(String name, String text) { + listAdapter.notifyDataSetInvalidated(); + listAdapter.add(name + ": " + text); + listAdapter.notifyDataSetChanged(); + + listView.setSelection(listAdapter.getCount() - 1); + } + + public void addMessageRight(String name, String text) { + listAdapter.notifyDataSetInvalidated(); + listAdapter.add(name + ": " + text); + listAdapter.notifyDataSetChanged(); + } + + /** Defines callbacks for service binding, passed to bindService() */ + private ServiceConnection mConnection = new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service; + mService = binder.getService(); + mBound = true; + // start connection + connectToPeer(address); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mBound = false; + } + }; + + /** Defines callbacks for service binding, passed to bindService() */ + private ServiceConnection apConnection = new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + AccessPointService.LocalBinder binder = (AccessPointService.LocalBinder) service; + apService = binder.getService(); + //apBound = true; + // start connection + //connectToPeer(address); + apService.startAP(); + + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mBound = false; + } + }; + +} diff --git a/app/src/main/java/com/flashwifi/wifip2p/ClientTask.java b/app/src/main/java/com/flashwifi/wifip2p/ClientTask.java new file mode 100644 index 0000000..9b197c0 --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/ClientTask.java @@ -0,0 +1,57 @@ +package com.flashwifi.wifip2p; + +import android.os.AsyncTask; +import android.util.Log; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +public class ClientTask extends AsyncTask { + + private final static String TAG = "ClientTask"; + + @Override + protected String doInBackground(String... params) { + String host = params[0]; + String message = params[1]; + int port = 9999; + Socket socket = new Socket(); + Log.d(TAG, "connectToSocketServer: socket created"); + byte buf[] = new byte[1024]; + try { + socket.bind(null); + Log.d(TAG, "connectToSocketServer: socket bind"); + socket.connect((new InetSocketAddress(host, port)), 500); + Log.d(TAG, "connectToSocketServer: socket connected"); + DataOutputStream DOS = new DataOutputStream(socket.getOutputStream()); + DOS.writeUTF(message); + Log.d(TAG, "connectToSocketServer: utf written"); + socket.close(); + } catch (IOException e) { + //catch logic + Log.d(TAG, "connectToSocketServer: io exception"); + } finally { + if (socket != null) { + if (socket.isConnected()) { + try { + socket.close(); + } catch (IOException e) { + //catch logic + } + } + } + } + return null; + } + + @Override + protected void onPostExecute(String result) {} + + @Override + protected void onPreExecute() {} + + @Override + protected void onProgressUpdate(Void... values) {} +} \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java b/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java new file mode 100644 index 0000000..cd07792 --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java @@ -0,0 +1,261 @@ +package com.flashwifi.wifip2p; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.net.wifi.p2p.WifiP2pManager; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import java.util.ArrayList; + +public class MainActivity extends AppCompatActivity { + + public final static String TAG = "MainActivity"; + + WiFiDirectBroadcastService mService; + boolean mBound = false; + BroadcastReceiver updateUIReceiver; + + ArrayList arrayList; + ArrayAdapter listAdapter; + + + + + + + Messenger xService = null; + /** Flag indicating whether we have called bind on the service. */ + boolean xIsBound; + + static class IncomingHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MessengerService.MSG_SET_VALUE: + Log.d(TAG, "Received from service: " + msg.arg1); + break; + default: + super.handleMessage(msg); + } + } + } + + /** + * Target we publish for clients to send messages to IncomingHandler. + */ + final Messenger xMessenger = new Messenger(new IncomingHandler()); + + /** + * Class for interacting with the main interface of the service. + */ + private ServiceConnection xConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, + IBinder service) { + // This is called when the connection with the service has been + // established, giving us the service object we can use to + // interact with the service. We are communicating with our + // service through an IDL interface, so get a client-side + // representation of that from the raw service object. + xService = new Messenger(service); + + // We want to monitor the service for as long as we are + // connected to it. + try { + Message msg = Message.obtain(null, + MessengerService.MSG_REGISTER_CLIENT); + msg.replyTo = xMessenger; + xService.send(msg); + + // Give it some value as an example. + msg = Message.obtain(null, + MessengerService.MSG_SET_VALUE, this.hashCode(), 0); + xService.send(msg); + } catch (RemoteException e) { + // In this case the service has crashed before we could even + // do anything with it; we can count on soon being + // disconnected (and then reconnected if it can be restarted) + // so there is no need to do anything here. + } + } + + public void onServiceDisconnected(ComponentName className) { + // This is called when the connection with the service has been + // unexpectedly disconnected -- that is, its process crashed. + xService = null; + } + }; + + void doBindService() { + // Establish a connection with the service. We use an explicit + // class name because there is no reason to be able to let other + // applications replace our component. + bindService(new Intent(this, + MessengerService.class), xConnection, Context.BIND_AUTO_CREATE); + xIsBound = true; + } + + void doUnbindService() { + if (xIsBound) { + // If we have received the service, and hence registered with + // it, then now is the time to unregister. + if (xService != null) { + try { + Message msg = Message.obtain(null, + MessengerService.MSG_UNREGISTER_CLIENT); + msg.replyTo = xMessenger; + xService.send(msg); + } catch (RemoteException e) { + // There is nothing special we need to do if the service + // has crashed. + } + } + + // Detach our existing connection. + unbindService(xConnection); + xIsBound = false; + } + } + + + + + + + + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_scrolling); + + initUI(); + } + + @Override + protected void onStart() { + super.onStart(); + + IntentFilter filter = new IntentFilter(); + filter.addAction("jenny.daniel.wifip2p.update_ui"); + + updateUIReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + updateUi(); + } + }; + registerReceiver(updateUIReceiver, filter); + + // Bind to Service + Intent intent = new Intent(this, WiFiDirectBroadcastService.class); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + } + + private void updateUi() { + listAdapter.notifyDataSetInvalidated(); + listAdapter.clear(); + listAdapter.addAll(mService.getArrayList()); + listAdapter.notifyDataSetChanged(); + } + + @Override + protected void onStop() { + super.onStop(); + unbindService(mConnection); + mBound = false; + } + + + private void initUI() { + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setTitle("Discover Peers"); + setSupportActionBar(toolbar); + + FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(final View view) { + onRefreshButtonClick(); + } + }); + + ListView listView = (ListView) findViewById(R.id.peer_list); + arrayList = new ArrayList<>(); + + listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList); + listView.setAdapter(listAdapter); + + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView adapterView, View view, int i, long l) { + String[] splittedLine = arrayList.get(i).split(" : "); + String address = splittedLine[1]; + String name = splittedLine[0]; + + startChat(address, name); + } + }); + } + + public void startChat(String address, String name) { + Intent intent = new Intent(this, ChatActivity.class); + intent.putExtra("address", address); + intent.putExtra("name", name); + startActivity(intent); + } + + public void onRefreshButtonClick() { + final View view = findViewById(R.id.main_view); + if (mBound) { + mService.getPeerList(new WifiP2pManager.ActionListener() { + @Override + public void onSuccess() { + Snackbar.make(view, "Successfully searched for peers", Snackbar.LENGTH_LONG).setAction("Action", null).show(); + } + + @Override + public void onFailure(int reasonCode) { + Snackbar.make(view, "Aaaargh :( Peering problem!", Snackbar.LENGTH_LONG).setAction("Action", null).show(); + } + }); + } + } + + /** Defines callbacks for service binding, passed to bindService() */ + private ServiceConnection mConnection = new ServiceConnection() { + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + WiFiDirectBroadcastService.LocalBinder binder = (WiFiDirectBroadcastService.LocalBinder) service; + mService = binder.getService(); + mBound = true; + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mBound = false; + } + }; +} diff --git a/app/src/main/java/com/flashwifi/wifip2p/MessengerService.java b/app/src/main/java/com/flashwifi/wifip2p/MessengerService.java new file mode 100644 index 0000000..5c498ce --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/MessengerService.java @@ -0,0 +1,134 @@ +package com.flashwifi.wifip2p; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.widget.Toast; + +import java.util.ArrayList; + +public class MessengerService extends Service { + /** For showing and hiding our notification. */ + NotificationManager mNM; + /** Keeps track of all current registered clients. */ + static ArrayList mClients = new ArrayList(); + /** Holds last value set by a client. */ + static int mValue = 0; + + /** + * Command to the service to register a client, receiving callbacks + * from the service. The Message's replyTo field must be a Messenger of + * the client where callbacks should be sent. + */ + static final int MSG_REGISTER_CLIENT = 1; + + /** + * Command to the service to unregister a client, ot stop receiving callbacks + * from the service. The Message's replyTo field must be a Messenger of + * the client as previously given with MSG_REGISTER_CLIENT. + */ + static final int MSG_UNREGISTER_CLIENT = 2; + + /** + * Command to service to set a new value. This can be sent to the + * service to supply a new value, and will be sent by the service to + * any registered clients with the new value. + */ + static final int MSG_SET_VALUE = 3; + + /** + * Handler of incoming messages from clients. + */ + static class IncomingHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_REGISTER_CLIENT: + mClients.add(msg.replyTo); + break; + case MSG_UNREGISTER_CLIENT: + mClients.remove(msg.replyTo); + break; + case MSG_SET_VALUE: + mValue = msg.arg1; + for (int i=mClients.size()-1; i>=0; i--) { + try { + mClients.get(i).send(Message.obtain(null, + MSG_SET_VALUE, mValue, 0)); + } catch (RemoteException e) { + // The client is dead. Remove it from the list; + // we are going through the list from back to front + // so this is safe to do inside the loop. + mClients.remove(i); + } + } + break; + default: + super.handleMessage(msg); + } + } + } + + /** + * Target we publish for clients to send messages to IncomingHandler. + */ + final Messenger mMessenger = new Messenger(new IncomingHandler()); + + @Override + public void onCreate() { + mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); + + // Display a notification about us starting. + showNotification(); + } + + @Override + public void onDestroy() { + // Cancel the persistent notification. + mNM.cancel(R.string.remote_service_started); + + // Tell the user we stopped. + Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show(); + } + + /** + * When binding to the service, we return an interface to our messenger + * for sending messages to the service. + */ + @Override + public IBinder onBind(Intent intent) { + return mMessenger.getBinder(); + } + + /** + * Show a notification while this service is running. + */ + private void showNotification() { + // In this sample, we'll use the same text for the ticker and the expanded notification + CharSequence text = getText(R.string.remote_service_started); + + // The PendingIntent to launch our activity if the user selects this notification + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, + new Intent(this, ChatActivity.class), 0); + + // Set the info for the views that show in the notification panel. + Notification notification = new Notification.Builder(this) + .setTicker(text) // the status text + .setWhen(System.currentTimeMillis()) // the time stamp + .setContentTitle(getText(R.string.local_service_label)) // the label of the entry + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked + .build(); + + // Send the notification. + // We use a string id because it is a unique number. We use it later to cancel. + mNM.notify(R.string.remote_service_started, notification); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/ServerTask.java b/app/src/main/java/com/flashwifi/wifip2p/ServerTask.java new file mode 100644 index 0000000..1c9530a --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/ServerTask.java @@ -0,0 +1,46 @@ +package com.flashwifi.wifip2p; + +import android.os.AsyncTask; +import android.util.Log; + +import java.io.DataInputStream; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +public class ServerTask extends AsyncTask { + + private boolean running = true; + + @Override + protected String doInBackground(String... params) { + try { + + String msg_received = null; + + while (running) { + ServerSocket serverSocket = new ServerSocket(9999); + Socket client = serverSocket.accept(); + Log.d("ServerTask", "doInBackground: openend"); + DataInputStream DIS = new DataInputStream(client.getInputStream()); + msg_received = DIS.readUTF(); + Log.d(">>>>>", msg_received); + serverSocket.close(); + } + + return msg_received; + } catch (IOException e) { + Log.d("", e.getMessage()); + return null; + } + } + + @Override + protected void onPostExecute(String result) {} + + @Override + protected void onPreExecute() {} + + @Override + protected void onProgressUpdate(Void... values) {} +} \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/WiFiDirectBroadcastReceiver.java b/app/src/main/java/com/flashwifi/wifip2p/WiFiDirectBroadcastReceiver.java new file mode 100644 index 0000000..c02b831 --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/WiFiDirectBroadcastReceiver.java @@ -0,0 +1,94 @@ +package com.flashwifi.wifip2p; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.net.NetworkInfo; +import android.net.wifi.p2p.WifiP2pDevice; +import android.net.wifi.p2p.WifiP2pDeviceList; +import android.net.wifi.p2p.WifiP2pGroup; +import android.net.wifi.p2p.WifiP2pInfo; +import android.net.wifi.p2p.WifiP2pManager; +import android.util.Log; + +import java.util.ArrayList; + +/** + * A BroadcastReceiver that notifies of important Wi-Fi p2p events. + */ +public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { + + public final static String TAG = "Brudiiii"; + + private WifiP2pManager mManager; + private WifiP2pManager.Channel mChannel; + private MainActivity mActivity; + + private WiFiDirectBroadcastService service; + + public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, WiFiDirectBroadcastService service) { + super(); + this.mManager = manager; + this.mChannel = channel; + this.service = service; + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + WifiP2pManager.PeerListListener myPeerListListener = new WifiP2pManager.PeerListListener() { + @Override + public void onPeersAvailable(WifiP2pDeviceList wifiP2pDeviceList) { + ArrayList arrayList = new ArrayList<>(); + for (WifiP2pDevice device : wifiP2pDeviceList.getDeviceList()) { + arrayList.add(device.deviceName + " : " + device.deviceAddress); + } + // change the state of the service + service.setArrayList(arrayList); + } + }; + + if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { + Log.d(TAG, "onReceive: WIFI_P2P_STATE_CHANGED_ACTION"); + int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); + if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { + // Wifi P2P is enabled + Log.d(TAG, "Wifi P2P is enabled"); + + } else { + // Wi-Fi P2P is not enabled + Log.d(TAG, "Wi-Fi P2P is not enabled"); + } + // Check to see if Wi-Fi is enabled and notify appropriate activity + } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { + Log.d(TAG, "onReceive: WIFI_P2P_PEERS_CHANGED_ACTION"); + // Call WifiP2pManager.requestPeers() to get a list of current peers + + // request available peers from the wifi p2p manager. This is an + // asynchronous call and the calling activity is notified with a + // callback on PeerListListener.onPeersAvailable() + if (mManager != null) { + mManager.requestPeers(mChannel, myPeerListListener); + } + + + + + } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { + Log.d(TAG, "onReceive: WIFI_P2P_CONNECTION_CHANGED_ACTION"); + // Respond to new connection or disconnections + WifiP2pInfo p2p_info = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO); + NetworkInfo network_info = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); + WifiP2pGroup p2p_group = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP); + Log.d(TAG, "p2p_info: " + p2p_info); + Log.d(TAG, "network_info: " + network_info); + Log.d(TAG, "p2p_group: " + p2p_group); + + Log.d(TAG, "onReceive: " + network_info.getState().toString()); + service.setConnectionStateChanged(p2p_info, network_info, p2p_group); + } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { + Log.d(TAG, "onReceive: WIFI_P2P_THIS_DEVICE_CHANGED_ACTION"); + // Respond to this device's wifi state changing + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/flashwifi/wifip2p/WiFiDirectBroadcastService.java b/app/src/main/java/com/flashwifi/wifip2p/WiFiDirectBroadcastService.java new file mode 100644 index 0000000..4b9e107 --- /dev/null +++ b/app/src/main/java/com/flashwifi/wifip2p/WiFiDirectBroadcastService.java @@ -0,0 +1,171 @@ +package com.flashwifi.wifip2p; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.NetworkInfo; +import android.net.wifi.p2p.WifiP2pConfig; +import android.net.wifi.p2p.WifiP2pDevice; +import android.net.wifi.p2p.WifiP2pGroup; +import android.net.wifi.p2p.WifiP2pInfo; +import android.net.wifi.p2p.WifiP2pManager; +import android.os.Binder; +import android.os.IBinder; +import android.util.Log; + +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Random; + +public class WiFiDirectBroadcastService extends Service { + public final static String TAG = "WiFiService"; + + // Binder given to clients + private final IBinder mBinder = new LocalBinder(); + // Random number generator + private final Random mGenerator = new Random(); + + private boolean setup = false; + + // broadcast stuff + WifiP2pManager mManager; + WifiP2pManager.Channel mChannel; + BroadcastReceiver mReceiver; + IntentFilter mIntentFilter; + + // content attributes + ArrayList arrayList = new ArrayList<>(); + WifiP2pInfo p2p_info; + NetworkInfo network_info; + WifiP2pGroup p2p_group; + ArrayList receivedMessages = new ArrayList<>(); + + // socket stuff + ServerTask serverTask; + boolean serverRuns; + + public void startSocketServer() { + Log.d("", "startSocketServer: "); + if (!serverRuns) { + serverTask.execute(); + } else { + Log.d("", "startSocketServer: ALREADY RUNNING"); + } + } + + public void sendMessageToSocketServer(InetAddress address, String message) { + new ClientTask().execute(address.getHostAddress(), message); + } + + public WifiP2pInfo getP2p_info() { + return p2p_info; + } + + public NetworkInfo getNetwork_info() { + return network_info; + } + + public WifiP2pGroup getP2p_group() { + return p2p_group; + } + + private void setupService() { + if (!setup) { + mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); + mChannel = mManager.initialize(this, getMainLooper(), null); + mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this); + + mIntentFilter = new IntentFilter(); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); + mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); + + registerReceiver(mReceiver, mIntentFilter); + + serverTask = new ServerTask(); + serverRuns = false; + + + setup = true; + } + } + + /** + * Class used for the client Binder. Because we know this service always + * runs in the same process as its clients, we don't need to deal with IPC. + */ + public class LocalBinder extends Binder { + WiFiDirectBroadcastService getService() { + // Return this instance of LocalService so clients can call public methods + return WiFiDirectBroadcastService.this; + } + } + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } + + @Override + public void onDestroy() { + super.onDestroy(); + unregisterReceiver(mReceiver); + } + + @Override + public void onCreate() { + super.onCreate(); + setupService(); + } + + public ArrayList getReceivedMessages() { + return receivedMessages; + } + + private void addReceivedMessage(String message) { + receivedMessages.add(message); + sendUpdateUIBroadcastWithMessage(message); + } + + public void getPeerList(WifiP2pManager.ActionListener action_listener) { + mManager.discoverPeers(mChannel, action_listener); + } + + public ArrayList getArrayList() { + return arrayList; + } + + public void setArrayList(ArrayList arrayList) { + this.arrayList = arrayList; + sendUpdateUIBroadcast(); + } + + public void setConnectionStateChanged(WifiP2pInfo p2p_info, NetworkInfo network_info, WifiP2pGroup p2p_group) { + this.p2p_info = p2p_info; + this.network_info = network_info; + this.p2p_group = p2p_group; + sendUpdateUIBroadcast(); + } + + private void sendUpdateUIBroadcast(){ + Intent local = new Intent(); + local.setAction("jenny.daniel.wifip2p.update_ui"); + this.sendBroadcast(local); + } + + private void sendUpdateUIBroadcastWithMessage(String message){ + Intent local = new Intent(); + local.putExtra("message", message); + local.setAction("jenny.daniel.wifip2p.update_ui"); + this.sendBroadcast(local); + } + + public void connect(String address, WifiP2pManager.ActionListener actionListener) { + WifiP2pDevice device; + WifiP2pConfig config = new WifiP2pConfig(); + config.deviceAddress = address; + mManager.connect(mChannel, config, actionListener); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/icon_refresh.png b/app/src/main/res/drawable/icon_refresh.png new file mode 100644 index 0000000..208a333 Binary files /dev/null and b/app/src/main/res/drawable/icon_refresh.png differ diff --git a/app/src/main/res/drawable/icon_send.png b/app/src/main/res/drawable/icon_send.png new file mode 100644 index 0000000..273157e Binary files /dev/null and b/app/src/main/res/drawable/icon_send.png differ diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml new file mode 100644 index 0000000..c4f8d47 --- /dev/null +++ b/app/src/main/res/layout/activity_chat.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + +