Skip to content

Instantly share code, notes, and snippets.

@EXJUSTICE
Created January 4, 2017 07:33
Show Gist options
  • Save EXJUSTICE/e70169b64ac3b7feca3f945164b62781 to your computer and use it in GitHub Desktop.
Save EXJUSTICE/e70169b64ac3b7feca3f945164b62781 to your computer and use it in GitHub Desktop.
package com.xu.consent;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.xu.consent.DeviceListFragment.DeviceActionListener;
/**
* This Fragment shows the status of the client your connecting to as the owner
* ConnectionInfoListener's callback onConnectionAvailable is called
* by Receiver's requestConnectionInfo, Which is itself called when connection made
*/
public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
//DeviceList Fragment will call WifiDirectActivity's ShowDetails(device)
//Which passes along target device data
protected static final int CHOOSE_FILE_RESULT_CODE= 20;
private View mContentView = null;
public WifiP2pDevice device;
public WifiP2pInfo info;
ProgressDialog progressDialog=null;
SharedPreferences received;
SharedPreferences.Editor receivededitor;
SharedPreferences gOwnerStatus;
SharedPreferences.Editor ownereditor;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
//onCreateView is called already by Activity, since our fragments are in xml
mContentView = inflater.inflate(R.layout.device_detail, null);
mContentView.findViewById(R.id.btn_connect).setOnClickListener (new View.OnClickListener(){
@Override
public void onClick(View v){
WifiP2pConfig config= new WifiP2pConfig();
//P2P device data gained from showDetails(), called initially by activity
config.deviceAddress = device.deviceAddress;
//
config.wps.setup = WpsInfo.PBC;
if(progressDialog != null && progressDialog.isShowing()){
progressDialog.dismiss();
}
progressDialog = progressDialog.show(getActivity(),"Press back to cancel",
"Connecting to :"+device.deviceAddress,true, true
// new DialogInterface.OnCancelListener() {
//
// @Override
// public void onCancel(DialogInterface dialog) {
// ((DeviceActionListener) getActivity()).cancelDisconnect();
// }
// }
);
//Automatically connect using WifiDirectActivity and subsequently BroadcastRecevier
((DeviceActionListener) getActivity()).connect(config);
}
});
mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
((DeviceActionListener) getActivity()).disconnect();
}
});
mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
//24-12-2016 removed all image code + onactivity result, skipping straight to start service intent
//Gotta add in the ability to READ stuff to write a test
//All of this code below wrt to serviceIntent could be transfered to our Consent activity right?
TextView status = (TextView)mContentView.findViewById(R.id.status_text);
status.setText("Sending strings");
Log.d(WIFIDirectActivity.TAG,"Intent---");
//Now look to start Service with File transfer
Intent serviceIntent= new Intent(getActivity(),FileTransferService.class);
//Define Intent type, effectively intent filter
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
//Info isnt initialized though?
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, info.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
//finally, add in the username from WIFIDirectActivity, passed from FB login
serviceIntent.putExtra("username",WIFIDirectActivity.username);
getActivity().startService(serviceIntent);
}
});
//Return the view once all buttons are registered
return mContentView;
}
// Not sure if this would work at all, would need
public static void sendFilesFromConsentActivity(Activity activity, String GroupOwnerAddress, String input){
//How to pass in the Device Info?
Log.d(WIFIDirectActivity.TAG,"Intent---");
//Now look to start Service with File transfer
Intent serviceIntent= new Intent(activity,FileTransferService.class);
//Define Intent type, effectively intent filter
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
//Info isnt initialized though?
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS, GroupOwnerAddress);
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
//finally, add in the username from WIFIDirectActivity, passed from FB login
serviceIntent.putExtra("username",WIFIDirectActivity.username);
serviceIntent.putExtra("input",input);
activity.startService(serviceIntent);
}
//This is called by OnConnectionInfoListener, by requestConnectionInfo, holds all TARGET device details
//Negotiation over group ownership
//Begin connection over client and whatever
@Override
public void onConnectionInfoAvailable(final WifiP2pInfo info){
if (progressDialog !=null && progressDialog.isShowing()){
progressDialog.dismiss();
}
this.info = info;
this.getView().setVisibility(View.VISIBLE);
//Owner IP is now known
TextView view = (TextView)mContentView.findViewById(R.id.group_owner);
view.setText(getResources().getString(R.string.group_owner_text)+((info.isGroupOwner==true)? getResources().getString(R.string.yes)
:getResources().getString(R.string.no)));
//Fetch groupownerAddress
view = (TextView)mContentView.findViewById(R.id.device_info);
view.setText("Group owner IP =" + info.groupOwnerAddress.getHostAddress());
//Post negotiation, assign group owner as file server, -------------------------------------------------------------------------FileAsyncTask Launch here, RECEIVING/ GROUP OWNER SERVER
if (info.groupFormed && info.isGroupOwner){
//Should this code be here or in ConsentActivity?
new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
.execute();
//Launch ConsentActivity as servr/group owner, disabling buttons
gOwnerStatus =getActivity().getSharedPreferences("gOwnerStatus",Context.MODE_PRIVATE);
ownereditor = gOwnerStatus.edit();
ownereditor.putBoolean("isGroupOwner",true);
ownereditor.commit();
//Intent startConsentActivityasOwner = new Intent(getActivity(), ConsentActivity.class);
//startConsentActivityasOwner.putExtra("isGroupOwner",true);
//startActivity(startConsentActivityasOwner);
}else if (info.groupFormed){
//Post negotiation, if other device is the client, we enable the start client button on client device, and for US refer to code above
mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
((TextView)mContentView.findViewById(R.id.status_text)).setText(getResources().getString(R.string.client_text));
gOwnerStatus =getActivity().getSharedPreferences("gOwnerStatus",Context.MODE_PRIVATE);
ownereditor = gOwnerStatus.edit();
ownereditor.putBoolean("isGroupOwner",false);
ownereditor.putString("GroupOwnerAddress", info.groupOwnerAddress.getHostAddress());
ownereditor.putString("GroupOwnerPort","8988");
ownereditor.commit();
/*Intent startConsentActivityasClient = new Intent(getActivity(),ConsentActivity.class);
startConsentActivityasClient.putExtra("GroupOwnerAddress", info.groupOwnerAddress.getHostAddress());
startConsentActivityasClient.putExtra("GroupOwnerPort",8988);
startActivity(startConsentActivityasClient);
*/
}
//We are already connected, so hide connect button
mContentView.findViewById(R.id.btn_connect).setVisibility(view.GONE);
}
//Called by WifiDirecActivity's showDetails on targetDevice
//Shows target device data
public void showDetails(WifiP2pDevice device){
this.device = device;
this.getView().setVisibility(View.VISIBLE);
TextView view = (TextView)mContentView.findViewById(R.id.device_address);
view.setText(device.deviceAddress);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(device.toString());;
}
//clearing UI fields of DETAILFRAG after disconnect or direct mode disable operation
public void resetViews(){
mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
TextView view = (TextView)mContentView.findViewById(R.id.device_address);
view.setText("");
view = (TextView)mContentView.findViewById(R.id.device_info);
view.setText("");
view = (TextView)mContentView.findViewById(R.id.group_owner);
view.setText("");
view = (TextView)mContentView.findViewById(R.id.status_text);
view.setText("");
mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
this.getView().setVisibility(View.GONE);
}
/* Part of DeviceDetailFragment
Server socket set up for when device ACTS AS A OWNER
Write the inputStream into a FILE, in this case JPEG
*/
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String>{
private Context context;
private TextView statusText;
String incoming;
ArrayList<String>receivedStrings;
SharedPreferences received;
SharedPreferences.Editor receivedEditor;
public FileServerAsyncTask(Context context, View statusText){
this.context = context;
this.statusText =(TextView)statusText;
received = context.getSharedPreferences("received", Context.MODE_PRIVATE);
receivedEditor = received.edit();
}
@Override
protected String doInBackground(Void... params){
try {
ServerSocket serverSocket = new ServerSocket(8988);
Log.d(WIFIDirectActivity.TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.d(WIFIDirectActivity.TAG, "Server: connection done");
DataInputStream ds= new DataInputStream(client.getInputStream());
//could potentially get client IP and name passed from FB?
//How to separate inputstream?
incoming= ds.readUTF();
//split received hueg string thing by arrays
receivedStrings = new ArrayList<String>(Arrays.asList(incoming.split(",")));
for (int i = 0; i<receivedStrings.size();i++){
//add receivedStrings into sharedprefs storage
receivedEditor.putString(Integer.toString(i),receivedStrings.get(i));
}
Log.d(WIFIDirectActivity.TAG, "server: copying strings to local list");
serverSocket.close();
return incoming;
}catch (IOException e){
Log.e(WIFIDirectActivity.TAG, e.getMessage());
return null;
}
}
@Override
protected void onPostExecute(String result){
//Necessary to return to consent manually?
}
@Override
protected void onPreExecute(){
statusText.setText("Opening server socket");
}
}
//Actual copyFile method, both for writing to server or to system- OUT OF DATE/ DEletable
public static boolean copyFile(InputStream inputStream, OutputStream out){
byte buf[] = new byte[1024];
int len;
long startTime =System.currentTimeMillis();
try {
while ((len = inputStream.read(buf))!= -1){
out.write(buf,0,len);
}
out.close();
inputStream.close();
long endTime = System.currentTimeMillis()-startTime;
Log.v("","Time taken to transfer all bytes" +endTime);
}catch(IOException e){
Log.d(WIFIDirectActivity.TAG,e.toString());
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment