Created
January 4, 2017 07:30
-
-
Save EXJUSTICE/25657f080131d4b14528983006fbf272 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.xu.consent; | |
import android.app.Activity; | |
import android.content.BroadcastReceiver; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.content.IntentFilter; | |
import android.content.SharedPreferences; | |
import android.net.wifi.p2p.WifiP2pConfig; | |
import android.net.wifi.p2p.WifiP2pDevice; | |
import android.net.wifi.p2p.WifiP2pDeviceList; | |
import android.net.wifi.p2p.WifiP2pManager; | |
import android.net.wifi.p2p.WifiP2pManager.ActionListener; | |
import android.net.wifi.p2p.WifiP2pManager.Channel; | |
import android.net.wifi.p2p.WifiP2pManager.ChannelListener; | |
import android.os.Bundle; | |
import android.preference.PreferenceManager; | |
import android.provider.Settings; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.Toolbar; | |
import android.util.Log; | |
import android.view.Menu; | |
import android.view.MenuInflater; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.widget.Toast; | |
import java.util.ArrayList; | |
import java.util.List; | |
//Add in proper stamp callbacks when events take place | |
/** | |
Host Activity handling WIFI Direct, displaying two fragments along with listeners. Code will be explained | |
This should be the second activity, after loginActivity. Following this, | |
We would launch consentActivity | |
Unfourtuantely in its curent state, only clients can send info to GroupOwner | |
*A client can only begin a file transfer if it is not the P2P group owner. If the client | |
is the P2P owner, it cannot open a TCP socket since the Android WiFi direct API does not | |
provide a mechanism to retrieve the InetAddress (IP address) of any peer other than the | |
P2P group owner. This issue can be resolved upon finding a means to determine the IP | |
address of any given peer in the P2P group. | |
*/ | |
public class WIFIDirectActivity extends AppCompatActivity implements ChannelListener, DeviceListFragment.DeviceActionListener { | |
public static final String TAG ="wifidirectdemo"; | |
private WifiP2pManager manager; | |
private boolean isWifiP2pEnabled; | |
private boolean retryChannel = false; | |
private final IntentFilter intentFilter = new IntentFilter(); | |
private Channel channel; | |
private BroadcastReceiver receiver =null; | |
public static String username; | |
SharedPreferences mPrefs; | |
boolean welcomeScreenShown; | |
boolean firstTime; | |
//instead of local ArrayList, we use a globalDB | |
public void setIsWifiP2pEnabled (boolean isWifiP2pEnabled){ | |
this.isWifiP2pEnabled=isWifiP2pEnabled; | |
} | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_wifi); | |
//add necessary intent values to be matched with BroadcastReceiver | |
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); | |
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); | |
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); | |
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); | |
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | |
setSupportActionBar(toolbar); | |
//Fetch name first of our logged in user, will have to pass it to client as well | |
Intent fetchname = getIntent(); | |
username = fetchname.getStringExtra("username"); | |
//fetch singletoninstance, should be first instance for this particular situation | |
/*1. Initialize Manager and Channel. Manager needed to handle P2p and is called first, | |
Channel needed to connect to WIfi Direct Framework | |
All these details and activity reference needed for Registering with BroadCastReceiver | |
*/ | |
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); | |
channel = manager.initialize(this, getMainLooper(), null); | |
//Check if first time running, inflate WelcomeFragment if necessary | |
mPrefs = PreferenceManager.getDefaultSharedPreferences(this); | |
// second argument is the default to use if the preference can't be found | |
welcomeScreenShown = mPrefs.getBoolean("welcomeShown", false); | |
firstTime = mPrefs.getBoolean("firstTimeWelcome", false); | |
if (!welcomeScreenShown && firstTime == true) { | |
// the code below will display a popup welcome screen | |
WelcomeFragment welcome = new WelcomeFragment(); | |
welcome.show(this.getSupportFragmentManager(), "Welcome to HanGO"); | |
} | |
} | |
@Override | |
public void onResume(){ | |
super.onResume(); | |
receiver = new WifiDirectBroadcastReceiver(manager, channel,this); | |
//Allow receiver to not only send info back to DirectActivity, | |
// but also have access to Wifi and channel stuff if needed | |
registerReceiver(receiver, intentFilter); | |
} | |
@Override | |
public void onPause(){ | |
super.onPause(); | |
unregisterReceiver(receiver); | |
} | |
//resetData method clears all fields, remove peers, called | |
//When BroadcastReceiver receives state change | |
public void resetData(){ | |
//Find all frags first, written in XML | |
DeviceListFragment fragmentList = (DeviceListFragment)getFragmentManager() | |
.findFragmentById(R.id.frag_list); | |
DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) | |
getFragmentManager() | |
.findFragmentById(R.id.frag_detail); | |
if(fragmentList != null){ | |
fragmentList.clearPeers(); | |
} | |
if(fragmentDetails != null){ | |
fragmentDetails.resetViews(); | |
} | |
} | |
//Handling option Menu inflation and calls | |
@Override | |
public boolean onCreateOptionsMenu (Menu menu){ | |
MenuInflater inflater = getMenuInflater(); | |
inflater.inflate(R.menu.action_items,menu); | |
return true; | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
switch (item.getItemId()) { | |
case R.id.atn_direct_enable: | |
//Check first we have access to Wifi Manager and channel to access framework | |
if (manager != null && channel != null) { | |
/*Since this is android System wireless settings | |
Hence, we will not receive DIRECT result | |
Notification via WifiBroadCastReceiver instead | |
*/ | |
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); | |
} else { | |
Log.e(TAG, "Channel or manager is null"); | |
} | |
return true; | |
case R.id.atn_direct_discover: | |
//Clicked discover, initialize fragments and discover available peers | |
if (!isWifiP2pEnabled) { | |
Toast.makeText(WIFIDirectActivity.this, "WifiDirect is not enabled", Toast.LENGTH_SHORT).show(); | |
return true; | |
} | |
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager() | |
.findFragmentById(R.id.frag_list); | |
fragment.onInitiateDiscovery(); | |
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { | |
@Override | |
public void onSuccess() { | |
Toast.makeText(WIFIDirectActivity.this, "Discovery Initiated", | |
Toast.LENGTH_SHORT).show(); | |
//OnSuccess and DiscoverPeers are only to show that Discovery process is working | |
//Actual list of peers is done in broadcastReceiver: | |
//1. When System detects peers, Activity broadcasts WIFI_P2P_CHANGED_ACTION | |
//2. BroadCastReceiver receives intent, and calls requestPeers(); | |
//3. Receiver displays all peers in listfragments | |
} | |
@Override | |
public void onFailure(int reasonCode) { | |
Toast.makeText(WIFIDirectActivity.this, "Discovery failed" + reasonCode, Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
return true; | |
default: | |
return super.onOptionsItemSelected(item); | |
} | |
} | |
//WifiDirectActivity's ShowDetails is the initially called version, which forwards to fragments showDetails, | |
//Which does what? | |
@Override | |
public void showDetails(WifiP2pDevice device){ | |
DeviceDetailFragment fragment = (DeviceDetailFragment)getFragmentManager().findFragmentById(R.id.frag_detail); | |
fragment.showDetails(device); | |
} | |
//Similiar to OnOptionsSelected's discoverPeers, we are usuing Managers connect to connect | |
//P2PConfig icnludes info on TARGET DEVICE | |
@Override | |
public void connect(WifiP2pConfig config){ | |
manager.connect(channel, config, new ActionListener() { | |
@Override | |
public void onSuccess() { | |
//WifiDirectBroadcast will notify us | |
logconnect(); | |
//For debugging | |
Intent startConsentActivity = new Intent(WIFIDirectActivity.this, ConsentActivity.class); | |
startActivity(startConsentActivity); | |
} | |
@Override | |
public void onFailure(int i) { | |
Toast.makeText(WIFIDirectActivity.this,"Connect failed. Retry.",Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} | |
@Override | |
public void disconnect(){ | |
final DeviceDetailFragment fragment = (DeviceDetailFragment)getFragmentManager() | |
.findFragmentById(R.id.frag_detail); | |
fragment.resetViews(); | |
/* | |
The device that creates the group, | |
becomes Group owner, which others can connect as clients | |
*/ | |
//Cant initialize History fragment via same method since its not a part of WifiDirectActivity's XML, | |
//may have to create singleton DB class instead. | |
logdisconnect(); | |
manager.removeGroup(channel, new ActionListener() { | |
@Override | |
public void onSuccess() { | |
//getView currently doesnt exist becaause fragment doesnt exist | |
fragment.getView().setVisibility(View.GONE); | |
} | |
@Override | |
public void onFailure(int reasonCode) { | |
Log.d(TAG,"Disconnect failed" +reasonCode); | |
} | |
}); | |
} | |
//if channel disconnected, try again, if fail, then decalre lost | |
@Override | |
public void onChannelDisconnected(){ | |
if (manager != null && !retryChannel){ | |
Toast.makeText(this, "Channel lost, trying again",Toast.LENGTH_SHORT).show(); | |
resetData(); | |
retryChannel=true; | |
manager.initialize(this,getMainLooper(),this); | |
}else{ | |
Toast.makeText(this,"error, try to renable p2p",Toast.LENGTH_SHORT).show(); | |
} | |
} | |
@Override | |
public void cancelDisconnect(){ | |
/* User actively aborts an connection attempt | |
if already connected, removeGroup | |
else, abort ongoing request through Manager | |
*/ | |
if(manager!= null){ | |
final DeviceListFragment fragment = (DeviceListFragment)getFragmentManager().findFragmentById(R.id.frag_list); | |
if(fragment.getDevice() ==null || fragment.getDevice().status== WifiP2pDevice.CONNECTED){ | |
disconnect(); | |
}else if(fragment.getDevice().status == WifiP2pDevice.AVAILABLE || fragment.getDevice().status ==WifiP2pDevice.INVITED){ | |
manager.cancelConnect(channel, new ActionListener() { | |
@Override | |
public void onSuccess() { | |
Toast.makeText(WIFIDirectActivity.this,"Aborting",Toast.LENGTH_SHORT).show(); | |
} | |
public void onFailure(int reasonCode){ | |
Toast.makeText(WIFIDirectActivity.this, "Abort failed" +reasonCode,Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} | |
} | |
logcancel(); | |
} | |
public void logconnect(){ | |
//maybe add in IPs later once w figure out wtf, passed through argument | |
//sdb.addStamp(new Stamp(System.currentTimeMillis(),"connection established")); | |
} | |
public void logdisconnect(){ | |
//sdb.addStamp(new Stamp(System.currentTimeMillis(),"connection disconnected")); | |
} | |
public void logcancel(){ | |
//sdb.addStamp(new Stamp(System.currentTimeMillis(),"connection cancelled by user")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment