package net.screenfreeze.deskcon;
import java.io.BufferedInputStream;
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.InetAddress;
import javax.net.ssl.SSLSocket;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
public class SendFilesService extends Service {
private static String UUID;
private static String PNAME;
private String HOST;
private int PORT;
private SharedPreferences sharedPrefs;
private static Toast ConnectionError;
public static Context context;
@SuppressLint("ShowToast")
@Override
public void onCreate() {
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
loadIdentifiers();
ConnectionError = Toast.makeText(getApplicationContext(), "could not connect to "+HOST, Toast.LENGTH_SHORT);
super.onCreate();
}
private void loadIdentifiers() {
UUID = sharedPrefs.getString("uuid", "0000000011111111");
String storedname = sharedPrefs.getString("device_name", "");
if (storedname.equals("")) {
PNAME = android.os.Build.MODEL;
}
else {
PNAME = storedname;
}
}
@SuppressLint("NewApi")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle extras = intent.getExtras();
context = this;
HOST = extras.getString("host");
PORT = extras.getInt("port");
if (extras != null) {
SendFilesClient sfclient = new SendFilesClient();
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
sfclient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, extras);
} else {
sfclient.execute(extras);
}
}
return super.onStartCommand(intent, flags, startId);
}
private class SendFilesClient extends AsyncTask<Bundle, Void, Void> {
private String type;
private String[] filepaths;
@Override
protected Void doInBackground(Bundle... params) {
Bundle data = params[0];
type = "FILE_UP";
filepaths = data.getStringArray("filepaths");
try {
sendData();
} catch (Exception e) {
e.printStackTrace();
}
stopSelf();
return null;
}
// Building Protocol MSG
private String buildmsg(String type, String[] filenames) {
JSONObject jobject = new JSONObject();
JSONArray jarray = new JSONArray();
for (int i=0; i<filenames.length; i++){
jarray.put(filenames[i]);
}
try {
jobject.put("uuid", UUID);
jobject.put("devicename", PNAME);
jobject.put("type", type);
jobject.put("data", jarray.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return jobject.toString();
}
// sendfile
private void sendFile(Uri f, SSLSocket sslsocket) throws Exception {
byte [] buffer = new byte [4096];
long filesize = getFileSize(f);
InputStream is = getContentResolver().openInputStream(f);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream outputstream = sslsocket.getOutputStream();
InputStream inputstream = sslsocket.getInputStream();
// send file size
outputstream.write(String.valueOf(filesize).getBytes());
// wait for ready
inputstream.read();
long cnt = Math.round(filesize / 4096)+1;
for (long i=0; i < cnt; i++) {
int bytesread = bis.read(buffer, 0, 4096);
outputstream.write(buffer, 0 ,bytesread);
outputstream.flush();
}
}
private void sendData() throws Exception {
// create Filehandler
Uri[] fileUris = new Uri[filepaths.length];
String[] filenames = new String[filepaths.length];
for (int i=0; i< fileUris.length; i++) {
if (filepaths[i].startsWith("content://com.google.android.gallery3d.provider/picasa/")){
fileUris[i] = cachePicasaFile(Uri.parse(filepaths[i])); // Picasa workaround
}
else {
fileUris[i] = Uri.parse(filepaths[i]);
}
filenames[i] = getFileName(fileUris[i]);
}
String msg = buildmsg(type, filenames);
SSLSocket sslsocket;
try {
HOST = InetAddress.getByName(HOST).getHostAddress();
// create SSL Connection
sslsocket = Connection.createSSLSocket(getApplicationContext(), HOST, PORT);
} catch (Exception e) {
Log.d("Connection: ", "could not connect");
ConnectionError.show();
return;
}
// write data
OutputStream out = sslsocket.getOutputStream();
DataInputStream in = new DataInputStream(sslsocket.getInputStream());
//Ask Host for Conformation
out.write(msg.getBytes());
//wait for ACK from Server
Log.d("FileUp: ", "wait for Ack");
int return_code = in.read();
// send a File
if (return_code == 49) {
for (int j=0; j<fileUris.length ;j++) {
Uri file = fileUris[j];
sendFile(file, sslsocket);
}
}
}
}
// Workaround ,because of a Google Bug!
private Uri cachePicasaFile(Uri contentUri) throws IOException {
String fname = getFileName(contentUri);
File cDir = getBaseContext().getCacheDir();
File tempFile = new File(cDir.getPath() + "/" + fname) ;
InputStream is = getContentResolver().openInputStream(contentUri);
BufferedInputStream bis = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(tempFile);
long filesize = getFileSize(contentUri);
byte[] buffer = new byte[4096];
long cnt = Math.round(filesize / 4096)+1;
for (long i=0; i < cnt; i++) {
int bytesread = bis.read(buffer, 0, 4096);
fos.write(buffer, 0 ,bytesread);
fos.flush();
}
fos.close();
Uri uri = Uri.fromFile(tempFile);
return uri;
}
private long getFileSize(Uri contentUri) {
if (contentUri.getScheme().equals("file")) {
File f = new File(contentUri.getPath());
return f.length();
}
else {
String [] proj={MediaStore.Images.Media.SIZE};
Cursor cursor = getBaseContext().getContentResolver().query( contentUri,
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
cursor.moveToFirst();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
long size = cursor.getLong(column_index);
cursor.close();
return size;
}
}
private String getFileName(Uri contentUri) {
if (contentUri.getScheme().equals("file")) {
return contentUri.getLastPathSegment();
}
else {
String [] proj={MediaStore.Images.Media.DISPLAY_NAME};
Cursor cursor = getBaseContext().getContentResolver().query( contentUri,
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
cursor.moveToFirst();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
String name = cursor.getString(column_index);
cursor.close();
return name;
}
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}