Commit 5b712bad authored by Albert Vaca Cintora's avatar Albert Vaca Cintora

Initial commit

parents
local.properties
.gradle
.idea
out
<?xml version="1.0" encoding="UTF-8"?>
<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":" />
<option name="PROJECT_ABSOLUTE_PATH" value="$MODULE_DIR$" />
<option name="GRADLE_HOME_DIR_PATH" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":KdeConnect" />
<option name="PROJECT_ABSOLUTE_PATH" value="$MODULE_DIR$/.." />
<option name="GRADLE_HOME_DIR_PATH" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/apk" />
<excludeFolder url="file://$MODULE_DIR$/build/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/exploded-bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android 4.2.2" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="android-support-v4" level="project" />
</component>
</module>
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4'
}
}
apply plugin: 'android'
dependencies {
compile files('libs/android-support-v4.jar')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 7
targetSdkVersion 16
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.kde.connect"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="org.kde.connect.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:enabled="true"
android:name=".BackgroundService">
</service>
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
</manifest>
package org.kde.connect;
import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdServiceInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import org.kde.connect.Receivers.BaseReceiver;
import org.kde.connect.Receivers.PhoneCallReceiver;
import org.kde.connect.Types.NetworkPackage;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
public class BackgroundService extends Service {
ArrayList<BaseReceiver> receivers = new ArrayList<BaseReceiver>();
DesktopCommunication dc = new DesktopCommunication();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("BackgroundService","Starting");
SharedPreferences settings = getSharedPreferences("KdeConnect", 0);
if (settings.getBoolean("listenCalls", true)) {
receivers.add(new PhoneCallReceiver(getApplicationContext(), dc));
}
NetworkPackage p = new NetworkPackage(System.currentTimeMillis());
p.setType(NetworkPackage.Type.PING);
dc.asyncSend(p.toString());
return Service.START_STICKY;
}
@Override
public void onCreate() {
Log.e("BackgroundService","Creating");
super.onCreate();
}
@Override
public void onDestroy() {
Log.e("BackgroundService","Destroying");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
Log.e("BackgroundService", "Binding");
return null;
}
}
package org.kde.connect;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class BootReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
if (intent.getAction() != Intent.ACTION_BOOT_COMPLETED) {
Log.w("KdeConnect", "Received unexpected intent: " + intent);
} else {
Log.i("KdeConnect", "BootReceiver");
context.startService(new Intent(context,BackgroundService.class));
}
}
}
package org.kde.connect;
import android.os.AsyncTask;
import android.util.Log;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class DesktopCommunication {
final int UDP_PORT = 10600;
final String IP = "192.168.1.48";
public void asyncSend(final String messageStr) {
new AsyncTask<Void,Void,Void>(){
@Override
protected Void doInBackground(Void... voids) {
try {
int server_port = UDP_PORT;
DatagramSocket s = new DatagramSocket();
InetAddress local = InetAddress.getByName(IP);
int msg_length = messageStr.length();
byte[] message = messageStr.getBytes();
DatagramPacket p = new DatagramPacket(message, msg_length,local,server_port);
s.send(p);
Log.e("Sent", messageStr);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
package org.kde.connect;
import android.app.Activity;
import android.content.Intent;
import android.net.nsd.NsdServiceInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
//http://developer.android.com/training/connect-devices-wirelessly/nsd.html
public void registerService(int port) {
// Create the NsdServiceInfo object, and populate it.
NsdServiceInfo serviceInfo = new NsdServiceInfo();
// The name is subject to change based on conflicts
// with other services advertised on the same network.
serviceInfo.setServiceName("NsdChat");
serviceInfo.setServiceType("_http._tcp.");
serviceInfo.setPort(port);
//....
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent service = new Intent(MainActivity.this, BackgroundService.class);
startService(service);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
package org.kde.connect.Receivers;
import android.content.Context;
public interface BaseReceiver {
}
package org.kde.connect.Receivers;
import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import org.kde.connect.DesktopCommunication;
import org.kde.connect.Types.NetworkPackage;
public class PhoneCallReceiver implements BaseReceiver {
public PhoneCallReceiver(final Context ctx, final DesktopCommunication dc) {
Log.i("PhoneCallReceiver", "Registered");
PhoneStateListener callStateListener = new PhoneStateListener() {
int lastState = TelephonyManager.CALL_STATE_IDLE;
NetworkPackage lastPackage;
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Log.i("IncomingCall", incomingNumber);
lastPackage = new NetworkPackage(System.currentTimeMillis());
lastPackage.setType(NetworkPackage.Type.RING);
lastPackage.setBody(incomingNumber);
dc.asyncSend(lastPackage.toString());
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //Ongoing call
if (lastPackage != null) {
lastPackage.cancel();
dc.asyncSend(lastPackage.toString());
lastPackage = null;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (lastState != TelephonyManager.CALL_STATE_IDLE && lastPackage != null) {
lastPackage.cancel();
dc.asyncSend(lastPackage.toString());
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
String number = lastPackage.getBody();
lastPackage = new NetworkPackage(System.currentTimeMillis());
lastPackage.setType(NetworkPackage.Type.MISSED);
lastPackage.setBody(incomingNumber);
dc.asyncSend(lastPackage.toString());
}
}
lastPackage = null;
break;
}
lastState = state;
}
};
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
package org.kde.connect.Types;
import org.json.JSONObject;
import java.util.Calendar;
import java.util.TimeZone;
public class NetworkPackage {
public enum Type {
UNKNOWN,
RING,
MISSED,
SMS,
BATTERY,
NOTIFY,
PING,
TYPE_SIZE
}
private long mId;
private long mDeviceId;
private long mTime; //since epoch, utc
private Type mType;
private String mBody;
private boolean mIsCancel;
private JSONObject mExtras; //JSON
public NetworkPackage(long id) {
mId = id;
mDeviceId = 42;
mTime = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() / 1000L;
mType = Type.UNKNOWN;
mBody = "";
mIsCancel = false;
mExtras = new JSONObject();
}
public void setType(Type type) {
mType = type;
}
public void setBody(String body) {
mBody = body;
}
public String getBody() {
return mBody;
}
public Type getType() {
return mType;
}
public void updateTime() {
mTime = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() / 1000L;
}
public void cancel() {
mIsCancel = true;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(mId);
sb.append(' ');
sb.append(mDeviceId);
sb.append(' ');
sb.append(mTime);
sb.append(' ');
sb.append(mType.toString());
sb.append(' ');
sb.append(mBody.length());
sb.append(' ');
sb.append(mBody);
sb.append(' ');
sb.append(mIsCancel?'1':'0');
sb.append(' ');
sb.append(mExtras.length());
sb.append(' ');
sb.append(mExtras);
sb.append("END");
return sb.toString();
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:orientation="vertical">
<Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Launch service"/>
</LinearLayout>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
android:showAsAction="never" />
</menu>
<resources>
<!-- Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw600dp devices (e.g. 7" tablets) here. -->
</resources>
<resources>
<!-- Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
<dimen name="activity_horizontal_margin">128dp</dimen>
</resources>
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" >KdeConnect
</string>
<string name="action_settings" >Settings
</string>
<string name="hello_world" >Hello world!
</string>
</resources>
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>
// Top-level build file where you can add configuration options common to all sub-projects/modules.
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}