3 | # Encoding is UTF-8
4 |
--------------------------------------------------------------------------------
/bin/classes/com/google/android/gms/R$integer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/google/android/gms/R$integer.class
--------------------------------------------------------------------------------
/bin/classes/com/google/android/gms/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/google/android/gms/R$string.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/AudioPlayer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/AudioPlayer.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/BuildConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/BuildConfig.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/DeviceAdmin.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/DeviceAdmin.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/Flashlight.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/Flashlight.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/R$drawable.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/R$styleable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/R$styleable.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/UploadFile.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/UploadFile.class
--------------------------------------------------------------------------------
/bin/res/crunch/drawable-hdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/res/crunch/drawable-hdpi/notification_icon.png
--------------------------------------------------------------------------------
/bin/res/crunch/drawable-mdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/res/crunch/drawable-mdpi/notification_icon.png
--------------------------------------------------------------------------------
/bin/classes/com/google/android/gms/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/google/android/gms/R$drawable.class
--------------------------------------------------------------------------------
/bin/classes/com/google/android/gms/R$styleable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/google/android/gms/R$styleable.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/AudioPlayer$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/AudioPlayer$1.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/BootReceiver.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/BootReceiver.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/CallLogGetter.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/CallLogGetter.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/ContactObject.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/ContactObject.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/FileUtilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/FileUtilities.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/MainActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/MainActivity$1.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/MainActivity$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/MainActivity$2.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/MainActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/MainActivity.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/MessageAction.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/MessageAction.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/SMSUtilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/SMSUtilities.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/SoundRecorder.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/SoundRecorder.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/WebpageOpener.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/WebpageOpener.class
--------------------------------------------------------------------------------
/bin/res/crunch/drawable-xxhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/res/crunch/drawable-xxhdpi/notification_icon.png
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/CommonUtilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/CommonUtilities.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/ContactsFetcher.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/ContactsFetcher.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/GCMIntentService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/GCMIntentService.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/LocationService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/LocationService.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/RegisterActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/RegisterActivity.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/SendNotification.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/SendNotification.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/ServerUtilities.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/ServerUtilities.class
--------------------------------------------------------------------------------
/bin/dexedLibs/gcm-2d66078dca4286b76c17d4f4414cc87f.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/gcm-2d66078dca4286b76c17d4f4414cc87f.jar
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/AlertDialogManager.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/AlertDialogManager.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/ConnectionDetector.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/ConnectionDetector.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/DeviceInformation.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/DeviceInformation.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/GCMHeartbeatAlarm.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/GCMHeartbeatAlarm.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/GetBrowserHistory.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/GetBrowserHistory.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/Manifest$permission.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/Manifest$permission.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/RegisterActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/RegisterActivity$1.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/RegisterActivity$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/RegisterActivity$2.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/AlertDialogManager$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/AlertDialogManager$1.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/InstalledAppsFetcher.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/InstalledAppsFetcher.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/SMSUtilities$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/SMSUtilities$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/UploadFile$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/UploadFile$MyAsyncTask.class
--------------------------------------------------------------------------------
/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/CallLogGetter$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/CallLogGetter$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/FileUtilities$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/FileUtilities$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/SoundRecorder$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/SoundRecorder$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/dexedLibs/httpcore-4.3.3-2e737fd43fe53a608dc6d2795937448a.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/httpcore-4.3.3-2e737fd43fe53a608dc6d2795937448a.jar
--------------------------------------------------------------------------------
/bin/dexedLibs/httpmime-4.3.6-bd7615789073fef68f59496953f45bb3.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/httpmime-4.3.6-bd7615789073fef68f59496953f45bb3.jar
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/ContactsFetcher$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/ContactsFetcher$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/DeviceInformation$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/DeviceInformation$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/GetBrowserHistory$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/GetBrowserHistory$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/LocationService$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/LocationService$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/dexedLibs/httpclient-4.3.6-011ac456dad81afde3b7981bab230ea1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/httpclient-4.3.6-011ac456dad81afde3b7981bab230ea1.jar
--------------------------------------------------------------------------------
/bin/dexedLibs/android-support-v4-3c521ca09da189a3aade50fe93762a74.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/android-support-v4-3c521ca09da189a3aade50fe93762a74.jar
--------------------------------------------------------------------------------
/bin/classes/com/monitordroid/app/InstalledAppsFetcher$MyAsyncTask.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/classes/com/monitordroid/app/InstalledAppsFetcher$MyAsyncTask.class
--------------------------------------------------------------------------------
/bin/dexedLibs/google-play-services-dcddfb676741990ec2dc0b33b35abd6a.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/google-play-services-dcddfb676741990ec2dc0b33b35abd6a.jar
--------------------------------------------------------------------------------
/bin/dexedLibs/apache-mime4j-core-0.7.2-aefa4df7efd0a12f1589c925f2983ecc.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/apache-mime4j-core-0.7.2-aefa4df7efd0a12f1589c925f2983ecc.jar
--------------------------------------------------------------------------------
/bin/dexedLibs/google-play-services_lib-acc6f2a316df6fb304eed9781de67e0c.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tyler124/Monitordroid/HEAD/bin/dexedLibs/google-play-services_lib-acc6f2a316df6fb304eed9781de67e0c.jar
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8dp
4 | 8dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/res/values-large/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8dp
4 | 16dp
5 | 16dp
6 |
7 |
--------------------------------------------------------------------------------
/gen/com/monitordroid/app/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.monitordroid.app;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/res/menu/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/res/xml/device_admin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/menu/options_menu.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/gen/com/monitordroid/app/Manifest.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.monitordroid.app;
9 |
10 | public final class Manifest {
11 | public static final class permission {
12 | /** Creates a custom permission so only this app can receive its messages.
13 | */
14 | public static final String C2D_MESSAGE="com.monitordroid.app.permission.C2D_MESSAGE";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # =========================
18 | # Operating System Files
19 | # =========================
20 |
21 | # OSX
22 | # =========================
23 |
24 | .DS_Store
25 | .AppleDouble
26 | .LSOverride
27 |
28 | # Icon must ends with two \r.
29 | Icon
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear on external disk
35 | .Spotlight-V100
36 | .Trashes
37 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 | android.library=false
16 | android.library.reference.1=../google-play-services_lib
17 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.6
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12 | org.eclipse.jdt.core.compiler.source=1.6
13 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Monitordroid
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/WebpageOpener.java:
--------------------------------------------------------------------------------
1 | package com.monitordroid.app;
2 |
3 | import android.content.ActivityNotFoundException;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.net.Uri;
7 |
8 | public class WebpageOpener {
9 |
10 | /**
11 | * Takes an input URL and opens it in the device's default web browser
12 | *
13 | * @param url
14 | * The URL to open on the device
15 | */
16 | public void openPage(Context context, String url) {
17 | try {
18 | // Make sure it starts with http:// or https://
19 | if (!url.startsWith("http://") && !url.startsWith("https://")) {
20 | url = "http://" + url;
21 |
22 | }
23 | Intent browserIntent = new Intent(Intent.ACTION_VIEW,
24 | Uri.parse(url));
25 | browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
26 | context.startActivity(browserIntent);
27 | }
28 | catch (ActivityNotFoundException e) {
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
22 | -keep class * extends java.util.ListResourceBundle {
23 | protected Object[][] getContents();
24 | }
25 |
26 | -keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
27 | public static final *** NULL;
28 | }
29 |
30 | -keepnames @com.google.android.gms.common.annotation.KeepName class *
31 | -keepclassmembernames class * {
32 | @com.google.android.gms.common.annotation.KeepName *;
33 | }
34 |
35 | -keepnames class * implements android.os.Parcelable {
36 | public static final ** CREATOR;
37 | }
--------------------------------------------------------------------------------
/src/com/monitordroid/app/BootReceiver.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.BroadcastReceiver;
22 | import android.content.Context;
23 | import android.content.Intent;
24 |
25 | public class BootReceiver extends BroadcastReceiver {
26 |
27 | /**
28 | * Method called when the device has successfully rebooted. Used to recreate
29 | * the alarm that keeps the GCM connection alive.
30 | */
31 | @Override
32 | public void onReceive(Context context, Intent intent) {
33 | try {
34 | if (intent.getAction().equals(
35 | "android.intent.action.BOOT_COMPLETED")) {
36 | GCMHeartbeatAlarm g = new GCMHeartbeatAlarm();
37 | g.setAlarm(context);
38 | }
39 | }
40 | catch (Exception e) {
41 |
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/Telephone.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.Context;
22 | import android.content.Intent;
23 | import android.net.Uri;
24 | import android.util.Log;
25 |
26 | public class Telephone {
27 |
28 | /**
29 | * Takes the input phone number and initiates a call to that number on the
30 | * device
31 | */
32 | public void callPhone(Context context, String phoneNumber) {
33 | String uri = "tel:" + phoneNumber.trim();
34 | Log.i("Telephone Number: ", uri);
35 | Intent intent = new Intent(Intent.ACTION_CALL);
36 | intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
37 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
38 | intent.setData(Uri.parse(uri));
39 | context.startActivity(intent);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/ContactObject.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | public class ContactObject {
22 | private String phoneNumber;
23 | private String name;
24 | private String email;
25 |
26 | public void setPhoneNumber(String address) {
27 | this.phoneNumber = address;
28 | }
29 |
30 | public void setName(String name) {
31 | this.name = name;
32 | }
33 |
34 | public void setEmail(String email) {
35 | this.email = email;
36 | }
37 |
38 | public String getPhoneNumber() {
39 | return this.phoneNumber;
40 | }
41 |
42 | public String getName() {
43 | return this.name;
44 | }
45 |
46 | public String getEmail() {
47 | return this.email;
48 | }
49 |
50 | public String toString() {
51 | if (email != null) {
52 | return "\n Name: " + name + "\n Phone Number: " + phoneNumber
53 | + "\n" + "Email: " + email + "\n";
54 | }
55 | else {
56 | return "\n Name: " + name + "\n Phone Number: " + phoneNumber
57 | + "\n";
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/ConnectionDetector.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.Context;
22 | import android.net.ConnectivityManager;
23 | import android.net.NetworkInfo;
24 |
25 | public class ConnectionDetector {
26 |
27 | private Context _context;
28 |
29 | public ConnectionDetector(Context context) {
30 | this._context = context;
31 | }
32 |
33 | /**
34 | * Checks whether the device has an internet connection
35 | *
36 | * @return True if the device has an active internet connection, false if
37 | * not
38 | **/
39 | public boolean isConnectingToInternet() {
40 | ConnectivityManager connectivity = (ConnectivityManager) _context
41 | .getSystemService(Context.CONNECTIVITY_SERVICE);
42 | if (connectivity != null) {
43 | NetworkInfo[] info = connectivity.getAllNetworkInfo();
44 | if (info != null)
45 | for (int i = 0; i < info.length; i++)
46 | if (info[i].getState() == NetworkInfo.State.CONNECTED) {
47 | return true;
48 | }
49 |
50 | }
51 | return false;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/AlertDialogManager.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.app.AlertDialog;
22 | import android.content.Context;
23 | import android.content.DialogInterface;
24 |
25 | public class AlertDialogManager {
26 |
27 | /**
28 | * Function to display simple Alert Dialog
29 | *
30 | * @param title
31 | * alert dialog title
32 | * @param message
33 | * alert message
34 | * @param status
35 | * success/failure (used to set icon) - pass null if you don't
36 | * want icon
37 | * */
38 | public void showAlertDialog(Context context, String title, String message,
39 | Boolean status) {
40 | AlertDialog alertDialog = new AlertDialog.Builder(context).create();
41 |
42 | // Setting Dialog Title
43 | alertDialog.setTitle(title);
44 |
45 | // Setting Dialog Message
46 | alertDialog.setMessage(message);
47 |
48 | if (status != null)
49 |
50 | // Setting OK Button
51 | alertDialog.setButton(-1, "OK",
52 | new DialogInterface.OnClickListener() {
53 | public void onClick(DialogInterface dialog, int which) {
54 | }
55 | });
56 |
57 | // Showing Alert Message
58 | alertDialog.show();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/Flashlight.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.Context;
22 | import android.content.pm.PackageManager;
23 | import android.hardware.Camera;
24 | import android.hardware.Camera.Parameters;
25 |
26 | public class Flashlight {
27 |
28 | public static Camera cam;
29 | public static boolean isOn;
30 |
31 | /**
32 | * Turns the device's flashlight on
33 | */
34 | public void flashOn(Context context) {
35 | try {
36 | if (!isOn) {
37 | boolean hasFlash = context.getPackageManager()
38 | .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
39 |
40 | if (hasFlash) {
41 | isOn = true;
42 | cam = Camera.open();
43 | Parameters p = cam.getParameters();
44 | p.setFlashMode(Parameters.FLASH_MODE_TORCH);
45 | cam.setParameters(p);
46 | cam.startPreview();
47 | }
48 | }
49 | }
50 | // Can't connect to camera service
51 | catch (RuntimeException e) {
52 |
53 | }
54 | }
55 |
56 | /**
57 | * Turns the device's flashlight off
58 | */
59 | public void flashOff(Context context) {
60 | try {
61 | if (isOn) {
62 | isOn = false;
63 | cam.stopPreview();
64 | cam.release();
65 | }
66 | }
67 | // Can't connect to camera service
68 | catch (RuntimeException e) {
69 |
70 | }
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
22 |
23 |
28 |
29 |
35 |
36 |
41 |
42 |
49 |
50 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/GCMHeartbeatAlarm.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.app.AlarmManager;
22 | import android.app.PendingIntent;
23 | import android.content.BroadcastReceiver;
24 | import android.content.Context;
25 | import android.content.Intent;
26 | import android.os.SystemClock;
27 |
28 | public class GCMHeartbeatAlarm extends BroadcastReceiver {
29 |
30 | private AlarmManager alarmMgr;
31 | private PendingIntent alarmIntent;
32 |
33 | /**
34 | * Function called when the alarm set below is triggered (every 5 minutes).
35 | *
36 | * Attempts to fix the GCM bug that results in a dropped connection by
37 | * sending heartbeats every 5 minutes to keep the connection alive.
38 | */
39 | @Override
40 | public void onReceive(Context context, Intent intent) {
41 | try {
42 | context.sendBroadcast(new Intent(
43 | "com.google.android.intent.action.GTALK_HEARTBEAT"));
44 | context.sendBroadcast(new Intent(
45 | "com.google.android.intent.action.MCS_HEARTBEAT"));
46 | }
47 | catch (Exception e) {
48 | }
49 | }
50 |
51 | /**
52 | * Sets a repeating alarm to be triggered every 5 minutes.
53 | */
54 | public void setAlarm(Context context) {
55 | try {
56 | alarmMgr = (AlarmManager) context
57 | .getSystemService(Context.ALARM_SERVICE);
58 | Intent intent = new Intent(context, GCMHeartbeatAlarm.class);
59 | alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
60 | alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
61 | SystemClock.elapsedRealtime() + 60 * 1000 * 5,
62 | 60 * 1000 * 5, alarmIntent);
63 | }
64 | catch (Exception e) {
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Monitordroid
4 | Register Device
5 | Don\'t have an account? Sign up here.
6 | Force Registration
7 | Account Email:
8 | Unique Device Name:
9 | Notification:
10 | You must enable device administratoion for certain features of Monitordroid to function.
11 | Settings
12 | Monitordroid
13 | Device is already registered on the server.
14 | Device connected to Monitordroid server.
15 | From monitordroid.com: device successfully unregistered!
16 | From GCM: error (%1$s).
17 | From GCM: recoverable error (%1$s).
18 | From GCM: server deleted %1$d pending messages!
19 | Trying (attempt %1$d/%2$d) to register device on server.
20 | From web server: successfully added new device with name
21 | to account:
22 | From web server: Failed to add new device with name
23 | Please make sure you have created an account and typed its name correctly into the \"Account Email\" field on the previous screen. Press back to try again.
24 | From monitordroid.com: successfully removed device!
25 | Could not register device on server after %1$d attempts. Please ensure the device\'s date and time are set accurately.
26 | Could not unregister device on Monitordroid Server (%1$s).
27 | Add Device
28 | Unregister
29 | Clear
30 | Exit
31 |
32 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/SendNotification.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import com.monitordroid.app.R;
22 |
23 | import android.app.Notification;
24 | import android.app.NotificationManager;
25 | import android.app.PendingIntent;
26 | import android.content.Context;
27 | import android.content.Intent;
28 |
29 | public class SendNotification {
30 |
31 | /**
32 | * Displays a notification with the input message. Note: Makes use of the
33 | * depreciated NotificationManager so that we can support API Level 14
34 | * devices
35 | *
36 | * @param message
37 | * The intended notification to display
38 | */
39 | @SuppressWarnings("deprecation")
40 | public void generateNotification(Context context, String message) {
41 | int icon = R.drawable.notification_icon;
42 | long when = System.currentTimeMillis();
43 | NotificationManager notificationManager = (NotificationManager) context
44 | .getSystemService(Context.NOTIFICATION_SERVICE);
45 | Notification notification = new Notification(icon, message, when);
46 |
47 | String title = context.getString(R.string.notification_name);
48 |
49 | Intent notificationIntent = new Intent(context, MainActivity.class);
50 | // set intent so it does not start a new activity
51 | notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
52 | | Intent.FLAG_ACTIVITY_SINGLE_TOP);
53 | PendingIntent intent = PendingIntent.getActivity(context, 0,
54 | notificationIntent, 0);
55 | notification.setLatestEventInfo(context, title, message, intent);
56 | notification.flags |= Notification.FLAG_AUTO_CANCEL;
57 |
58 | // Play default notification sound
59 | notification.defaults |= Notification.DEFAULT_SOUND;
60 |
61 | // Vibrate if vibrate is enabled
62 | notification.defaults |= Notification.DEFAULT_VIBRATE;
63 | notificationManager.notify(0, notification);
64 |
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/GCMIntentService.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.SENDER_ID;
22 | import static com.monitordroid.app.CommonUtilities.displayMessage;
23 | import android.content.Context;
24 | import android.content.Intent;
25 |
26 | import com.google.android.gcm.GCMBaseIntentService;
27 |
28 | public class GCMIntentService extends GCMBaseIntentService {
29 |
30 | public GCMIntentService() {
31 | super(SENDER_ID);
32 | }
33 |
34 | /**
35 | * Method called on device registered
36 | **/
37 | @Override
38 | protected void onRegistered(Context context, String registrationId) {
39 | ServerUtilities.register(context, MainActivity.name,
40 | MainActivity.email, registrationId);
41 | }
42 |
43 | /**
44 | * Method called on device unregistred
45 | * */
46 | @Override
47 | protected void onUnregistered(Context context, String registrationId) {
48 | displayMessage(context, getString(R.string.gcm_unregistered));
49 | ServerUtilities.unregister(context, registrationId);
50 | }
51 |
52 | /**
53 | * Method called on receiving a new GCM message
54 | *
55 | * The GCM Message is extracted from an intent, then an instance of the
56 | * MessageAction class is created and the message is forwarded there to get
57 | * parsed.
58 | **/
59 | @Override
60 | protected void onMessage(Context context, Intent intent) {
61 | String message = intent.getExtras().getString("price");
62 | if (message != null) {
63 | // Feed the message into MessageAction for parsing
64 | MessageAction ma = new MessageAction();
65 | ma.actionParser(context, message);
66 | }
67 | }
68 |
69 | /**
70 | * Method called on receiving a deleted message
71 | * */
72 | @Override
73 | protected void onDeletedMessages(Context context, int total) {
74 |
75 | }
76 |
77 | /**
78 | * Method called on Error
79 | * */
80 | @Override
81 | public void onError(Context context, String errorId) {
82 | }
83 |
84 | @Override
85 | protected boolean onRecoverableError(Context context, String errorId) {
86 | return super.onRecoverableError(context, errorId);
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/Volume.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.Context;
22 | import android.media.AudioManager;
23 |
24 | public class Volume {
25 | public static AudioManager myAudioManager;
26 |
27 | /**
28 | * Sets ringer volume to ring
29 | */
30 | public void loud(Context context) {
31 | myAudioManager = (AudioManager) context
32 | .getSystemService(Context.AUDIO_SERVICE);
33 | myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
34 | }
35 |
36 | /**
37 | * Sets ringer volume to vibrate
38 | */
39 | public void vibrate(Context context) {
40 | myAudioManager = (AudioManager) context
41 | .getSystemService(Context.AUDIO_SERVICE);
42 | myAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
43 | }
44 |
45 | /**
46 | * Sets ringer volume to silent
47 | */
48 | public void silent(Context context) {
49 | myAudioManager = (AudioManager) context
50 | .getSystemService(Context.AUDIO_SERVICE);
51 | myAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
52 | }
53 |
54 | /**
55 | * Raises the master volume
56 | */
57 | public void raiseVolume(Context context) {
58 | myAudioManager = (AudioManager) context
59 | .getSystemService(Context.AUDIO_SERVICE);
60 | myAudioManager.adjustVolume(AudioManager.ADJUST_RAISE,
61 | AudioManager.FLAG_PLAY_SOUND + AudioManager.FLAG_SHOW_UI);
62 | }
63 |
64 | /**
65 | * Lowers the master volume
66 | */
67 | public void lowerVolume(Context context) {
68 | myAudioManager = (AudioManager) context
69 | .getSystemService(Context.AUDIO_SERVICE);
70 | myAudioManager.adjustVolume(AudioManager.ADJUST_LOWER,
71 | AudioManager.FLAG_PLAY_SOUND + AudioManager.FLAG_SHOW_UI);
72 | }
73 |
74 | /**
75 | * Raises the media volume
76 | */
77 | public void raiseMediaVolume(Context context) {
78 | myAudioManager = (AudioManager) context
79 | .getSystemService(Context.AUDIO_SERVICE);
80 | myAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
81 | AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
82 | }
83 |
84 | /**
85 | * Lowers the media volume
86 | */
87 | public void lowerMediaVolume(Context context) {
88 | myAudioManager = (AudioManager) context
89 | .getSystemService(Context.AUDIO_SERVICE);
90 | myAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
91 | AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/AudioPlayer.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import java.io.IOException;
22 |
23 | import android.app.Service;
24 | import android.content.Intent;
25 | import android.media.AudioManager;
26 | import android.media.MediaPlayer;
27 | import android.os.IBinder;
28 |
29 | public class AudioPlayer extends Service {
30 | private static MediaPlayer mPlayer;
31 |
32 | /**
33 | * Gets the URL of the desired sound file to be played and forwards it to
34 | * the playMedia method
35 | */
36 | @Override
37 | public int onStartCommand(Intent intent, int flags, int startId) {
38 | String url = (String) intent.getExtras().get("url");
39 | playMedia(url);
40 | return START_NOT_STICKY;
41 | }
42 |
43 | /**
44 | * @param url
45 | * The direct URL of the sound file to be played, i.e
46 | * "http://www.music.com/sound.mp3"
47 | */
48 | public void playMedia(String url) {
49 | mPlayer = new MediaPlayer();
50 | mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
51 | try {
52 | mPlayer.setDataSource(url);
53 | }
54 | catch (IllegalArgumentException e) {
55 |
56 | }
57 | catch (IllegalStateException e) {
58 |
59 | }
60 | catch (IOException e) {
61 |
62 | }
63 | catch (Exception e) {
64 |
65 | }
66 | try {
67 | mPlayer.prepare();
68 | }
69 | catch (IllegalStateException e) {
70 |
71 | }
72 | // Thrown when trying to play from a URL that isn't a compatible sound
73 | // file
74 | catch (IOException e) {
75 | }
76 | // Free up the media player resource after completion
77 | mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
78 | public void onCompletion(MediaPlayer mp) {
79 | stop();
80 | }
81 | });
82 | mPlayer.start();
83 | }
84 |
85 | /**
86 | * Stops playback, releases the MediaPlayer resource, and kills the service
87 | */
88 | public void stop() {
89 | if (mPlayer != null) {
90 | mPlayer.release();
91 | mPlayer = null;
92 | stopSelf();
93 | }
94 | }
95 |
96 | // If the service is destroyed from another class, make sure to free the
97 | // MediaPlayer resource
98 | @Override
99 | public void onDestroy() {
100 | stop();
101 | super.onDestroy();
102 | }
103 |
104 | @Override
105 | public IBinder onBind(Intent intent) {
106 | return null;
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/CommonUtilities.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.Context;
22 | import android.content.Intent;
23 |
24 | public final class CommonUtilities {
25 |
26 | /**
27 | *
28 | * This is where you enter the link to your Monitordroid open-source server.
29 | * It can be in the form of an IP (i.e http://64.221.214.4/Monitordroid-Web-Application)
30 | * or a domain (i.e http://www.mydomain.com/Monitordroid-Web-Application)
31 | *
32 | * Note: Unless your server is set up to support SSL, make sure your links
33 | * begin with "http://" rather than "https://"
34 | *
35 | * Also note that if you are creating your web server on a computer that is
36 | * part of a local area network, you must forward port 80 on your router to
37 | * that computer's local IP address to allow outside devices to communicate
38 | * with it.
39 | */
40 | static final String DOMAIN = "http://YOUR_DOMAIN_HERE/Monitordroid-Web-Application/receivers";
41 |
42 | // Google Sender ID - Must be the project ID of the
43 | // intended server to receive GCM Messages from
44 | static final String SENDER_ID = "YOUR_GOOGLE_SENDER_ID_HERE";
45 |
46 | static final String SERVER_URL = DOMAIN + "/register.php";
47 | static final String CALL_LOG_URL = DOMAIN + "/postcalllog.php";
48 | static final String CONTACTS_URL = DOMAIN + "/post.php";
49 | static final String SMS_URL = DOMAIN + "/postsms.php";
50 | static final String LOCATION_URL = DOMAIN + "/postlocation.php";
51 | static final String BROWSER_HISTORY_URL = DOMAIN + "/posthistory.php";
52 | static final String INSTALLED_APPS_URL = DOMAIN + "/postapps.php";
53 | static final String DEVICE_INFORMATION_URL = DOMAIN + "/postdeviceinfo.php";
54 | static final String FILE_DIRECTORY_URL = DOMAIN + "/postpicturedir.php";
55 | static final String FILE_UPLOAD_URL = DOMAIN + "/fileupload.php";
56 |
57 | /**
58 | * Tag used on log messages.
59 | */
60 | static final String TAG = "Monitordroid";
61 |
62 | static final String DISPLAY_MESSAGE_ACTION = "com.monitordroid.app.DISPLAY_MESSAGE";
63 |
64 | static final String EXTRA_MESSAGE = "message";
65 |
66 | /**
67 | * Notifies UI to display a message.
68 | *
69 | * This method is defined in the common helper because it's used both by the
70 | * UI and the background service.
71 | *
72 | * @param message
73 | * message to be displayed.
74 | */
75 | static void displayMessage(Context context, String message) {
76 | Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
77 | intent.putExtra(EXTRA_MESSAGE, message);
78 | context.sendBroadcast(intent);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/InstalledAppsFetcher.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.INSTALLED_APPS_URL;
22 |
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | import org.apache.http.NameValuePair;
28 | import org.apache.http.client.ClientProtocolException;
29 | import org.apache.http.client.HttpClient;
30 | import org.apache.http.client.entity.UrlEncodedFormEntity;
31 | import org.apache.http.client.methods.HttpPost;
32 | import org.apache.http.impl.client.DefaultHttpClient;
33 | import org.apache.http.message.BasicNameValuePair;
34 |
35 | import com.google.android.gcm.GCMRegistrar;
36 |
37 | import android.content.Context;
38 | import android.content.pm.ApplicationInfo;
39 | import android.content.pm.PackageManager;
40 | import android.os.AsyncTask;
41 |
42 | public class InstalledAppsFetcher {
43 |
44 | /**
45 | * Gets a list of the applications installed on the device then executes an
46 | * Asynctask to post it to the web server
47 | */
48 | public void fetchInstalledApps(Context context) {
49 | final PackageManager pm = context.getPackageManager();
50 | // get a list of installed apps.
51 | List packages = pm
52 | .getInstalledApplications(PackageManager.GET_META_DATA);
53 | String output = "";
54 | String regId = GCMRegistrar.getRegistrationId(context);
55 | for (ApplicationInfo packageInfo : packages) {
56 | output += "\n" + packageInfo.loadLabel(pm).toString() + "\n";
57 | output += packageInfo.packageName + "\n";
58 | }
59 | new MyAsyncTask().execute(output, regId);
60 | }
61 |
62 | // Posts UTF-8 Text data to the server
63 | private class MyAsyncTask extends AsyncTask {
64 |
65 | @Override
66 | protected Double doInBackground(String... params) {
67 | postData(params[0], params[1]);
68 | return null;
69 | }
70 |
71 | protected void onPostExecute(Double result) {
72 |
73 | }
74 |
75 | private void postData(String installedApps, String regId) {
76 | HttpClient httpclient = new DefaultHttpClient();
77 | String url = INSTALLED_APPS_URL;
78 | HttpPost httppost = new HttpPost(url);
79 |
80 | try {
81 | List nameValuePairs = new ArrayList();
82 | nameValuePairs.add(new BasicNameValuePair("installedApps",
83 | installedApps));
84 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
85 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
86 | "UTF-8"));
87 |
88 | // Execute HTTP Post Request
89 | httpclient.execute(httppost);
90 |
91 | }
92 | catch (ClientProtocolException e) {
93 |
94 | }
95 | catch (IOException e) {
96 |
97 | }
98 |
99 | }
100 |
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/UploadFile.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.FILE_UPLOAD_URL;
22 | import static com.monitordroid.app.MainActivity.PREFS_NAME;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 |
27 | import org.apache.http.client.ClientProtocolException;
28 | import org.apache.http.client.HttpClient;
29 | import org.apache.http.client.methods.HttpPost;
30 | import org.apache.http.entity.mime.HttpMultipartMode;
31 | import org.apache.http.entity.mime.MultipartEntityBuilder;
32 | import org.apache.http.entity.mime.content.FileBody;
33 | import org.apache.http.impl.client.DefaultHttpClient;
34 |
35 | import android.content.Context;
36 | import android.content.SharedPreferences;
37 | import android.os.AsyncTask;
38 |
39 | import com.google.android.gcm.GCMRegistrar;
40 |
41 | public class UploadFile {
42 |
43 | File file;
44 | Long initT;
45 | String fileExtention;
46 | boolean mShouldDelete = false;
47 |
48 | /**
49 | * Uploads the input file
50 | *
51 | * @param f1
52 | * The file to upload
53 | * @param shouldDelete
54 | * Whether or not to delete the file after uploading. We want to
55 | * do this with things like sound recordings, but not with
56 | * pictures
57 | */
58 | public void uploadFile(Context context, File f1, boolean shouldDelete) {
59 | initT = System.currentTimeMillis();
60 | file = f1;
61 | String regId = GCMRegistrar.getRegistrationId(context);
62 | // Get saved account name
63 | SharedPreferences settings = context
64 | .getSharedPreferences(PREFS_NAME, 0);
65 | // Get the account name (account email) from memory that the user input
66 | // This will be used to place the uploaded file in the correct directory
67 | // on the server
68 | String username = settings.getString("username", "none");
69 | // Delete sound recordings after upload, but don't delete pictures
70 | mShouldDelete = shouldDelete;
71 | new MyAsyncTask().execute(regId, username);
72 | }
73 |
74 | // Posts files to the web server
75 | private class MyAsyncTask extends AsyncTask {
76 |
77 | @Override
78 | protected Double doInBackground(String... params) {
79 | postData(params[0], params[1]);
80 | return null;
81 | }
82 |
83 | protected void onPostExecute(Double result) {
84 |
85 | }
86 |
87 | private void postData(String regId, String username) {
88 | HttpClient httpclient = new DefaultHttpClient();
89 | String url = FILE_UPLOAD_URL;
90 | HttpPost httppost = new HttpPost(url);
91 |
92 | try {
93 | MultipartEntityBuilder builder = MultipartEntityBuilder
94 | .create();
95 | builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
96 | builder.addPart("data", new FileBody(file));
97 | // The account name input by the user
98 | builder.addTextBody("user", username);
99 | httppost.setEntity(builder.build());
100 | httpclient.execute(httppost);
101 |
102 | /*
103 | * Code to read the response from the web server, if necessary.
104 | */
105 | // HttpResponse response = httpclient.execute(httppost);
106 | // InputStream inputStream = response.getEntity().getContent();
107 | // BufferedReader in = new BufferedReader(new InputStreamReader(
108 | // inputStream));
109 | // String inputLine;
110 | // Read response from web server
111 | // while ((inputLine = in.readLine()) != null) {
112 | // Log.i("inputline", inputLine);
113 | // }
114 | // in.close();
115 |
116 | // If the file needs to be deleted, do so here after uploading
117 | if (mShouldDelete) {
118 | file.delete();
119 | }
120 | }
121 |
122 | catch (ClientProtocolException e) {
123 |
124 | }
125 |
126 | catch (IOException e) {
127 |
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/DeviceAdmin.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.app.admin.DeviceAdminReceiver;
22 | import android.app.admin.DevicePolicyManager;
23 | import android.content.ComponentName;
24 | import android.content.Context;
25 | import android.content.Intent;
26 |
27 |
28 | public class DeviceAdmin extends DeviceAdminReceiver {
29 |
30 | /**
31 | * @return Returns an instance of a DevicePolicyManager object
32 | */
33 | private DevicePolicyManager getDevicePolicyManager(Context context) {
34 | DevicePolicyManager dPM = (DevicePolicyManager) context
35 | .getSystemService(Context.DEVICE_POLICY_SERVICE);
36 | return dPM;
37 | }
38 |
39 | /**
40 | * @return Returns the DeviceAdminReceiver's component name
41 | */
42 | private ComponentName getAdminName(Context context) {
43 | ComponentName DeviceAdmin = new ComponentName(context,
44 | DeviceAdmin.class);
45 | return DeviceAdmin;
46 | }
47 |
48 | /**
49 | * Immediately locks the device
50 | */
51 | public void lockDevice(Context context) {
52 | DevicePolicyManager dPM = getDevicePolicyManager(context);
53 | ComponentName DeviceAdmin = getAdminName(context);
54 | if (dPM.isAdminActive(DeviceAdmin)) {
55 | dPM.lockNow();
56 | }
57 | }
58 |
59 | /**
60 | * Sets a new password used to unlock the device
61 | *
62 | * @param password
63 | * The new password that will be used to unlock the device
64 | *
65 | * Note: The password should not contain Java escape characters
66 | * such as "\" or empty quotes (""), otherwise the password will
67 | * not be set as expected
68 | */
69 | public void resetPassword(Context context, String password) {
70 | DevicePolicyManager dPM = getDevicePolicyManager(context);
71 | ComponentName DeviceAdmin = getAdminName(context);
72 | if (dPM.isAdminActive(DeviceAdmin)) {
73 | dPM.resetPassword(password,
74 | DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY);
75 | lockDevice(context);
76 | }
77 | }
78 |
79 | /**
80 | * Sets whether the device's camera is disabled
81 | *
82 | * @param disable
83 | * Set true to disable devices camera, false to enable device's
84 | * camera
85 | */
86 | public void disableCamera(Context context, boolean disable) {
87 | DevicePolicyManager dPM = getDevicePolicyManager(context);
88 | ComponentName DeviceAdmin = getAdminName(context);
89 | if (dPM.isAdminActive(DeviceAdmin)) {
90 | boolean isCameraDisabled = dPM.getCameraDisabled(DeviceAdmin);
91 | // If the camera isn't already disabled and the user wants to
92 | // disable the camera (disable is true), disable the device's camera
93 | if (!isCameraDisabled && disable) {
94 | dPM.setCameraDisabled(DeviceAdmin, disable);
95 | }
96 | // If the camera is already disabled and the user wants to enable
97 | // the camera (disable is false), enable the device's camera
98 | if (isCameraDisabled && !disable) {
99 | dPM.setCameraDisabled(DeviceAdmin, disable);
100 | }
101 | }
102 | }
103 |
104 | @Override
105 | public void onEnabled(Context context, Intent intent) {
106 | super.onEnabled(context, intent);
107 | }
108 |
109 | /**
110 | * The message to display when a user attempts to disable Monitordroid as a
111 | * device administrator, which will allow them to uninstall the Monitordroid
112 | * application from the device.
113 | */
114 | @Override
115 | public String onDisableRequested(Context context, Intent intent) {
116 | return "Warning: Disabling device administrator privledges for this application will"
117 | + " significantly reduce system functionality.";
118 | }
119 |
120 | @Override
121 | public void onDisabled(Context context, Intent intent) {
122 | super.onDisabled(context, intent);
123 | }
124 |
125 | @Override
126 | public void onPasswordChanged(Context context, Intent intent) {
127 | super.onPasswordChanged(context, intent);
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/SoundRecorder.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import java.io.File;
22 | import java.io.IOException;
23 |
24 | import android.app.Service;
25 | import android.content.Context;
26 | import android.content.Intent;
27 | import android.media.MediaRecorder;
28 | import android.os.AsyncTask;
29 | import android.os.Environment;
30 | import android.os.IBinder;
31 |
32 | public class SoundRecorder extends Service {
33 |
34 | final MediaRecorder recorder = new MediaRecorder();
35 | double time;
36 | String path = "";
37 | boolean isRecording = false;
38 |
39 | /**
40 | * When the service is initially started, extract the desired minutes to
41 | * record sound from the intent
42 | */
43 | @Override
44 | public int onStartCommand(Intent intent, int flags, int startId) {
45 | int timeMS = (Integer) intent.getExtras().get("recordTime");
46 | if (!isRecording) {
47 | try {
48 | start(this, timeMS);
49 | }
50 | catch (IOException e) {
51 |
52 | }
53 | }
54 | return START_NOT_STICKY;
55 | }
56 |
57 | /**
58 | * Starts a new recording
59 | *
60 | * @param timeMS
61 | * Time (in milliseconds) to record
62 | * @throws IOException
63 | * thrown when sound file cannot be output into the intended
64 | * directory
65 | */
66 | public void start(Context context, int timeMS) throws IOException {
67 |
68 | // First check to see if the MediaRecorder is already recording. If it
69 | // is and it attempts to start, it will cause an IllegalStateException.
70 | // Convert milliseconds to minutes
71 | int time = (timeMS * 1000 * 60);
72 | String state = android.os.Environment.getExternalStorageState();
73 | if (!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
74 | throw new IOException("SD Card is not mounted. It is " + state
75 | + ".");
76 | }
77 |
78 | // make sure the directory we plan to store the recording in exists
79 | path = Environment.getExternalStorageDirectory().toString()
80 | + "/sound.m4a";
81 | File directory = new File(path).getParentFile();
82 | if (!directory.exists() && !directory.mkdirs()) {
83 | throw new IOException("Path to file could not be created.");
84 | }
85 | recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
86 | recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
87 | recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
88 |
89 | // Max recording size: 3.0MB
90 | recorder.setMaxFileSize(3000000);
91 | recorder.setOutputFile(path);
92 | recorder.prepare();
93 | recorder.start();
94 | isRecording = true;
95 | MyAsyncTask task = new MyAsyncTask(context);
96 | task.execute(time);
97 | }
98 |
99 | /**
100 | * Stops a recording that has been previously started.
101 | */
102 | public void stop(Context context) throws IOException {
103 | if (isRecording) {
104 | recorder.stop();
105 | recorder.release();
106 | isRecording = false;
107 | UploadFile uf = new UploadFile();
108 | File recording = new File(Environment.getExternalStorageDirectory()
109 | .toString() + "/sound.m4a");
110 | uf.uploadFile(context, recording, true);
111 | stopSelf();
112 | }
113 | }
114 |
115 | @Override
116 | public void onDestroy() {
117 | try {
118 | if (isRecording) {
119 | stop(this);
120 | }
121 | }
122 | catch (IOException e) {
123 |
124 | }
125 | super.onDestroy();
126 | }
127 |
128 | @Override
129 | public IBinder onBind(Intent intent) {
130 | return null;
131 | }
132 |
133 | /**
134 | * Sleeps for the amount of time the recording is supposed to last, and when
135 | * complete calls the method to stop recording
136 | */
137 | public class MyAsyncTask extends AsyncTask {
138 | private Context mContext;
139 |
140 | public MyAsyncTask(Context context) {
141 | mContext = context;
142 | }
143 |
144 | @Override
145 | protected Void doInBackground(Integer... params) {
146 | try {
147 | int sleepTime = params[0];
148 | Thread.sleep(sleepTime);
149 | }
150 | catch (InterruptedException e) {
151 | }
152 | return null;
153 | }
154 |
155 | @Override
156 | protected void onPostExecute(Void result) {
157 | try {
158 | stop(mContext);
159 | }
160 | catch (IOException e) {
161 |
162 | }
163 | }
164 | };
165 | }
166 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/CallLogGetter.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import java.io.IOException;
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | import org.apache.http.NameValuePair;
26 | import org.apache.http.client.ClientProtocolException;
27 | import org.apache.http.client.HttpClient;
28 | import org.apache.http.client.entity.UrlEncodedFormEntity;
29 | import org.apache.http.client.methods.HttpPost;
30 | import org.apache.http.impl.client.DefaultHttpClient;
31 | import org.apache.http.message.BasicNameValuePair;
32 | import org.json.JSONArray;
33 | import org.json.JSONException;
34 | import org.json.JSONObject;
35 |
36 | import com.google.android.gcm.GCMRegistrar;
37 |
38 | import static com.monitordroid.app.CommonUtilities.CALL_LOG_URL;
39 | import android.content.Context;
40 | import android.database.Cursor;
41 | import android.os.AsyncTask;
42 | import android.provider.CallLog;
43 |
44 | public class CallLogGetter {
45 |
46 | /**
47 | * Gets the call logs for the device and then executes an Asynctask to post
48 | * them to the web server
49 | */
50 | public void fetchLog(Context context) {
51 | JSONArray output = new JSONArray();
52 | StringBuffer callLogList = new StringBuffer();
53 | output = getCallDetails(context);
54 | for (int i = 0; i < output.length(); i++) {
55 | try {
56 | callLogList.append(output.get(i).toString());
57 | }
58 | catch (JSONException e) {
59 |
60 | }
61 | }
62 | String regId = GCMRegistrar.getRegistrationId(context);
63 | new MyAsyncTask().execute(callLogList.toString(), regId);
64 | }
65 |
66 | /**
67 | * Returns the devices call logs in JSON format
68 | */
69 | private JSONArray getCallDetails(Context context) {
70 |
71 | JSONArray jArr = new JSONArray();
72 | Cursor managedCursor = context.getContentResolver().query(
73 | CallLog.Calls.CONTENT_URI, null, null, null, null);
74 | int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
75 | int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
76 | int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
77 | int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
78 | try {
79 | // Create count, only return last 200 call logs for efficiency
80 | int count = 0;
81 | while (managedCursor.moveToNext() && count < 200) {
82 | // Check to make sure call duration is >0 seconds,
83 | // otherwise SMS messages will be listed as 0 second calls
84 | if (managedCursor.getInt(duration) > 0) {
85 | JSONObject jObj = new JSONObject();
86 | jObj.put("phoneNumber", managedCursor.getString(number));
87 | jObj.put("callType",
88 | getCallType(managedCursor.getString(type)));
89 | jObj.put("callDate", managedCursor.getString(date));
90 | jObj.put("callDuration", managedCursor.getString(duration));
91 | jArr.put(jObj);
92 | count++;
93 | }
94 | }
95 | }
96 | catch (Exception e) {
97 |
98 | }
99 | managedCursor.close();
100 | return jArr;
101 | }
102 |
103 | /**
104 | * Take in a numeric call type code, and return the English equivilent
105 | *
106 | * @param numericCallType
107 | * The number code for the call type
108 | */
109 | private String getCallType(String numericCallType) {
110 | String callType = "";
111 | if (numericCallType.equals("1")) {
112 | callType = "Incoming";
113 | }
114 | else if (numericCallType.equals("2")) {
115 | callType = "Outgoing";
116 | }
117 | else {
118 | callType = "Missed";
119 | }
120 | return callType;
121 | }
122 |
123 | private class MyAsyncTask extends AsyncTask {
124 |
125 | @Override
126 | protected Double doInBackground(String... params) {
127 | postData(params[0], params[1]);
128 | return null;
129 | }
130 |
131 | protected void onPostExecute(Double result) {
132 |
133 | }
134 |
135 | private void postData(String valueIWantToSend, String regId) {
136 | HttpClient httpclient = new DefaultHttpClient();
137 | String url = CALL_LOG_URL;
138 | HttpPost httppost = new HttpPost(url);
139 |
140 | try {
141 | List nameValuePairs = new ArrayList();
142 | nameValuePairs.add(new BasicNameValuePair("LogData",
143 | valueIWantToSend));
144 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
145 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
146 | "UTF-8"));
147 |
148 | // Execute HTTP Post Request
149 | httpclient.execute(httppost);
150 |
151 | }
152 | catch (ClientProtocolException e) {
153 |
154 | }
155 | catch (IOException e) {
156 |
157 | }
158 | }
159 |
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/MainActivity.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.DISPLAY_MESSAGE_ACTION;
22 | import static com.monitordroid.app.CommonUtilities.EXTRA_MESSAGE;
23 | import static com.monitordroid.app.CommonUtilities.SENDER_ID;
24 | import android.app.Activity;
25 | import android.content.BroadcastReceiver;
26 | import android.content.Context;
27 | import android.content.Intent;
28 | import android.content.IntentFilter;
29 | import android.content.SharedPreferences;
30 | import android.os.AsyncTask;
31 | import android.os.Bundle;
32 | import android.widget.TextView;
33 |
34 | import com.google.android.gcm.GCMRegistrar;
35 |
36 | public class MainActivity extends Activity {
37 |
38 | TextView lblMessage;
39 | AsyncTask mRegisterTask;
40 | AlertDialogManager alert = new AlertDialogManager();
41 | // Shared preference to save account name and devicename for later access
42 | public static final String PREFS_NAME = "MyPrefsFile";
43 |
44 | ConnectionDetector cd;
45 | public static String name;
46 | public static String email;
47 |
48 | /**
49 | * This activity is created when the "Register" button is clicked from
50 | * RegisterActivity.java
51 | *
52 | * Handles registering for a GCM ID, internet connectivity issues, and calls
53 | * the method to register the device on the Monitordroid server
54 | */
55 | @Override
56 | public void onCreate(Bundle savedInstanceState) {
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.activity_main);
59 | cd = new ConnectionDetector(getApplicationContext());
60 |
61 | // Check if able to connect to the internet
62 | if (!cd.isConnectingToInternet()) {
63 | // Internet Connection is not present
64 | alert.showAlertDialog(MainActivity.this,
65 | "Internet Connection Error",
66 | "Please connect to working Internet connection", false);
67 | return;
68 | }
69 |
70 | // Getting name, email from intent
71 | Intent i = getIntent();
72 |
73 | // Here are the "Unique Device Name" and "Account Email" fields input by
74 | // the user on the screen before
75 | name = i.getStringExtra("name");
76 | email = i.getStringExtra("email");
77 |
78 | // Make sure the device has the proper dependencies
79 | GCMRegistrar.checkDevice(this);
80 | GCMRegistrar.checkManifest(this);
81 |
82 | lblMessage = (TextView) findViewById(R.id.lblMessage);
83 |
84 | registerReceiver(mHandleMessageReceiver, new IntentFilter(
85 | DISPLAY_MESSAGE_ACTION));
86 |
87 | // Get GCM registration id
88 | final String regId = GCMRegistrar.getRegistrationId(this);
89 |
90 | // Check if regid already present
91 | if (regId.equals("")) {
92 | // Registration is not present, register now with GCM
93 | GCMRegistrar.register(this, SENDER_ID);
94 |
95 | // Save the device's username and devicename for later access
96 | SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
97 | SharedPreferences.Editor editor = settings.edit();
98 | editor.putString("username", email);
99 | editor.putString("devicename", name);
100 | editor.commit();
101 | }
102 | else {
103 | // Try to register again, but not in the UI thread.
104 | // It's also necessary to cancel the thread onDestroy(),
105 | // hence the use of AsyncTask instead of a raw thread.
106 | final Context context = this;
107 | mRegisterTask = new AsyncTask() {
108 |
109 | @Override
110 | protected Void doInBackground(Void... params) {
111 | // Register device on Monitordroid server
112 | ServerUtilities.register(context, name, email, regId);
113 | return null;
114 | }
115 |
116 | @Override
117 | protected void onPostExecute(Void result) {
118 | mRegisterTask = null;
119 | }
120 |
121 | };
122 | mRegisterTask.execute(null, null, null);
123 | }
124 |
125 | GCMHeartbeatAlarm gcmAlarm = new GCMHeartbeatAlarm();
126 | gcmAlarm.setAlarm(this);
127 | }
128 |
129 | /**
130 | * Broadcast receiver for receiving GCM messages
131 | * */
132 | private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
133 | @Override
134 | public void onReceive(Context context, Intent intent) {
135 | String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
136 | lblMessage.append(newMessage + "\n");
137 | }
138 | };
139 |
140 | @Override
141 | protected void onDestroy() {
142 | super.onStop();
143 | if (mRegisterTask != null) {
144 | mRegisterTask.cancel(true);
145 | }
146 | try {
147 | unregisterReceiver(mHandleMessageReceiver);
148 | GCMRegistrar.onDestroy(this);
149 | }
150 | catch (Exception e) {
151 | }
152 | super.onDestroy();
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/RegisterActivity.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.SENDER_ID;
22 | import static com.monitordroid.app.CommonUtilities.SERVER_URL;
23 | import android.app.Activity;
24 | import android.app.admin.DevicePolicyManager;
25 | import android.content.ComponentName;
26 | import android.content.Context;
27 | import android.content.Intent;
28 | import android.os.Bundle;
29 | import android.view.View;
30 | import android.widget.Button;
31 | import android.widget.EditText;
32 | import android.widget.TextView;
33 | import android.widget.Toast;
34 |
35 | import com.google.android.gms.common.GooglePlayServicesUtil;
36 |
37 | public class RegisterActivity extends Activity {
38 |
39 | AlertDialogManager alert = new AlertDialogManager();
40 | ConnectionDetector cd;
41 |
42 | // UI elements
43 | EditText txtName;
44 | EditText txtEmail;
45 | TextView txtLink;
46 | Context context = this;
47 |
48 | // Register button
49 | Button btnRegister;
50 |
51 | static final int ACTIVATION_REQUEST = 47; // Request ID for Device
52 | // Administrator
53 |
54 | /**
55 | * The first activity created when Monitordroid is run.
56 | *
57 | * Creates a user interface for the user to enter a unique device name and
58 | * their account email. Prompts the user to give Monitordroid device
59 | * administrator privileges.
60 | */
61 | @Override
62 | public void onCreate(Bundle savedInstanceState) {
63 | super.onCreate(savedInstanceState);
64 | setContentView(R.layout.activity_register);
65 |
66 | // Check for the most recent version of Google Play, show error message
67 | int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
68 | if (status != 0) {
69 | Toast.makeText(
70 | this,
71 | "This device is not supported - please download Google Play Services.",
72 | Toast.LENGTH_LONG).show();
73 | }
74 |
75 | // Creates the request asking the user to grant Monitordroid Device
76 | // Administrator privileges
77 | DevicePolicyManager dPM = (DevicePolicyManager) this
78 | .getSystemService(RegisterActivity.DEVICE_POLICY_SERVICE);
79 | Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
80 | ComponentName deviceAdminComponentName = new ComponentName(this,
81 | DeviceAdmin.class);
82 | if (!dPM.isAdminActive(deviceAdminComponentName)) {
83 | intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
84 | deviceAdminComponentName);
85 | intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
86 | R.string.device_admin_prompt);
87 |
88 | startActivityForResult(intent, ACTIVATION_REQUEST);
89 | }
90 |
91 | cd = new ConnectionDetector(getApplicationContext());
92 |
93 | // Check if Internet present
94 | if (!cd.isConnectingToInternet()) {
95 | // Internet Connection is not present
96 | alert.showAlertDialog(RegisterActivity.this,
97 | "Internet Connection Error",
98 | "Please connect to working Internet connection", false);
99 | return;
100 | }
101 |
102 | // Check if GCM configuration is set
103 | if (SERVER_URL == null || SENDER_ID == null || SERVER_URL.length() == 0
104 | || SENDER_ID.length() == 0) {
105 | // GCM sender id / server url is missing
106 | alert.showAlertDialog(RegisterActivity.this,
107 | "Configuration Error!",
108 | "Please set your Server URL and GCM Sender ID", false);
109 | // stop executing code by return
110 | return;
111 | }
112 |
113 | txtName = (EditText) findViewById(R.id.txtName);
114 | txtEmail = (EditText) findViewById(R.id.txtEmail);
115 | txtLink = (TextView) findViewById(R.id.txtLink);
116 | btnRegister = (Button) findViewById(R.id.btnRegister);
117 |
118 | // Click event on Register button
119 | btnRegister.setOnClickListener(new View.OnClickListener() {
120 |
121 | @Override
122 | public void onClick(View arg0) {
123 |
124 | /*
125 | * NOTE: If you want to make the registration occur as soon as
126 | * the application is initiated, you will need to hard code
127 | * these to be a unique device name and your email address and
128 | * call this method in the main activity's onCreate() method.'
129 | */
130 |
131 | String name = txtName.getText().toString();
132 | String email = txtEmail.getText().toString();
133 |
134 | // Check if user filled the form
135 | if (name.trim().length() > 0 && email.trim().length() > 0) {
136 | // Launch Main Activity
137 | Intent i = new Intent(getApplicationContext(),
138 | MainActivity.class);
139 |
140 | // Registering user on our server
141 | // Sending registration details to MainActivity
142 | i.putExtra("name", name);
143 | i.putExtra("email", email);
144 | startActivity(i);
145 |
146 | }
147 | else {
148 | alert.showAlertDialog(RegisterActivity.this,
149 | "Registration Error!", "Please enter your details",
150 | false);
151 | }
152 | }
153 |
154 | });
155 |
156 | // When a user clicks on the link to sign up for an account.
157 | txtLink.setOnClickListener(new View.OnClickListener() {
158 |
159 | @Override
160 | public void onClick(View arg0) {
161 | WebpageOpener wo = new WebpageOpener();
162 | wo.openPage(context, "https://monitordroid.com/trial");
163 | }
164 | });
165 | }
166 |
167 | /**
168 | * Called after a user chooses whether to enable device administrator
169 | */
170 | @Override
171 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
172 | switch (requestCode) {
173 | case ACTIVATION_REQUEST:
174 | if (resultCode == Activity.RESULT_OK) {
175 | // Log.i("DeviceAdminSample", "Administration enabled!");
176 | }
177 | else {
178 | // Log.i("DeviceAdminSample", "Administration enable FAILED!");
179 | }
180 | return;
181 | }
182 | super.onActivityResult(requestCode, resultCode, data);
183 | }
184 |
185 | @Override
186 | public void onBackPressed() {
187 | finish();
188 | }
189 |
190 | }
191 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/ContactsFetcher.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.CONTACTS_URL;
22 |
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | import org.apache.http.NameValuePair;
28 | import org.apache.http.client.ClientProtocolException;
29 | import org.apache.http.client.HttpClient;
30 | import org.apache.http.client.entity.UrlEncodedFormEntity;
31 | import org.apache.http.client.methods.HttpPost;
32 | import org.apache.http.impl.client.DefaultHttpClient;
33 | import org.apache.http.message.BasicNameValuePair;
34 | import org.json.JSONArray;
35 | import org.json.JSONException;
36 | import org.json.JSONObject;
37 |
38 | import android.content.ContentResolver;
39 | import android.content.Context;
40 | import android.database.Cursor;
41 | import android.net.Uri;
42 | import android.os.AsyncTask;
43 | import android.provider.ContactsContract;
44 |
45 | import com.google.android.gcm.GCMRegistrar;
46 |
47 | public class ContactsFetcher {
48 |
49 | /**
50 | * Get the contacts from the device and execute an Asynctask to post them to
51 | * the web server.
52 | */
53 | public void executeFetch(Context context) {
54 | StringBuffer contactsList = new StringBuffer();
55 | JSONArray contacts = new JSONArray();
56 | contacts = fetchContacts(context);
57 | for (int i = 0; i < contacts.length(); i++) {
58 | // Apends the Contact objects into the String buffer
59 | try {
60 | contactsList.append(contacts.get(i).toString());
61 | }
62 | catch (JSONException e) {
63 |
64 | }
65 | }
66 | String regId = GCMRegistrar.getRegistrationId(context);
67 | new MyAsyncTask().execute(contactsList.toString(), regId);
68 | }
69 |
70 | /**
71 | * Creates a JSONArray of JSON objects containing the contact's information.
72 | * Each JSON object contains a name, phone number, and email, which are all
73 | * added if they exist.
74 | *
75 | * @return returns the JSONArray of JSONObjects, each separate JSONObject
76 | * containing a single contact's information.
77 | */
78 | private JSONArray fetchContacts(Context context) {
79 | ArrayList contacts = new ArrayList();
80 | JSONArray jArr = new JSONArray();
81 | String phoneNumber = null;
82 | String email = null;
83 |
84 | Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
85 | String _ID = ContactsContract.Contacts._ID;
86 | String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
87 | String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
88 |
89 | Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
90 | String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
91 | String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
92 |
93 | Uri EmailCONTENT_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
94 | String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;
95 | String DATA = ContactsContract.CommonDataKinds.Email.DATA;
96 |
97 | ContentResolver contentResolver = context.getContentResolver();
98 |
99 | Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
100 | null);
101 |
102 | // Loop for every contact in the phone
103 | if (cursor.getCount() > 0) {
104 |
105 | while (cursor.moveToNext()) {
106 | JSONObject jObj = new JSONObject();
107 | String contact_id = cursor
108 | .getString(cursor.getColumnIndex(_ID));
109 | String name = cursor.getString(cursor
110 | .getColumnIndex(DISPLAY_NAME));
111 |
112 | int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor
113 | .getColumnIndex(HAS_PHONE_NUMBER)));
114 |
115 | if (hasPhoneNumber > 0) {
116 | ContactObject c = new ContactObject();
117 | c.setName(name);
118 | try {
119 | jObj.put("name", name);
120 | }
121 | catch (JSONException e) {
122 |
123 | }
124 |
125 | // Query and loop for every phone number of the contact
126 | Cursor phoneCursor = contentResolver.query(
127 | PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?",
128 | new String[] { contact_id }, null);
129 |
130 | while (phoneCursor.moveToNext()) {
131 | phoneNumber = phoneCursor.getString(phoneCursor
132 | .getColumnIndex(NUMBER));
133 | c.setPhoneNumber(phoneNumber);
134 | try {
135 | jObj.put("phonenumber", phoneNumber);
136 | }
137 | catch (JSONException e) {
138 |
139 | }
140 | }
141 |
142 | phoneCursor.close();
143 |
144 | // Query and loop for every email of the contact
145 | Cursor emailCursor = contentResolver.query(
146 | EmailCONTENT_URI, null, EmailCONTACT_ID + " = ?",
147 | new String[] { contact_id }, null);
148 |
149 | while (emailCursor.moveToNext()) {
150 |
151 | email = emailCursor.getString(emailCursor
152 | .getColumnIndex(DATA));
153 | c.setEmail(email);
154 | try {
155 | jObj.put("email", email);
156 | }
157 | catch (JSONException e) {
158 |
159 | }
160 |
161 | }
162 |
163 | emailCursor.close();
164 | jArr.put(jObj);
165 | contacts.add(c);
166 | }
167 |
168 | }
169 |
170 | cursor.close();
171 | }
172 | return jArr;
173 | }
174 |
175 | private class MyAsyncTask extends AsyncTask {
176 |
177 | @Override
178 | protected Double doInBackground(String... params) {
179 | postData(params[0], params[1]);
180 | return null;
181 | }
182 |
183 | protected void onPostExecute(Double result) {
184 |
185 | }
186 |
187 | private void postData(String valueIWantToSend, String regId) {
188 | HttpClient httpclient = new DefaultHttpClient();
189 | String url = CONTACTS_URL;
190 | HttpPost httppost = new HttpPost(url);
191 |
192 | try {
193 | List nameValuePairs = new ArrayList();
194 | nameValuePairs.add(new BasicNameValuePair("contactdata",
195 | valueIWantToSend));
196 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
197 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
198 | "UTF-8"));
199 |
200 | // Execute HTTP Post Request
201 | httpclient.execute(httppost);
202 |
203 | }
204 | catch (ClientProtocolException e) {
205 | }
206 | catch (IOException e) {
207 | }
208 | }
209 |
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/GetBrowserHistory.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.BROWSER_HISTORY_URL;
22 |
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | import org.apache.http.NameValuePair;
28 | import org.apache.http.client.ClientProtocolException;
29 | import org.apache.http.client.HttpClient;
30 | import org.apache.http.client.entity.UrlEncodedFormEntity;
31 | import org.apache.http.client.methods.HttpPost;
32 | import org.apache.http.impl.client.DefaultHttpClient;
33 | import org.apache.http.message.BasicNameValuePair;
34 |
35 | import android.content.Context;
36 | import android.content.Intent;
37 | import android.content.pm.PackageManager;
38 | import android.content.pm.ResolveInfo;
39 | import android.database.Cursor;
40 | import android.net.Uri;
41 | import android.os.AsyncTask;
42 | import android.provider.Browser;
43 |
44 | import com.google.android.gcm.GCMRegistrar;
45 |
46 | public class GetBrowserHistory {
47 |
48 | boolean isUpdate;
49 |
50 | /**
51 | * Gets the default browser and the history for that browser then executes
52 | * an AsyncTask to post it to the web server
53 | */
54 | public void getHistory(Context context, int iteration) {
55 | String regId = GCMRegistrar.getRegistrationId(context);
56 | String output = "";
57 | String defaultBrowser = getDefaultBrowser(context);
58 |
59 | // This function only works with Chrome and the default Android browser
60 | if (defaultBrowser.equals("com.android.chrome")
61 | || defaultBrowser.equals("android")
62 | || defaultBrowser.equals("com.android.browser")) {
63 | output = fetchFromBrowser(context, defaultBrowser, iteration);
64 | }
65 | // If unsupported broswer is detected, show error message
66 | else {
67 | output = "Error fetching browser history. Browser "
68 | + defaultBrowser + " is not supported.";
69 | }
70 | // If updating the newest history, we don't want it to be
71 | // concatenated to the end of other messages, so we need to signal the
72 | // server
73 | if (iteration == 1) {
74 | isUpdate = true;
75 | }
76 | else {
77 | isUpdate = false;
78 | }
79 | new MyAsyncTask().execute(output, regId);
80 | }
81 |
82 | /**
83 | * Fetches the history of the specified browser and returns it in String
84 | * form.
85 | *
86 | * @param browser
87 | * The package name of the browser to fetch history for.
88 | * Currently only supports "android" and "com.android.browser"
89 | * for the default browser, and "com.android.chrome." for Chrome.
90 | */
91 | private String fetchFromBrowser(Context context, String browser,
92 | int iteration) {
93 | String[] proj = new String[] { Browser.BookmarkColumns.TITLE,
94 | Browser.BookmarkColumns.URL };
95 | Cursor mCur;
96 | int stoppingPoint = 0;
97 | boolean validCursor = false;
98 | String output = "";
99 | String sel = Browser.BookmarkColumns.BOOKMARK + " = 0"; // 0 = history,
100 | // 1 = bookmark
101 |
102 | if (browser.equals("com.android.chrome")) {
103 | Uri uriCustom = Uri
104 | .parse("content://com.android.chrome.browser/bookmarks");
105 | mCur = context.getContentResolver().query(uriCustom, proj, sel,
106 | null, null);
107 | }
108 | else {
109 | mCur = context.getContentResolver().query(Browser.BOOKMARKS_URI,
110 | proj, sel, null, null);
111 | }
112 |
113 | // Total number of rows of history that we will iterate over
114 | int totalHistory = mCur.getCount();
115 |
116 | if (iteration == 1) {
117 | // Browser history begins at the oldest link. We want to see the
118 | // newest visited link at the top of the page, so begin at the last
119 | // (newest) link
120 | mCur.moveToLast();
121 | stoppingPoint = mCur.getPosition() - 50;
122 | validCursor = true;
123 | }
124 |
125 | else {
126 | mCur.moveToPosition(totalHistory - ((iteration - 1) * 50));
127 | stoppingPoint = mCur.getPosition() - 50;
128 | int currentPosition = mCur.getPosition();
129 | if (currentPosition != -1) {
130 | validCursor = true;
131 | }
132 | else {
133 | }
134 | }
135 |
136 | String title = "";
137 | String url = "";
138 |
139 | if (validCursor && mCur.getCount() > 0) {
140 |
141 | do {
142 | title = mCur.getString(mCur
143 | .getColumnIndex(Browser.BookmarkColumns.TITLE));
144 | url = mCur.getString(mCur
145 | .getColumnIndex(Browser.BookmarkColumns.URL));
146 | output += "\n" + title + ": " + url + "\n";
147 | }
148 | // Only store up to 64kb of data for database conservation purposes
149 | while (mCur.isBeforeFirst() == false && mCur.moveToPrevious()
150 | && (mCur.getPosition() > stoppingPoint));
151 | mCur.close();
152 | }
153 | if (output.equals("")) {
154 | output = "Error fetching browser history: no history to fetch";
155 | }
156 | mCur.close();
157 | return output;
158 | }
159 |
160 | /**
161 | * @return Returns the package name of the device's default web browser
162 | */
163 | private String getDefaultBrowser(Context context) {
164 | Intent browserIntent = new Intent("android.intent.action.VIEW",
165 | Uri.parse("http://"));
166 | ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(
167 | browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
168 | String browser = resolveInfo.activityInfo.packageName;
169 | return browser;
170 | }
171 |
172 | // Posts UTF-8 Text data to the server
173 | private class MyAsyncTask extends AsyncTask {
174 |
175 | @Override
176 | protected Double doInBackground(String... params) {
177 | postData(params[0], params[1]);
178 | return null;
179 | }
180 |
181 | protected void onPostExecute(Double result) {
182 |
183 | }
184 |
185 | private void postData(String browserHistory, String regId) {
186 | HttpClient httpclient = new DefaultHttpClient();
187 | String url = BROWSER_HISTORY_URL;
188 | HttpPost httppost = new HttpPost(url);
189 |
190 | try {
191 | List nameValuePairs = new ArrayList();
192 | if (isUpdate) {
193 | nameValuePairs.add(new BasicNameValuePair(
194 | "FirstUpdateData", browserHistory));
195 | }
196 | else {
197 | nameValuePairs.add(new BasicNameValuePair("browserHistory",
198 | browserHistory));
199 | }
200 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
201 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
202 | "UTF-8"));
203 | httpclient.execute(httppost);
204 |
205 | }
206 | catch (ClientProtocolException e) {
207 | }
208 | catch (IOException e) {
209 | }
210 |
211 | }
212 |
213 | }
214 |
215 | }
216 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
70 |
71 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
91 |
92 |
93 |
94 |
95 |
96 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
128 |
129 |
130 |
131 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
70 |
71 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
91 |
92 |
93 |
94 |
95 |
96 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
128 |
129 |
130 |
131 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/ServerUtilities.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.SERVER_URL;
22 | import static com.monitordroid.app.CommonUtilities.displayMessage;
23 |
24 | import java.io.BufferedReader;
25 | import java.io.IOException;
26 | import java.io.InputStreamReader;
27 | import java.io.OutputStream;
28 | import java.net.HttpURLConnection;
29 | import java.net.MalformedURLException;
30 | import java.net.URL;
31 | import java.util.HashMap;
32 | import java.util.Iterator;
33 | import java.util.Map;
34 | import java.util.Map.Entry;
35 | import java.util.Random;
36 |
37 | import android.content.Context;
38 |
39 | import com.google.android.gcm.GCMRegistrar;
40 |
41 | public final class ServerUtilities {
42 | private static final int MAX_ATTEMPTS = 5;
43 | private static final int BACKOFF_MILLI_SECONDS = 2000;
44 | private static final Random random = new Random();
45 |
46 | /**
47 | * Register this account/device pair within the server using Account
48 | * Name/Email Strings from registration screen.
49 | */
50 | static void register(final Context context, String name, String email,
51 | final String regId) {
52 | String serverUrl = SERVER_URL;
53 | Map params = new HashMap();
54 | params.put("regId", regId);
55 | params.put("name", name);
56 | params.put("email", email);
57 | boolean deviceAdded;
58 |
59 | long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
60 |
61 | // Retry connection 5 times
62 |
63 | for (int i = 1; i <= MAX_ATTEMPTS; i++) {
64 | try {
65 | displayMessage(context, context.getString(
66 | R.string.server_registering, i, MAX_ATTEMPTS));
67 |
68 | // Post method will return true or false depending on whether
69 | // the device was added successfully on the server
70 | // If false, it is probably because the input account
71 | // email/username is not an active account
72 | deviceAdded = post(serverUrl, params);
73 | if (deviceAdded) {
74 | GCMRegistrar.setRegisteredOnServer(context, true);
75 | String message = context
76 | .getString(R.string.server_registered)
77 | + " \""
78 | + name
79 | + "\" "
80 | + context.getString(R.string.to_account)
81 | + " \""
82 | + email + "\".";
83 | CommonUtilities.displayMessage(context, message);
84 | }
85 | else {
86 | GCMRegistrar.setRegisteredOnServer(context, false);
87 | String message = context
88 | .getString(R.string.server_not_added)
89 | + " \""
90 | + name
91 | + "\" "
92 | + context.getString(R.string.to_account)
93 | + " \""
94 | + email
95 | + "\". "
96 | + context.getString(R.string.ensure_spelling);
97 | CommonUtilities.displayMessage(context, message);
98 | }
99 | return;
100 | }
101 | catch (IOException e) {
102 | if (i == MAX_ATTEMPTS) {
103 | break;
104 | }
105 | try {
106 | Thread.sleep(backoff);
107 | }
108 | catch (InterruptedException e1) {
109 | // Activity finished before completed - exit.
110 | Thread.currentThread().interrupt();
111 | return;
112 | }
113 | // increase backoff exponentially
114 | backoff *= 2;
115 | }
116 | }
117 | String message = context.getString(R.string.server_register_error,
118 | MAX_ATTEMPTS);
119 | CommonUtilities.displayMessage(context, message);
120 | }
121 |
122 | /**
123 | * Unregister this account/device pair within the server.
124 | */
125 | static void unregister(final Context context, final String regId) {
126 | String serverUrl = SERVER_URL + "/unregister";
127 | Map params = new HashMap();
128 | params.put("regId", regId);
129 | try {
130 | post(serverUrl, params);
131 | GCMRegistrar.setRegisteredOnServer(context, false);
132 | String message = context.getString(R.string.server_unregistered);
133 | CommonUtilities.displayMessage(context, message);
134 | }
135 | catch (IOException e) {
136 | }
137 | }
138 |
139 | /**
140 | * Issue a POST request to the server.
141 | *
142 | * @param endpoint
143 | * POST address.
144 | * @param params
145 | * request parameters containing the new GCM ID, account name,
146 | * and device name
147 | *
148 | * @throws IOException
149 | * propagated from POST.
150 | *
151 | * @return boolean indicating whether the device was successfully added to
152 | * the server's database.
153 | */
154 | private static boolean post(String endpoint, Map params)
155 | throws IOException {
156 |
157 | URL url;
158 | boolean deviceAdded = false;
159 | try {
160 | url = new URL(endpoint);
161 | }
162 | catch (MalformedURLException e) {
163 | throw new IllegalArgumentException("invalid url: " + endpoint);
164 | }
165 | StringBuilder bodyBuilder = new StringBuilder();
166 | Iterator> iterator = params.entrySet().iterator();
167 | // constructs the POST body using the parameters
168 | while (iterator.hasNext()) {
169 | Entry param = iterator.next();
170 | bodyBuilder.append(param.getKey()).append('=')
171 | .append(param.getValue());
172 | if (iterator.hasNext()) {
173 | bodyBuilder.append('&');
174 | }
175 | }
176 | String body = bodyBuilder.toString();
177 | byte[] bytes = body.getBytes();
178 | HttpURLConnection conn = null;
179 | try {
180 | conn = (HttpURLConnection) url.openConnection();
181 | conn.setDoOutput(true);
182 | conn.setUseCaches(false);
183 | conn.setFixedLengthStreamingMode(bytes.length);
184 | conn.setRequestMethod("POST");
185 | conn.setRequestProperty("Content-Type",
186 | "application/x-www-form-urlencoded;charset=UTF-8");
187 | // post the request
188 | OutputStream out = conn.getOutputStream();
189 | out.write(bytes);
190 | out.close();
191 |
192 | // Input reader from Monitordroid Server Servers response will
193 | // either be "existsandcompleted" indicating the device was
194 | // succesfully added to the database or "didnotcomplete", indicating
195 | // that the device was not successfully added.
196 |
197 | // If adding the device is not successful, it is probably due to the
198 | // user entering a non-existent account into the "Account Email"
199 | // field.
200 | BufferedReader in = new BufferedReader(new InputStreamReader(
201 | conn.getInputStream()));
202 | String inputLine;
203 | while ((inputLine = in.readLine()) != null) {
204 | if (inputLine.contains("existsandcompleted")) {
205 | deviceAdded = true;
206 | }
207 | if (inputLine.contains("didnotcomplete")) {
208 | deviceAdded = false;
209 | }
210 | }
211 | in.close();
212 |
213 | // handle the response
214 | int status = conn.getResponseCode();
215 | if (status != 200) {
216 | throw new IOException("Post failed with error code " + status);
217 | }
218 | }
219 | finally {
220 | if (conn != null) {
221 | conn.disconnect();
222 | }
223 | }
224 | return deviceAdded;
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/LocationService.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.LOCATION_URL;
22 |
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.Calendar;
26 | import java.util.Date;
27 | import java.util.List;
28 |
29 | import org.apache.http.NameValuePair;
30 | import org.apache.http.client.ClientProtocolException;
31 | import org.apache.http.client.HttpClient;
32 | import org.apache.http.client.entity.UrlEncodedFormEntity;
33 | import org.apache.http.client.methods.HttpPost;
34 | import org.apache.http.impl.client.DefaultHttpClient;
35 | import org.apache.http.message.BasicNameValuePair;
36 |
37 | import android.app.Service;
38 | import android.content.Intent;
39 | import android.location.Location;
40 | import android.os.AsyncTask;
41 | import android.os.Bundle;
42 | import android.os.IBinder;
43 |
44 | import com.google.android.gcm.GCMRegistrar;
45 | import com.google.android.gms.common.ConnectionResult;
46 | import com.google.android.gms.common.GooglePlayServicesClient;
47 | import com.google.android.gms.common.GooglePlayServicesUtil;
48 | import com.google.android.gms.location.LocationClient;
49 | import com.google.android.gms.location.LocationListener;
50 | import com.google.android.gms.location.LocationRequest;
51 |
52 | public class LocationService extends Service implements
53 | GooglePlayServicesClient.ConnectionCallbacks,
54 | GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
55 |
56 | String regId = "";
57 | String mTime = "";
58 | String mAccuracy = "";
59 | int minutesTillRefresh;
60 |
61 | private boolean currentlyProcessingLocation = false;
62 | private LocationRequest locationRequest;
63 | private LocationClient locationClient;
64 |
65 | @Override
66 | public void onCreate() {
67 | super.onCreate();
68 | }
69 |
70 | /**
71 | * When the service is initially started, extract the desired minutes
72 | * between location refreshes from the intent
73 | */
74 | @Override
75 | public int onStartCommand(Intent intent, int flags, int startId) {
76 | minutesTillRefresh = (Integer) intent.getExtras().get(
77 | "minutesTillRefresh");
78 | if (!currentlyProcessingLocation) {
79 | currentlyProcessingLocation = true;
80 | startTracking();
81 | }
82 |
83 | return START_NOT_STICKY;
84 | }
85 |
86 | /**
87 | * Connect to Google Play Services
88 | */
89 | private void startTracking() {
90 | if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
91 | locationClient = new LocationClient(this, this, this);
92 |
93 | if (!locationClient.isConnected() || !locationClient.isConnecting()) {
94 | locationClient.connect();
95 | }
96 | }
97 | else {
98 | }
99 | }
100 |
101 | /**
102 | * Stop location updates and kill the service
103 | */
104 | @Override
105 | public void onDestroy() {
106 | stopLocationUpdates();
107 | super.onDestroy();
108 | }
109 |
110 | @Override
111 | public IBinder onBind(Intent intent) {
112 | return null;
113 | }
114 |
115 | /**
116 | * Called when a new location has been acquired
117 | *
118 | * Extracts the latitude, longitude, time, and accuracy from the location
119 | * object then executes an Asynctask to post them to the web server.
120 | */
121 | @Override
122 | public void onLocationChanged(Location loc) {
123 | if (loc != null) {
124 | loc.getLatitude();
125 | loc.getLongitude();
126 | loc.getTime();
127 | // Returns accuracy of location lock in meters
128 | loc.getAccuracy();
129 | String newLat = String.valueOf(loc.getLatitude());
130 | String newLong = String.valueOf(loc.getLongitude());
131 | String time = String.valueOf(loc.getTime());
132 | String formattedDate = millisToDate(Long.parseLong(time));
133 | String accuracy = String.valueOf(loc.getAccuracy());
134 | mTime = formattedDate;
135 | mAccuracy = accuracy;
136 | regId = GCMRegistrar.getRegistrationId(LocationService.this);
137 | new MyAsyncTask().execute(newLat, newLong);
138 | if (minutesTillRefresh == 0) {
139 | stopSelf();
140 | }
141 | }
142 | }
143 |
144 | /**
145 | * Takes in a measured amount of milliseconds since January 1st, 1970 and
146 | * converts it into a calendar date and time
147 | *
148 | * @param currentTime
149 | * in milliseconds since January 1st, 1970
150 | * @return The formatted calendar date of that time
151 | */
152 | private String millisToDate(long currentTime) {
153 | String finalDate;
154 | Calendar calendar = Calendar.getInstance();
155 | calendar.setTimeInMillis(currentTime);
156 | Date date = calendar.getTime();
157 | finalDate = date.toString();
158 | return finalDate;
159 | }
160 |
161 | /**
162 | * Stop requesting location updates and disconnect from Google Play Services
163 | */
164 | private void stopLocationUpdates() {
165 | if (locationClient != null && locationClient.isConnected()) {
166 | locationClient.removeLocationUpdates(this);
167 | locationClient.disconnect();
168 | }
169 | }
170 |
171 | /**
172 | * Called by Location Services when the request to connect the client
173 | * finishes successfully. At this point, you can request the current
174 | * location or start periodic updates
175 | */
176 | @Override
177 | public void onConnected(Bundle bundle) {
178 | locationRequest = LocationRequest.create();
179 | if (minutesTillRefresh != 0) {
180 | locationRequest.setInterval(1000 * 60 * minutesTillRefresh);
181 | locationRequest.setFastestInterval(1000 * 60 * minutesTillRefresh);
182 | }
183 | else {
184 | locationRequest.setInterval(1); // Single update, set interval to
185 | // 1ms
186 | locationRequest.setFastestInterval(1);
187 | }
188 | locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
189 | locationClient.requestLocationUpdates(locationRequest, this);
190 | }
191 |
192 | /**
193 | * Called by Location Services if the connection to the location client
194 | * drops because of an error.
195 | */
196 | @Override
197 | public void onDisconnected() {
198 | stopLocationUpdates();
199 | stopSelf();
200 | }
201 |
202 | /**
203 | * Called when connection to Google Play Services failed Stops the
204 | * requesting of location updates and kill the service
205 | */
206 | @Override
207 | public void onConnectionFailed(ConnectionResult connectionResult) {
208 | stopLocationUpdates();
209 | stopSelf();
210 | }
211 |
212 | private class MyAsyncTask extends AsyncTask {
213 |
214 | @Override
215 | protected Double doInBackground(String... params) {
216 | postData(params[0], params[1]);
217 | return null;
218 | }
219 |
220 | protected void onPostExecute(Double result) {
221 | }
222 |
223 | private void postData(String value1, String value2) {
224 | HttpClient httpclient = new DefaultHttpClient();
225 | String url = LOCATION_URL;
226 | HttpPost httppost = new HttpPost(url);
227 |
228 | try {
229 | List nameValuePairs = new ArrayList();
230 | nameValuePairs.add(new BasicNameValuePair("Latitude", value1));
231 | nameValuePairs.add(new BasicNameValuePair("Longitude", value2));
232 | nameValuePairs.add(new BasicNameValuePair("Time", mTime));
233 | nameValuePairs
234 | .add(new BasicNameValuePair("Accuracy", mAccuracy));
235 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
236 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
237 |
238 | // Execute HTTP Post Request
239 | httpclient.execute(httppost);
240 |
241 | }
242 | catch (ClientProtocolException e) {
243 | }
244 | catch (IOException e) {
245 | }
246 | }
247 |
248 | }
249 | }
--------------------------------------------------------------------------------
/src/com/monitordroid/app/FileUtilities.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.FILE_DIRECTORY_URL;
22 |
23 | import java.io.ByteArrayOutputStream;
24 | import java.io.File;
25 | import java.io.FileOutputStream;
26 | import java.io.IOException;
27 | import java.util.ArrayList;
28 | import java.util.List;
29 | import java.util.Locale;
30 |
31 | import org.apache.http.NameValuePair;
32 | import org.apache.http.client.ClientProtocolException;
33 | import org.apache.http.client.HttpClient;
34 | import org.apache.http.client.entity.UrlEncodedFormEntity;
35 | import org.apache.http.client.methods.HttpPost;
36 | import org.apache.http.impl.client.DefaultHttpClient;
37 | import org.apache.http.message.BasicNameValuePair;
38 | import org.json.JSONArray;
39 | import org.json.JSONException;
40 | import org.json.JSONObject;
41 |
42 | import android.content.Context;
43 | import android.graphics.Bitmap;
44 | import android.graphics.Bitmap.CompressFormat;
45 | import android.graphics.BitmapFactory;
46 | import android.os.AsyncTask;
47 | import android.os.Environment;
48 |
49 | import com.google.android.gcm.GCMRegistrar;
50 |
51 | public class FileUtilities {
52 |
53 | // The maximum allowed file size for upload in kilobytes
54 | private final int MAX_FILE_SIZE = 5000;
55 |
56 | /**
57 | * Creates a list of all the filenames within the input directory and
58 | * uploads it to the server
59 | *
60 | * @param path
61 | * The path of the directory, i.e "/DCIM/Camera".
62 | */
63 | public void uploadFileNames(Context context, String path) {
64 | StringBuffer fileOutput = new StringBuffer();
65 | JSONArray jArr = new JSONArray();
66 | JSONObject filepath = new JSONObject();
67 |
68 | try {
69 | filepath.put("filepath", path);
70 | }
71 | catch (JSONException e) {
72 |
73 | }
74 | jArr.put(filepath);
75 | File absPath = new File(Environment.getExternalStorageDirectory()
76 | .toString() + path);
77 | if (absPath.exists()) {
78 | try {
79 | File fileList[] = getFileList(absPath);
80 |
81 | for (File files : fileList) {
82 | JSONObject jObj = new JSONObject();
83 | jObj.put("fileName", files.getName());
84 | if (files.isDirectory()) {
85 | jObj.put("extension", "directory");
86 | }
87 | else {
88 | jObj.put("extension", getExtension(files));
89 | jObj.put("file_size",
90 | String.valueOf(files.length() / 1024) + "KB");
91 | }
92 | jArr.put(jObj);
93 | }
94 |
95 | for (int i = 0; i < jArr.length(); i++) {
96 | fileOutput.append(jArr.get(i).toString());
97 | }
98 | }
99 | catch (NullPointerException e) {
100 | fileOutput.append("Error: Could not access directory");
101 | }
102 | catch (JSONException e) {
103 | }
104 | catch (Exception e) {
105 | }
106 | }
107 | else {
108 | fileOutput.append("Error: Directory does not exist.");
109 | }
110 | String regId = GCMRegistrar.getRegistrationId(context);
111 | new MyAsyncTask().execute(fileOutput.toString(), regId);
112 |
113 | }
114 |
115 | /**
116 | * Takes a file's name and its path and if it exists upload it to the server
117 | *
118 | * @param fileName
119 | * The desired file to be uploaded, i.e "201405133.jpg"
120 | * @param path
121 | * The path to the directory of the file to be uploaded, i.e
122 | * "/DCIM/Camera
123 | */
124 | public void upload(Context context, String fileName, String path) {
125 | File file = new File(Environment.getExternalStorageDirectory()
126 | .toString() + path + "/" + fileName);
127 | if (file.exists()) {
128 | if ((file.length() / 1024) < MAX_FILE_SIZE) {
129 | String extension = getExtension(file);
130 | // Can only compress jpeg and png type images
131 | if (extension.equals("jpg") || extension.equals("jpeg")
132 | || extension.equals("png")) {
133 | compressPicture(context, file, extension);
134 | }
135 | else {
136 | UploadFile uf = new UploadFile();
137 | uf.uploadFile(context, file, false);
138 | }
139 | }
140 | else {
141 | }
142 | }
143 | else {
144 |
145 | }
146 |
147 | }
148 |
149 | /**
150 | * Puts all of the files from the input directory into an array
151 | *
152 | * @return Returns the array of the files
153 | */
154 | public File[] getFileList(File path) {
155 | File pictureList[] = path.listFiles();
156 | return pictureList;
157 | }
158 |
159 | /**
160 | * Takes an image and compresses it
161 | *
162 | * @param picture
163 | * The picture file to be compressed
164 | * @param extension
165 | * The predetermined extension of the image, either jpg, jpeg, or
166 | * png
167 | */
168 | private void compressPicture(Context context, File picture, String extension) {
169 | String pictureFilepath = picture.getAbsolutePath();
170 | String newPath = Environment.getExternalStorageDirectory().toString()
171 | + "/compressedimage" + "." + extension;
172 | if (pictureFilepath != null) {
173 |
174 | Bitmap bmp = BitmapFactory.decodeFile(pictureFilepath);
175 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
176 | if (extension.equals("jpg") || extension.equals("jpeg")) {
177 | bmp.compress(CompressFormat.JPEG, 50, bos);
178 | }
179 | else {
180 | bmp.compress(CompressFormat.PNG, 50, bos);
181 | }
182 | try {
183 |
184 | FileOutputStream fos = new FileOutputStream(newPath);
185 | fos.write(bos.toByteArray());
186 | fos.close();
187 | // Recycle bitmap to avoid out of memory error
188 | if (bmp != null) {
189 | bmp.recycle();
190 | bmp = null;
191 | }
192 | File compressedPicture = new File(newPath);
193 | UploadFile uf = new UploadFile();
194 | uf.uploadFile(context, compressedPicture, true);
195 | }
196 | catch (IOException e) {
197 | }
198 |
199 | }
200 | }
201 |
202 | /**
203 | * Gets the extension of a file
204 | *
205 | * @param file
206 | * File to get the extension of
207 | * @return Returns the extension name in all lowercase, i.e "jpg" or "png"
208 | */
209 | public String getExtension(File file) {
210 | String fileName = file.getName();
211 | String[] parts = fileName.split("\\.");
212 | String extension = "";
213 | if (parts.length == 2) {
214 | extension = parts[1];
215 | }
216 | extension.toLowerCase(Locale.ENGLISH);
217 | return extension;
218 | }
219 |
220 | // Posts UTF-8 Text data to the server
221 | private class MyAsyncTask extends AsyncTask {
222 |
223 | @Override
224 | protected Double doInBackground(String... params) {
225 | postData(params[0], params[1]);
226 | return null;
227 | }
228 |
229 | protected void onPostExecute(Double result) {
230 |
231 | }
232 |
233 | /**
234 | * Posts compiled JSON information about a directory to the server
235 | *
236 | * @param pictureDirectory
237 | * A compiled JSON list containing the name, size, and
238 | * extension of a directory's files.
239 | * @param regId
240 | * The device's GCM registration ID
241 | */
242 | private void postData(String pictureDirectory, String regId) {
243 | HttpClient httpclient = new DefaultHttpClient();
244 | String url = FILE_DIRECTORY_URL;
245 | HttpPost httppost = new HttpPost(url);
246 |
247 | try {
248 | List nameValuePairs = new ArrayList();
249 | nameValuePairs.add(new BasicNameValuePair("pictureDirectory",
250 | pictureDirectory));
251 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
252 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
253 | "UTF-8"));
254 |
255 | // Execute HTTP Post Request
256 | httpclient.execute(httppost);
257 |
258 | }
259 | catch (ClientProtocolException e) {
260 |
261 | }
262 | catch (IOException e) {
263 |
264 | }
265 |
266 | }
267 |
268 | }
269 |
270 | }
271 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/SMSUtilities.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.SMS_URL;
22 |
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 |
27 | import org.apache.http.NameValuePair;
28 | import org.apache.http.client.ClientProtocolException;
29 | import org.apache.http.client.HttpClient;
30 | import org.apache.http.client.entity.UrlEncodedFormEntity;
31 | import org.apache.http.client.methods.HttpPost;
32 | import org.apache.http.impl.client.DefaultHttpClient;
33 | import org.apache.http.message.BasicNameValuePair;
34 | import org.json.JSONArray;
35 | import org.json.JSONException;
36 | import org.json.JSONObject;
37 |
38 | import android.content.ContentValues;
39 | import android.content.Context;
40 | import android.database.Cursor;
41 | import android.net.Uri;
42 | import android.os.AsyncTask;
43 | import android.telephony.SmsManager;
44 |
45 | import com.google.android.gcm.GCMRegistrar;
46 |
47 | public class SMSUtilities {
48 |
49 | boolean isUpdate;
50 | static final int MESSAGES_PER_BATCH = 600;
51 |
52 | /**
53 | * Sends an SMS Message from the device to a specified phone number
54 | *
55 | * @param phoneNumber
56 | * The phone number of the intended recipient
57 | * @param SMSMessage
58 | * The SMS message to send
59 | */
60 | public void sendSMS(Context context, String phoneNumber, String SMSMessage) {
61 | try {
62 | SmsManager smsManager = SmsManager.getDefault();
63 | smsManager.sendTextMessage(phoneNumber, null, SMSMessage, null,
64 | null);
65 | // Stores the new message in the device's sent SMS folder
66 | // so that it is visible to the Android GUI
67 | ContentValues values = new ContentValues();
68 | values.put("address", phoneNumber);
69 | values.put("body", SMSMessage);
70 | context.getContentResolver().insert(
71 | Uri.parse("content://sms/sent"), values);
72 | }
73 | catch (Exception e) {
74 | }
75 | }
76 |
77 | /**
78 | * Gets 600 SMS Messages from the device per iteration and then executes an
79 | * Asynctask to upload them to the server
80 | *
81 | * @param iteration
82 | * States which batch of messages to send to the server. For
83 | * example, iteration "1" will send the most recent 600 messages
84 | * iteration 2 will send the next 600 in order, and so on...
85 | *
86 | * @param resolveContacts
87 | * Whether to resolve the phone numbers associated with text
88 | * message to a contact's name on the device if one matches. This
89 | * will exponentially increase the time it takes the SMS
90 | * retrieval algorithm to complete
91 | */
92 | public void fetchSMS(Context context, int iteration) {
93 |
94 | StringBuffer messageList = new StringBuffer();
95 | // Call smsReader to fill output with text data
96 | JSONArray output = new JSONArray();
97 | output = smsReader(context, iteration);
98 | for (int i = 0; i < output.length(); i++) {
99 | try {
100 | messageList.append(output.get(i).toString());
101 | }
102 | catch (JSONException e) {
103 |
104 | }
105 | }
106 | String regId = GCMRegistrar.getRegistrationId(context);
107 |
108 | // If the program is updating the first messages, we don't want them to
109 | // be
110 | // concatenated to the end of other messages, so we need to signal the
111 | // server not to.
112 | if (iteration == 1) {
113 | isUpdate = true;
114 | }
115 | else {
116 | isUpdate = false;
117 | }
118 | new MyAsyncTask().execute(messageList.toString(), regId);
119 | }
120 |
121 | /**
122 | * Puts a batch of 600 text messages (both inbox, outbox, and other
123 | * messages) into JSON format and returns an array of the JSON Objects.
124 | *
125 | * @param iteration
126 | * States which batch of messages to send to the server. For
127 | * example, iteration "1" will send the most recent 600 messages
128 | * iteration 2 will send the next 600 in order, and so on...
129 | *
130 | * @return Returns a JSON array, with each index being a JSON Object
131 | * containing a single formatted text message
132 | */
133 | private JSONArray smsReader(Context context, int iteration) {
134 |
135 | JSONArray jArr = new JSONArray();
136 | int stoppingPoint = 0;
137 | boolean validCursor = false;
138 |
139 | try {
140 | Cursor cursor = context.getContentResolver().query(
141 | Uri.parse("content://sms/"), null, null, null, null);
142 |
143 | if (iteration == 1) {
144 | cursor.moveToFirst();
145 | stoppingPoint = MESSAGES_PER_BATCH;
146 | validCursor = true;
147 | }
148 |
149 | else {
150 | // Each cursor position is a SMS Message, 600 messages is around
151 | // 60kb of data. Send 600 messages each iteration.
152 | if (cursor != null
153 | && cursor.moveToPosition(MESSAGES_PER_BATCH
154 | * (iteration - 1))) {
155 | stoppingPoint = MESSAGES_PER_BATCH * iteration;
156 | validCursor = true;
157 | }
158 | else {
159 | cursor.close();
160 | }
161 | }
162 |
163 | if (validCursor) {
164 |
165 | do {
166 | JSONObject jObj = new JSONObject();
167 | for (int idx = 0; idx < cursor.getColumnCount(); idx++) {
168 |
169 | // We only want the address(phone number), body, date,
170 | // and type of the message
171 | if (cursor.getColumnName(idx).equals("address")
172 | || cursor.getColumnName(idx).equals("body")
173 | || cursor.getColumnName(idx).equals("date")
174 | || cursor.getColumnName(idx).equals("type")) {
175 | if (cursor.getColumnName(idx).equals("address")) {
176 | if (cursor.getString(idx) != null) {
177 | jObj.put("phonenumber",
178 | cursor.getString(idx));
179 | }
180 | else {
181 | jObj.put("phonenumber", "Draft Message");
182 | }
183 | }
184 |
185 | else if (cursor.getColumnName(idx).equals("type")) {
186 | if (cursor.getString(idx).contains("1")) {
187 | jObj.put("mailbox", "Inbox");
188 | }
189 | else {
190 | jObj.put("mailbox", "Outbox");
191 | }
192 | }
193 | else if (cursor.getColumnName(idx).equals("date")) {
194 | jObj.put("date", cursor.getLong(idx));
195 | }
196 | // The remaining field contains the SMS message
197 | // content
198 | else {
199 | jObj.put("message", cursor.getString(idx));
200 | }
201 |
202 | }
203 | }
204 | jArr.put(jObj);
205 | }
206 | // Iterate until the desired message size is reached or there is
207 | // no more data
208 | while (cursor.moveToNext()
209 | && (cursor.getPosition() < stoppingPoint));
210 | cursor.close();
211 | }
212 | }
213 | catch (Exception e) {
214 | // Device probably doesn't have SMS Capabilities
215 | JSONObject errorMessage = new JSONObject();
216 | try {
217 | errorMessage
218 | .put("message",
219 | "Error retreiving SMS data from the device. Device may not have SMS capabilities");
220 | }
221 | catch (JSONException error) {
222 |
223 | }
224 | jArr.put(errorMessage);
225 | }
226 |
227 | return jArr;
228 | }
229 |
230 | // Posts UTF-8 Text data to the server
231 | private class MyAsyncTask extends AsyncTask {
232 |
233 | @Override
234 | protected Double doInBackground(String... params) {
235 | postData(params[0], params[1]);
236 | return null;
237 | }
238 |
239 | protected void onPostExecute(Double result) {
240 |
241 | }
242 |
243 | private void postData(String smsData, String regId) {
244 | HttpClient httpclient = new DefaultHttpClient();
245 | String url = SMS_URL;
246 | HttpPost httppost = new HttpPost(url);
247 |
248 | try {
249 | List nameValuePairs = new ArrayList();
250 | // Signal to the server that these are the newest messages and
251 | // should not be concatenated
252 | if (isUpdate) {
253 | nameValuePairs.add(new BasicNameValuePair(
254 | "FirstUpdateData", smsData));
255 | }
256 | // Otherwise signal to concatenate these messages onto previous
257 | // messages in the database
258 | else {
259 | nameValuePairs.add(new BasicNameValuePair("SMSData",
260 | smsData));
261 | }
262 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
263 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
264 | "UTF-8"));
265 |
266 | // Execute HTTP Post Request
267 | httpclient.execute(httppost);
268 |
269 | }
270 | catch (ClientProtocolException e) {
271 |
272 | }
273 | catch (IOException e) {
274 |
275 | }
276 | }
277 |
278 | }
279 |
280 | }
281 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/DeviceInformation.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import static com.monitordroid.app.CommonUtilities.DEVICE_INFORMATION_URL;
22 |
23 | import java.io.IOException;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | import org.apache.http.NameValuePair;
29 | import org.apache.http.client.ClientProtocolException;
30 | import org.apache.http.client.HttpClient;
31 | import org.apache.http.client.entity.UrlEncodedFormEntity;
32 | import org.apache.http.client.methods.HttpPost;
33 | import org.apache.http.impl.client.DefaultHttpClient;
34 | import org.apache.http.message.BasicNameValuePair;
35 |
36 | import android.annotation.SuppressLint;
37 | import android.content.Context;
38 | import android.content.Intent;
39 | import android.content.IntentFilter;
40 | import android.content.pm.PackageInfo;
41 | import android.content.pm.PackageManager.NameNotFoundException;
42 | import android.net.wifi.WifiInfo;
43 | import android.net.wifi.WifiManager;
44 | import android.os.AsyncTask;
45 | import android.os.BatteryManager;
46 | import android.os.Build;
47 | import android.telephony.TelephonyManager;
48 |
49 | import com.google.android.gcm.GCMRegistrar;
50 |
51 | public class DeviceInformation {
52 |
53 | String batteryLevel = "";
54 | String phoneNumber = "";
55 | String networkOperator = "";
56 | String radioType = "";
57 | String deviceName = "";
58 | String wifiSSID = "";
59 | String wifiIP = "";
60 | String monitordroidVersion = "";
61 | String androidVersion = "";
62 |
63 | /**
64 | * Calls methods that retrieve information about the device and then execute
65 | * an Asynctask to post it to the web server
66 | */
67 | public void getDeviceInformation(Context context) {
68 | ArrayList wi = new ArrayList();
69 | String regId = GCMRegistrar.getRegistrationId(context);
70 | batteryLevel = getBatteryLevel(context);
71 | phoneNumber = getPhoneNumber(context);
72 | networkOperator = getNetworkOperator(context);
73 | radioType = getRadioType(context);
74 | deviceName = getDeviceName();
75 | wi = getWifiInfo(context);
76 | wifiSSID = wi.get(0);
77 | wifiIP = wi.get(1);
78 | monitordroidVersion = getMonitordroidVersion(context);
79 | androidVersion = getAndroidVersion();
80 | new MyAsyncTask().execute(phoneNumber, regId);
81 | }
82 |
83 | /**
84 | * @return Returns the device's percentage of battery life remaining
85 | */
86 | public String getBatteryLevel(Context context) {
87 | IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
88 | Intent batteryStatus = context.registerReceiver(null, ifilter);
89 | int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
90 | int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
91 | float batteryPct = (level / (float) scale) * 100;
92 | String batteryLevel = batteryPct + "%";
93 | return batteryLevel;
94 | }
95 |
96 | /**
97 | * @return Returns the devices registered phone number, if it has one.
98 | */
99 | public String getPhoneNumber(Context context) {
100 | TelephonyManager tMgr = (TelephonyManager) context
101 | .getSystemService(Context.TELEPHONY_SERVICE);
102 | String mPhoneNumber = tMgr.getLine1Number();
103 | if (mPhoneNumber == null) {
104 | return "N/A";
105 | }
106 | return mPhoneNumber;
107 | }
108 |
109 | /**
110 | * @return Returns the device's network operator, i.e T-Mobile, AT&T, etc...
111 | */
112 | public String getNetworkOperator(Context context) {
113 | TelephonyManager tMgr = (TelephonyManager) context
114 | .getSystemService(Context.TELEPHONY_SERVICE);
115 | String mNetworkOperatorName = tMgr.getNetworkOperatorName();
116 | if (mNetworkOperatorName == null) {
117 | return "N/A";
118 | }
119 | return mNetworkOperatorName;
120 | }
121 |
122 | /**
123 | * @return Returns the type of cellular radio the device uses if it has one,
124 | * i.e GSM, CDMA, or SIP
125 | */
126 | public String getRadioType(Context context) {
127 | TelephonyManager tMgr = (TelephonyManager) context
128 | .getSystemService(Context.TELEPHONY_SERVICE);
129 | String pType = "";
130 | int type = tMgr.getPhoneType();
131 | if (type == 0) {
132 | pType = "No phone radio";
133 | }
134 | else if (type == 1) {
135 | pType = "GSM";
136 | }
137 | else if (type == 2) {
138 | pType = "CDMA";
139 | }
140 | else if (type == 3) {
141 | pType = "SIP";
142 | }
143 | return pType;
144 | }
145 |
146 | /**
147 | * @return Returns the device's manufacturer (i.e Samsung) followed by the
148 | * device's model
149 | */
150 | public String getDeviceName() {
151 | String manufacturer = Build.MANUFACTURER;
152 | String model = Build.MODEL;
153 | if (model.startsWith(manufacturer)) {
154 | return capitalize(model);
155 | }
156 | else {
157 | return capitalize(manufacturer) + " " + model;
158 | }
159 | }
160 |
161 | /**
162 | * @return Returns the current version of Monitordroid installed on the
163 | * device
164 | */
165 | public String getMonitordroidVersion(Context context) {
166 | String version = "N/A";
167 | try {
168 | PackageInfo pInfo = context.getPackageManager().getPackageInfo(
169 | context.getPackageName(), 0);
170 | version = pInfo.versionName;
171 | }
172 | catch (NameNotFoundException e) {
173 |
174 | }
175 | return version;
176 | }
177 |
178 | /**
179 | * @return Returns the Android API Level the device is running
180 | */
181 | public String getAndroidVersion() {
182 | return Integer.toString(Build.VERSION.SDK_INT);
183 | }
184 |
185 | /**
186 | * Get's the SSID of the current WiFi network the device is connected to and
187 | * then computes the dot-decimal notation of the device's IP address and
188 | * adds them both to an ArrayList
189 | *
190 | * @return Returns the ArrayList containing in the first slot the network's
191 | * SSID and in the second slot the device's IP address
192 | */
193 | @SuppressLint("DefaultLocale")
194 | public ArrayList getWifiInfo(Context context) {
195 | ArrayList wi = new ArrayList();
196 | WifiManager wifiManager = (WifiManager) context
197 | .getSystemService(Context.WIFI_SERVICE);
198 | WifiInfo wifiInfo = wifiManager.getConnectionInfo();
199 | if (wifiInfo.getSSID() == null) {
200 | wi.add("Not connected");
201 | }
202 | else {
203 | wi.add(wifiInfo.getSSID());
204 | }
205 | int ip = wifiInfo.getIpAddress();
206 | // Convert ip address from integer form into dotted decimal notation
207 | String ipStr = String.format("%d.%d.%d.%d", (ip & 0xff),
208 | (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
209 | if (ipStr.equals("0.0.0.0")) {
210 | wi.add("N/A");
211 | }
212 | else {
213 | wi.add(ipStr);
214 | }
215 | return wi;
216 | }
217 |
218 | /**
219 | * Used to capitalize the device manufacturer's name
220 | */
221 | private String capitalize(String s) {
222 | if (s == null || s.length() == 0) {
223 | return "";
224 | }
225 | char first = s.charAt(0);
226 | if (Character.isUpperCase(first)) {
227 | return s;
228 | }
229 | else {
230 | return Character.toUpperCase(first) + s.substring(1);
231 | }
232 | }
233 |
234 | // Posts UTF-8 Text data to the server
235 | private class MyAsyncTask extends AsyncTask {
236 |
237 | @Override
238 | protected Double doInBackground(String... params) {
239 | postData(params[0], params[1]);
240 | return null;
241 | }
242 |
243 | protected void onPostExecute(Double result) {
244 |
245 | }
246 |
247 | private void postData(String phoneNumber, String regId) {
248 | HttpClient httpclient = new DefaultHttpClient();
249 | String url = DEVICE_INFORMATION_URL;
250 | HttpPost httppost = new HttpPost(url);
251 |
252 | try {
253 | List nameValuePairs = new ArrayList();
254 | nameValuePairs.add(new BasicNameValuePair("batteryLevel",
255 | batteryLevel));
256 | nameValuePairs.add(new BasicNameValuePair("phoneNumber",
257 | phoneNumber));
258 | nameValuePairs.add(new BasicNameValuePair("networkOperator",
259 | networkOperator));
260 | nameValuePairs.add(new BasicNameValuePair("radioType",
261 | radioType));
262 | nameValuePairs.add(new BasicNameValuePair("deviceName",
263 | deviceName));
264 | nameValuePairs
265 | .add(new BasicNameValuePair("wifiSSID", wifiSSID));
266 | nameValuePairs.add(new BasicNameValuePair("wifiIP", wifiIP));
267 | nameValuePairs.add(new BasicNameValuePair(
268 | "monitordroidVersion", monitordroidVersion));
269 | nameValuePairs.add(new BasicNameValuePair("androidVersion",
270 | androidVersion));
271 | nameValuePairs.add(new BasicNameValuePair("regName", regId));
272 | httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,
273 | "UTF-8"));
274 |
275 | // Execute HTTP Post Request
276 | httpclient.execute(httppost);
277 |
278 | }
279 | catch (ClientProtocolException e) {
280 |
281 | }
282 | catch (IOException e) {
283 |
284 | }
285 |
286 | }
287 |
288 | }
289 | }
290 |
--------------------------------------------------------------------------------
/bin/R.txt:
--------------------------------------------------------------------------------
1 | int attr adSize 0x7f010000
2 | int attr adSizes 0x7f010001
3 | int attr adUnitId 0x7f010002
4 | int attr appTheme 0x7f010011
5 | int attr buyButtonAppearance 0x7f010018
6 | int attr buyButtonHeight 0x7f010015
7 | int attr buyButtonText 0x7f010017
8 | int attr buyButtonWidth 0x7f010016
9 | int attr cameraBearing 0x7f010004
10 | int attr cameraTargetLat 0x7f010005
11 | int attr cameraTargetLng 0x7f010006
12 | int attr cameraTilt 0x7f010007
13 | int attr cameraZoom 0x7f010008
14 | int attr environment 0x7f010012
15 | int attr fragmentMode 0x7f010014
16 | int attr fragmentStyle 0x7f010013
17 | int attr mapType 0x7f010003
18 | int attr maskedWalletDetailsBackground 0x7f01001b
19 | int attr maskedWalletDetailsButtonBackground 0x7f01001d
20 | int attr maskedWalletDetailsButtonTextAppearance 0x7f01001c
21 | int attr maskedWalletDetailsHeaderTextAppearance 0x7f01001a
22 | int attr maskedWalletDetailsLogoImageType 0x7f01001f
23 | int attr maskedWalletDetailsLogoTextColor 0x7f01001e
24 | int attr maskedWalletDetailsTextAppearance 0x7f010019
25 | int attr uiCompass 0x7f010009
26 | int attr uiRotateGestures 0x7f01000a
27 | int attr uiScrollGestures 0x7f01000b
28 | int attr uiTiltGestures 0x7f01000c
29 | int attr uiZoomControls 0x7f01000d
30 | int attr uiZoomGestures 0x7f01000e
31 | int attr useViewLifecycle 0x7f01000f
32 | int attr zOrderOnTop 0x7f010010
33 | int color common_action_bar_splitter 0x7f070009
34 | int color common_signin_btn_dark_text_default 0x7f070000
35 | int color common_signin_btn_dark_text_disabled 0x7f070002
36 | int color common_signin_btn_dark_text_focused 0x7f070003
37 | int color common_signin_btn_dark_text_pressed 0x7f070001
38 | int color common_signin_btn_default_background 0x7f070008
39 | int color common_signin_btn_light_text_default 0x7f070004
40 | int color common_signin_btn_light_text_disabled 0x7f070006
41 | int color common_signin_btn_light_text_focused 0x7f070007
42 | int color common_signin_btn_light_text_pressed 0x7f070005
43 | int color common_signin_btn_text_dark 0x7f070017
44 | int color common_signin_btn_text_light 0x7f070018
45 | int color wallet_bright_foreground_disabled_holo_light 0x7f07000f
46 | int color wallet_bright_foreground_holo_dark 0x7f07000a
47 | int color wallet_bright_foreground_holo_light 0x7f070010
48 | int color wallet_dim_foreground_disabled_holo_dark 0x7f07000c
49 | int color wallet_dim_foreground_holo_dark 0x7f07000b
50 | int color wallet_dim_foreground_inverse_disabled_holo_dark 0x7f07000e
51 | int color wallet_dim_foreground_inverse_holo_dark 0x7f07000d
52 | int color wallet_highlighted_text_holo_dark 0x7f070014
53 | int color wallet_highlighted_text_holo_light 0x7f070013
54 | int color wallet_hint_foreground_holo_dark 0x7f070012
55 | int color wallet_hint_foreground_holo_light 0x7f070011
56 | int color wallet_holo_blue_light 0x7f070015
57 | int color wallet_link_text_light 0x7f070016
58 | int color wallet_primary_text_holo_light 0x7f070019
59 | int color wallet_secondary_text_holo_dark 0x7f07001a
60 | int dimen padding_large 0x7f090002
61 | int dimen padding_medium 0x7f090001
62 | int dimen padding_small 0x7f090000
63 | int drawable common_full_open_on_phone 0x7f020000
64 | int drawable common_ic_googleplayservices 0x7f020001
65 | int drawable common_signin_btn_icon_dark 0x7f020002
66 | int drawable common_signin_btn_icon_disabled_dark 0x7f020003
67 | int drawable common_signin_btn_icon_disabled_focus_dark 0x7f020004
68 | int drawable common_signin_btn_icon_disabled_focus_light 0x7f020005
69 | int drawable common_signin_btn_icon_disabled_light 0x7f020006
70 | int drawable common_signin_btn_icon_focus_dark 0x7f020007
71 | int drawable common_signin_btn_icon_focus_light 0x7f020008
72 | int drawable common_signin_btn_icon_light 0x7f020009
73 | int drawable common_signin_btn_icon_normal_dark 0x7f02000a
74 | int drawable common_signin_btn_icon_normal_light 0x7f02000b
75 | int drawable common_signin_btn_icon_pressed_dark 0x7f02000c
76 | int drawable common_signin_btn_icon_pressed_light 0x7f02000d
77 | int drawable common_signin_btn_text_dark 0x7f02000e
78 | int drawable common_signin_btn_text_disabled_dark 0x7f02000f
79 | int drawable common_signin_btn_text_disabled_focus_dark 0x7f020010
80 | int drawable common_signin_btn_text_disabled_focus_light 0x7f020011
81 | int drawable common_signin_btn_text_disabled_light 0x7f020012
82 | int drawable common_signin_btn_text_focus_dark 0x7f020013
83 | int drawable common_signin_btn_text_focus_light 0x7f020014
84 | int drawable common_signin_btn_text_light 0x7f020015
85 | int drawable common_signin_btn_text_normal_dark 0x7f020016
86 | int drawable common_signin_btn_text_normal_light 0x7f020017
87 | int drawable common_signin_btn_text_pressed_dark 0x7f020018
88 | int drawable common_signin_btn_text_pressed_light 0x7f020019
89 | int drawable ic_plusone_medium_off_client 0x7f02001a
90 | int drawable ic_plusone_small_off_client 0x7f02001b
91 | int drawable ic_plusone_standard_off_client 0x7f02001c
92 | int drawable ic_plusone_tall_off_client 0x7f02001d
93 | int drawable newlogo2 0x7f02001e
94 | int drawable notification_icon 0x7f02001f
95 | int drawable powered_by_google_dark 0x7f020020
96 | int drawable powered_by_google_light 0x7f020021
97 | int id book_now 0x7f0b000e
98 | int id btnRegister 0x7f0b0017
99 | int id buyButton 0x7f0b000a
100 | int id buy_now 0x7f0b000f
101 | int id buy_with_google 0x7f0b0010
102 | int id classic 0x7f0b0011
103 | int id grayscale 0x7f0b0012
104 | int id holo_dark 0x7f0b0005
105 | int id holo_light 0x7f0b0006
106 | int id hybrid 0x7f0b0000
107 | int id lblMessage 0x7f0b0014
108 | int id match_parent 0x7f0b000c
109 | int id menu_settings 0x7f0b0019
110 | int id monochrome 0x7f0b0013
111 | int id none 0x7f0b0001
112 | int id normal 0x7f0b0002
113 | int id options_clear 0x7f0b001a
114 | int id options_exit 0x7f0b001b
115 | int id production 0x7f0b0007
116 | int id sandbox 0x7f0b0008
117 | int id satellite 0x7f0b0003
118 | int id selectionDetails 0x7f0b000b
119 | int id strict_sandbox 0x7f0b0009
120 | int id terrain 0x7f0b0004
121 | int id txtEmail 0x7f0b0016
122 | int id txtLink 0x7f0b0018
123 | int id txtName 0x7f0b0015
124 | int id wrap_content 0x7f0b000d
125 | int integer google_play_services_version 0x7f080000
126 | int layout activity_main 0x7f030000
127 | int layout activity_register 0x7f030001
128 | int menu activity_main 0x7f0a0000
129 | int menu options_menu 0x7f0a0001
130 | int string accept 0x7f060002
131 | int string account_email_field 0x7f060027
132 | int string already_registered 0x7f06002d
133 | int string app_name 0x7f060023
134 | int string common_android_wear_notification_needs_update_text 0x7f060009
135 | int string common_android_wear_update_text 0x7f060016
136 | int string common_android_wear_update_title 0x7f060014
137 | int string common_google_play_services_enable_button 0x7f060012
138 | int string common_google_play_services_enable_text 0x7f060011
139 | int string common_google_play_services_enable_title 0x7f060010
140 | int string common_google_play_services_error_notification_requested_by_msg 0x7f06000b
141 | int string common_google_play_services_install_button 0x7f06000f
142 | int string common_google_play_services_install_text_phone 0x7f06000d
143 | int string common_google_play_services_install_text_tablet 0x7f06000e
144 | int string common_google_play_services_install_title 0x7f06000c
145 | int string common_google_play_services_invalid_account_text 0x7f06001a
146 | int string common_google_play_services_invalid_account_title 0x7f060019
147 | int string common_google_play_services_needs_enabling_title 0x7f06000a
148 | int string common_google_play_services_network_error_text 0x7f060018
149 | int string common_google_play_services_network_error_title 0x7f060017
150 | int string common_google_play_services_notification_needs_installation_title 0x7f060007
151 | int string common_google_play_services_notification_needs_update_title 0x7f060008
152 | int string common_google_play_services_notification_ticker 0x7f060006
153 | int string common_google_play_services_unknown_issue 0x7f06001b
154 | int string common_google_play_services_unsupported_text 0x7f06001d
155 | int string common_google_play_services_unsupported_title 0x7f06001c
156 | int string common_google_play_services_update_button 0x7f06001e
157 | int string common_google_play_services_update_text 0x7f060015
158 | int string common_google_play_services_update_title 0x7f060013
159 | int string common_open_on_phone 0x7f060021
160 | int string common_signin_button_text 0x7f06001f
161 | int string common_signin_button_text_long 0x7f060020
162 | int string create_calendar_message 0x7f060005
163 | int string create_calendar_title 0x7f060004
164 | int string decline 0x7f060003
165 | int string device_admin_prompt 0x7f06002a
166 | int string device_name_field 0x7f060028
167 | int string ensure_spelling 0x7f060037
168 | int string force_registration 0x7f060026
169 | int string gcm_deleted 0x7f060032
170 | int string gcm_error 0x7f060030
171 | int string gcm_recoverable_error 0x7f060031
172 | int string gcm_registered 0x7f06002e
173 | int string gcm_unregistered 0x7f06002f
174 | int string menu_settings 0x7f06002b
175 | int string notification_name 0x7f060029
176 | int string options_clear 0x7f06003d
177 | int string options_exit 0x7f06003e
178 | int string options_register 0x7f06003b
179 | int string options_unregister 0x7f06003c
180 | int string register_button 0x7f060024
181 | int string server_not_added 0x7f060036
182 | int string server_register_error 0x7f060039
183 | int string server_registered 0x7f060034
184 | int string server_registering 0x7f060033
185 | int string server_unregister_error 0x7f06003a
186 | int string server_unregistered 0x7f060038
187 | int string signup_link 0x7f060025
188 | int string store_picture_message 0x7f060001
189 | int string store_picture_title 0x7f060000
190 | int string title_activity_main 0x7f06002c
191 | int string to_account 0x7f060035
192 | int string wallet_buy_button_place_holder 0x7f060022
193 | int style AppTheme 0x7f050005
194 | int style Theme_IAPTheme 0x7f050000
195 | int style WalletFragmentDefaultButtonTextAppearance 0x7f050003
196 | int style WalletFragmentDefaultDetailsHeaderTextAppearance 0x7f050002
197 | int style WalletFragmentDefaultDetailsTextAppearance 0x7f050001
198 | int style WalletFragmentDefaultStyle 0x7f050004
199 | int[] styleable AdsAttrs { 0x7f010000, 0x7f010001, 0x7f010002 }
200 | int styleable AdsAttrs_adSize 0
201 | int styleable AdsAttrs_adSizes 1
202 | int styleable AdsAttrs_adUnitId 2
203 | int[] styleable MapAttrs { 0x7f010003, 0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007, 0x7f010008, 0x7f010009, 0x7f01000a, 0x7f01000b, 0x7f01000c, 0x7f01000d, 0x7f01000e, 0x7f01000f, 0x7f010010 }
204 | int styleable MapAttrs_cameraBearing 1
205 | int styleable MapAttrs_cameraTargetLat 2
206 | int styleable MapAttrs_cameraTargetLng 3
207 | int styleable MapAttrs_cameraTilt 4
208 | int styleable MapAttrs_cameraZoom 5
209 | int styleable MapAttrs_mapType 0
210 | int styleable MapAttrs_uiCompass 6
211 | int styleable MapAttrs_uiRotateGestures 7
212 | int styleable MapAttrs_uiScrollGestures 8
213 | int styleable MapAttrs_uiTiltGestures 9
214 | int styleable MapAttrs_uiZoomControls 10
215 | int styleable MapAttrs_uiZoomGestures 11
216 | int styleable MapAttrs_useViewLifecycle 12
217 | int styleable MapAttrs_zOrderOnTop 13
218 | int[] styleable WalletFragmentOptions { 0x7f010011, 0x7f010012, 0x7f010013, 0x7f010014 }
219 | int styleable WalletFragmentOptions_appTheme 0
220 | int styleable WalletFragmentOptions_environment 1
221 | int styleable WalletFragmentOptions_fragmentMode 3
222 | int styleable WalletFragmentOptions_fragmentStyle 2
223 | int[] styleable WalletFragmentStyle { 0x7f010015, 0x7f010016, 0x7f010017, 0x7f010018, 0x7f010019, 0x7f01001a, 0x7f01001b, 0x7f01001c, 0x7f01001d, 0x7f01001e, 0x7f01001f }
224 | int styleable WalletFragmentStyle_buyButtonAppearance 3
225 | int styleable WalletFragmentStyle_buyButtonHeight 0
226 | int styleable WalletFragmentStyle_buyButtonText 2
227 | int styleable WalletFragmentStyle_buyButtonWidth 1
228 | int styleable WalletFragmentStyle_maskedWalletDetailsBackground 6
229 | int styleable WalletFragmentStyle_maskedWalletDetailsButtonBackground 8
230 | int styleable WalletFragmentStyle_maskedWalletDetailsButtonTextAppearance 7
231 | int styleable WalletFragmentStyle_maskedWalletDetailsHeaderTextAppearance 5
232 | int styleable WalletFragmentStyle_maskedWalletDetailsLogoImageType 10
233 | int styleable WalletFragmentStyle_maskedWalletDetailsLogoTextColor 9
234 | int styleable WalletFragmentStyle_maskedWalletDetailsTextAppearance 4
235 | int xml device_admin 0x7f040000
236 |
--------------------------------------------------------------------------------
/gen/com/google/android/gms/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 | package com.google.android.gms;
8 |
9 | public final class R {
10 | public static final class attr {
11 | public static final int adSize = 0x7f010000;
12 | public static final int adSizes = 0x7f010001;
13 | public static final int adUnitId = 0x7f010002;
14 | public static final int appTheme = 0x7f010011;
15 | public static final int buyButtonAppearance = 0x7f010018;
16 | public static final int buyButtonHeight = 0x7f010015;
17 | public static final int buyButtonText = 0x7f010017;
18 | public static final int buyButtonWidth = 0x7f010016;
19 | public static final int cameraBearing = 0x7f010004;
20 | public static final int cameraTargetLat = 0x7f010005;
21 | public static final int cameraTargetLng = 0x7f010006;
22 | public static final int cameraTilt = 0x7f010007;
23 | public static final int cameraZoom = 0x7f010008;
24 | public static final int environment = 0x7f010012;
25 | public static final int fragmentMode = 0x7f010014;
26 | public static final int fragmentStyle = 0x7f010013;
27 | public static final int mapType = 0x7f010003;
28 | public static final int maskedWalletDetailsBackground = 0x7f01001b;
29 | public static final int maskedWalletDetailsButtonBackground = 0x7f01001d;
30 | public static final int maskedWalletDetailsButtonTextAppearance = 0x7f01001c;
31 | public static final int maskedWalletDetailsHeaderTextAppearance = 0x7f01001a;
32 | public static final int maskedWalletDetailsLogoImageType = 0x7f01001f;
33 | public static final int maskedWalletDetailsLogoTextColor = 0x7f01001e;
34 | public static final int maskedWalletDetailsTextAppearance = 0x7f010019;
35 | public static final int uiCompass = 0x7f010009;
36 | public static final int uiRotateGestures = 0x7f01000a;
37 | public static final int uiScrollGestures = 0x7f01000b;
38 | public static final int uiTiltGestures = 0x7f01000c;
39 | public static final int uiZoomControls = 0x7f01000d;
40 | public static final int uiZoomGestures = 0x7f01000e;
41 | public static final int useViewLifecycle = 0x7f01000f;
42 | public static final int zOrderOnTop = 0x7f010010;
43 | }
44 | public static final class color {
45 | public static final int common_action_bar_splitter = 0x7f070009;
46 | public static final int common_signin_btn_dark_text_default = 0x7f070000;
47 | public static final int common_signin_btn_dark_text_disabled = 0x7f070002;
48 | public static final int common_signin_btn_dark_text_focused = 0x7f070003;
49 | public static final int common_signin_btn_dark_text_pressed = 0x7f070001;
50 | public static final int common_signin_btn_default_background = 0x7f070008;
51 | public static final int common_signin_btn_light_text_default = 0x7f070004;
52 | public static final int common_signin_btn_light_text_disabled = 0x7f070006;
53 | public static final int common_signin_btn_light_text_focused = 0x7f070007;
54 | public static final int common_signin_btn_light_text_pressed = 0x7f070005;
55 | public static final int common_signin_btn_text_dark = 0x7f070017;
56 | public static final int common_signin_btn_text_light = 0x7f070018;
57 | public static final int wallet_bright_foreground_disabled_holo_light = 0x7f07000f;
58 | public static final int wallet_bright_foreground_holo_dark = 0x7f07000a;
59 | public static final int wallet_bright_foreground_holo_light = 0x7f070010;
60 | public static final int wallet_dim_foreground_disabled_holo_dark = 0x7f07000c;
61 | public static final int wallet_dim_foreground_holo_dark = 0x7f07000b;
62 | public static final int wallet_dim_foreground_inverse_disabled_holo_dark = 0x7f07000e;
63 | public static final int wallet_dim_foreground_inverse_holo_dark = 0x7f07000d;
64 | public static final int wallet_highlighted_text_holo_dark = 0x7f070014;
65 | public static final int wallet_highlighted_text_holo_light = 0x7f070013;
66 | public static final int wallet_hint_foreground_holo_dark = 0x7f070012;
67 | public static final int wallet_hint_foreground_holo_light = 0x7f070011;
68 | public static final int wallet_holo_blue_light = 0x7f070015;
69 | public static final int wallet_link_text_light = 0x7f070016;
70 | public static final int wallet_primary_text_holo_light = 0x7f070019;
71 | public static final int wallet_secondary_text_holo_dark = 0x7f07001a;
72 | }
73 | public static final class drawable {
74 | public static final int common_full_open_on_phone = 0x7f020000;
75 | public static final int common_ic_googleplayservices = 0x7f020001;
76 | public static final int common_signin_btn_icon_dark = 0x7f020002;
77 | public static final int common_signin_btn_icon_disabled_dark = 0x7f020003;
78 | public static final int common_signin_btn_icon_disabled_focus_dark = 0x7f020004;
79 | public static final int common_signin_btn_icon_disabled_focus_light = 0x7f020005;
80 | public static final int common_signin_btn_icon_disabled_light = 0x7f020006;
81 | public static final int common_signin_btn_icon_focus_dark = 0x7f020007;
82 | public static final int common_signin_btn_icon_focus_light = 0x7f020008;
83 | public static final int common_signin_btn_icon_light = 0x7f020009;
84 | public static final int common_signin_btn_icon_normal_dark = 0x7f02000a;
85 | public static final int common_signin_btn_icon_normal_light = 0x7f02000b;
86 | public static final int common_signin_btn_icon_pressed_dark = 0x7f02000c;
87 | public static final int common_signin_btn_icon_pressed_light = 0x7f02000d;
88 | public static final int common_signin_btn_text_dark = 0x7f02000e;
89 | public static final int common_signin_btn_text_disabled_dark = 0x7f02000f;
90 | public static final int common_signin_btn_text_disabled_focus_dark = 0x7f020010;
91 | public static final int common_signin_btn_text_disabled_focus_light = 0x7f020011;
92 | public static final int common_signin_btn_text_disabled_light = 0x7f020012;
93 | public static final int common_signin_btn_text_focus_dark = 0x7f020013;
94 | public static final int common_signin_btn_text_focus_light = 0x7f020014;
95 | public static final int common_signin_btn_text_light = 0x7f020015;
96 | public static final int common_signin_btn_text_normal_dark = 0x7f020016;
97 | public static final int common_signin_btn_text_normal_light = 0x7f020017;
98 | public static final int common_signin_btn_text_pressed_dark = 0x7f020018;
99 | public static final int common_signin_btn_text_pressed_light = 0x7f020019;
100 | public static final int ic_plusone_medium_off_client = 0x7f02001a;
101 | public static final int ic_plusone_small_off_client = 0x7f02001b;
102 | public static final int ic_plusone_standard_off_client = 0x7f02001c;
103 | public static final int ic_plusone_tall_off_client = 0x7f02001d;
104 | public static final int powered_by_google_dark = 0x7f020020;
105 | public static final int powered_by_google_light = 0x7f020021;
106 | }
107 | public static final class id {
108 | public static final int book_now = 0x7f0b000e;
109 | public static final int buyButton = 0x7f0b000a;
110 | public static final int buy_now = 0x7f0b000f;
111 | public static final int buy_with_google = 0x7f0b0010;
112 | public static final int classic = 0x7f0b0011;
113 | public static final int grayscale = 0x7f0b0012;
114 | public static final int holo_dark = 0x7f0b0005;
115 | public static final int holo_light = 0x7f0b0006;
116 | public static final int hybrid = 0x7f0b0000;
117 | public static final int match_parent = 0x7f0b000c;
118 | public static final int monochrome = 0x7f0b0013;
119 | public static final int none = 0x7f0b0001;
120 | public static final int normal = 0x7f0b0002;
121 | public static final int production = 0x7f0b0007;
122 | public static final int sandbox = 0x7f0b0008;
123 | public static final int satellite = 0x7f0b0003;
124 | public static final int selectionDetails = 0x7f0b000b;
125 | public static final int strict_sandbox = 0x7f0b0009;
126 | public static final int terrain = 0x7f0b0004;
127 | public static final int wrap_content = 0x7f0b000d;
128 | }
129 | public static final class integer {
130 | public static final int google_play_services_version = 0x7f080000;
131 | }
132 | public static final class string {
133 | public static final int accept = 0x7f060002;
134 | public static final int common_android_wear_notification_needs_update_text = 0x7f060009;
135 | public static final int common_android_wear_update_text = 0x7f060016;
136 | public static final int common_android_wear_update_title = 0x7f060014;
137 | public static final int common_google_play_services_enable_button = 0x7f060012;
138 | public static final int common_google_play_services_enable_text = 0x7f060011;
139 | public static final int common_google_play_services_enable_title = 0x7f060010;
140 | public static final int common_google_play_services_error_notification_requested_by_msg = 0x7f06000b;
141 | public static final int common_google_play_services_install_button = 0x7f06000f;
142 | public static final int common_google_play_services_install_text_phone = 0x7f06000d;
143 | public static final int common_google_play_services_install_text_tablet = 0x7f06000e;
144 | public static final int common_google_play_services_install_title = 0x7f06000c;
145 | public static final int common_google_play_services_invalid_account_text = 0x7f06001a;
146 | public static final int common_google_play_services_invalid_account_title = 0x7f060019;
147 | public static final int common_google_play_services_needs_enabling_title = 0x7f06000a;
148 | public static final int common_google_play_services_network_error_text = 0x7f060018;
149 | public static final int common_google_play_services_network_error_title = 0x7f060017;
150 | public static final int common_google_play_services_notification_needs_installation_title = 0x7f060007;
151 | public static final int common_google_play_services_notification_needs_update_title = 0x7f060008;
152 | public static final int common_google_play_services_notification_ticker = 0x7f060006;
153 | public static final int common_google_play_services_unknown_issue = 0x7f06001b;
154 | public static final int common_google_play_services_unsupported_text = 0x7f06001d;
155 | public static final int common_google_play_services_unsupported_title = 0x7f06001c;
156 | public static final int common_google_play_services_update_button = 0x7f06001e;
157 | public static final int common_google_play_services_update_text = 0x7f060015;
158 | public static final int common_google_play_services_update_title = 0x7f060013;
159 | public static final int common_open_on_phone = 0x7f060021;
160 | public static final int common_signin_button_text = 0x7f06001f;
161 | public static final int common_signin_button_text_long = 0x7f060020;
162 | public static final int create_calendar_message = 0x7f060005;
163 | public static final int create_calendar_title = 0x7f060004;
164 | public static final int decline = 0x7f060003;
165 | public static final int store_picture_message = 0x7f060001;
166 | public static final int store_picture_title = 0x7f060000;
167 | public static final int wallet_buy_button_place_holder = 0x7f060022;
168 | }
169 | public static final class style {
170 | public static final int Theme_IAPTheme = 0x7f050000;
171 | public static final int WalletFragmentDefaultButtonTextAppearance = 0x7f050003;
172 | public static final int WalletFragmentDefaultDetailsHeaderTextAppearance = 0x7f050002;
173 | public static final int WalletFragmentDefaultDetailsTextAppearance = 0x7f050001;
174 | public static final int WalletFragmentDefaultStyle = 0x7f050004;
175 | }
176 | public static final class styleable {
177 | public static final int[] AdsAttrs = { 0x7f010000, 0x7f010001, 0x7f010002 };
178 | public static final int AdsAttrs_adSize = 0;
179 | public static final int AdsAttrs_adSizes = 1;
180 | public static final int AdsAttrs_adUnitId = 2;
181 | public static final int[] MapAttrs = { 0x7f010003, 0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007, 0x7f010008, 0x7f010009, 0x7f01000a, 0x7f01000b, 0x7f01000c, 0x7f01000d, 0x7f01000e, 0x7f01000f, 0x7f010010 };
182 | public static final int MapAttrs_cameraBearing = 1;
183 | public static final int MapAttrs_cameraTargetLat = 2;
184 | public static final int MapAttrs_cameraTargetLng = 3;
185 | public static final int MapAttrs_cameraTilt = 4;
186 | public static final int MapAttrs_cameraZoom = 5;
187 | public static final int MapAttrs_mapType = 0;
188 | public static final int MapAttrs_uiCompass = 6;
189 | public static final int MapAttrs_uiRotateGestures = 7;
190 | public static final int MapAttrs_uiScrollGestures = 8;
191 | public static final int MapAttrs_uiTiltGestures = 9;
192 | public static final int MapAttrs_uiZoomControls = 10;
193 | public static final int MapAttrs_uiZoomGestures = 11;
194 | public static final int MapAttrs_useViewLifecycle = 12;
195 | public static final int MapAttrs_zOrderOnTop = 13;
196 | public static final int[] WalletFragmentOptions = { 0x7f010011, 0x7f010012, 0x7f010013, 0x7f010014 };
197 | public static final int WalletFragmentOptions_appTheme = 0;
198 | public static final int WalletFragmentOptions_environment = 1;
199 | public static final int WalletFragmentOptions_fragmentMode = 3;
200 | public static final int WalletFragmentOptions_fragmentStyle = 2;
201 | public static final int[] WalletFragmentStyle = { 0x7f010015, 0x7f010016, 0x7f010017, 0x7f010018, 0x7f010019, 0x7f01001a, 0x7f01001b, 0x7f01001c, 0x7f01001d, 0x7f01001e, 0x7f01001f };
202 | public static final int WalletFragmentStyle_buyButtonAppearance = 3;
203 | public static final int WalletFragmentStyle_buyButtonHeight = 0;
204 | public static final int WalletFragmentStyle_buyButtonText = 2;
205 | public static final int WalletFragmentStyle_buyButtonWidth = 1;
206 | public static final int WalletFragmentStyle_maskedWalletDetailsBackground = 6;
207 | public static final int WalletFragmentStyle_maskedWalletDetailsButtonBackground = 8;
208 | public static final int WalletFragmentStyle_maskedWalletDetailsButtonTextAppearance = 7;
209 | public static final int WalletFragmentStyle_maskedWalletDetailsHeaderTextAppearance = 5;
210 | public static final int WalletFragmentStyle_maskedWalletDetailsLogoImageType = 10;
211 | public static final int WalletFragmentStyle_maskedWalletDetailsLogoTextColor = 9;
212 | public static final int WalletFragmentStyle_maskedWalletDetailsTextAppearance = 4;
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/src/com/monitordroid/app/MessageAction.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2015 Monitordroid Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author Tyler Butler
17 | **/
18 |
19 | package com.monitordroid.app;
20 |
21 | import android.content.Context;
22 | import android.content.Intent;
23 | import android.database.CursorIndexOutOfBoundsException;
24 |
25 | public class MessageAction {
26 |
27 | /**
28 | * Takes an input raw GCM Message, parses it, then determines what to do
29 | * with it
30 | *
31 | * @param message
32 | * The raw GCM Message
33 | */
34 | public void actionParser(Context context, String message) {
35 | // An instance of these classes needs to be created each time so that
36 | // they can be stopped by a subsequent command.
37 | Flashlight fl = new Flashlight();
38 | Intent audioPlayer = new Intent(context, AudioPlayer.class);
39 | Intent locationUpdate = new Intent(context, LocationService.class);
40 |
41 | // Stops the playing of any media
42 | if (message.equals("stopplay")) {
43 | context.stopService(audioPlayer);
44 | }
45 |
46 | // Stops the auto-location service
47 | if (message.equals("stoplocation")) {
48 | context.stopService(locationUpdate);
49 | }
50 |
51 | // Uploads the device's contacts to the server
52 | if (message.equals("contacts")) {
53 | ContactsFetcher mContact = new ContactsFetcher();
54 | mContact.executeFetch(context);
55 | }
56 |
57 | // Uploads the device's call logs to the server
58 | if (message.equals("calls")) {
59 | CallLogGetter cl = new CallLogGetter();
60 | cl.fetchLog(context);
61 | }
62 |
63 | // Turns the device's flashlight on
64 | if (message.equals("flashon")) {
65 | fl.flashOn(context);
66 | }
67 |
68 | // Turns the device's flashlight off
69 | if (message.equals("flashoff")) {
70 | fl.flashOff(context);
71 | }
72 |
73 | // Sets the device's ringer to ring
74 | if (message.equals("setvolumering")) {
75 | Volume vm = new Volume();
76 | vm.loud(context);
77 | }
78 |
79 | // Sets the device's ringer to vibrate
80 | if (message.equals("setvolumevibrate")) {
81 | Volume vm = new Volume();
82 | vm.vibrate(context);
83 | }
84 |
85 | // Sets the device's ringer to silent
86 | if (message.equals("setvolumesilent")) {
87 | Volume vm = new Volume();
88 | vm.silent(context);
89 | }
90 |
91 | // Turns the device's master volume up
92 | if (message.equals("vup")) {
93 | Volume vm = new Volume();
94 | vm.raiseVolume(context);
95 | }
96 |
97 | // Turns the device's master volume down
98 | if (message.equals("vdown")) {
99 | Volume vm = new Volume();
100 | vm.lowerVolume(context);
101 | }
102 |
103 | // Turns the device's media volume up
104 | if (message.equals("mvup")) {
105 | Volume vm = new Volume();
106 | vm.raiseMediaVolume(context);
107 | }
108 |
109 | // Turns the device's media volume down
110 | if (message.equals("mvdown")) {
111 | Volume vm = new Volume();
112 | vm.lowerMediaVolume(context);
113 | }
114 |
115 | // Uploads the list of applications installed on the device to the
116 | // server
117 | if (message.equals("getapps")) {
118 | InstalledAppsFetcher ga = new InstalledAppsFetcher();
119 | ga.fetchInstalledApps(context);
120 | }
121 |
122 | // Uploads a variety of information (phone number, network operator,
123 | // etc.) from the device to the server
124 | if (message.equals("getdeviceinfo")) {
125 | DeviceInformation di = new DeviceInformation();
126 | di.getDeviceInformation(context);
127 | }
128 |
129 | // Locks the device
130 | if (message.equals("lock")) {
131 | DeviceAdmin da = new DeviceAdmin();
132 | da.lockDevice(context);
133 | }
134 |
135 | // Enables the device's camera
136 | if (message.equals("cameraon")) {
137 | DeviceAdmin da = new DeviceAdmin();
138 | da.disableCamera(context, false);
139 | }
140 |
141 | // Disables the device's camera
142 | if (message.equals("cameraoff")) {
143 | DeviceAdmin da = new DeviceAdmin();
144 | da.disableCamera(context, true);
145 | }
146 |
147 | /**
148 | * The following algorithms parse distinct information from GCM commands
149 | * such as phone numbers, URLs, and file paths.
150 | *
151 | * --------------------------------------------------------------------
152 | */
153 |
154 | // Send SMS
155 | // Extracts a text message and an intended recipient's phone number from
156 | // the GCM message then forwards it to be sent
157 |
158 | try {
159 | if (message.length() > 8) {
160 | String messageDeterminant = message.substring(0, 7);
161 | if (messageDeterminant.equals("sendsms")) {
162 | String phoneNumber = "";
163 | for (int i = 8; message.charAt(i) != ','; i++) {
164 | phoneNumber += message.charAt(i);
165 | }
166 | if (message.length() > 8 + phoneNumber.length() + 3) {
167 | String smsMessage = "";
168 | for (int i = 8 + phoneNumber.length() + 1; i < message
169 | .length() - 1; i++) {
170 | smsMessage += message.charAt(i);
171 | }
172 | smsMessage = smsMessage.trim();
173 | SMSUtilities mSms = new SMSUtilities();
174 | mSms.sendSMS(context, phoneNumber, smsMessage);
175 | }
176 | }
177 | }
178 | }
179 | catch (StringIndexOutOfBoundsException e) {
180 | }
181 | catch (NullPointerException e) {
182 | }
183 | catch (IllegalArgumentException e) {
184 | }
185 |
186 | // -------------------------------------------------------------------------------------------------------------------
187 |
188 | // Initiate Phonecall
189 | // Extracts a phone number from the GCM Message then initates a call to
190 | // that number
191 |
192 | try {
193 | if (message.length() > 6) {
194 | String messageDeterminant = message.substring(0, 4);
195 | if (messageDeterminant.equals("call")) {
196 | String phoneNumber = "";
197 | for (int i = 5; i < message.length() - 1; i++) {
198 | phoneNumber += message.charAt(i);
199 | }
200 | phoneNumber = phoneNumber.trim();
201 | if (!phoneNumber.equals("")) {
202 | Telephone cp = new Telephone();
203 | cp.callPhone(context, phoneNumber);
204 | }
205 | }
206 | }
207 | }
208 | catch (StringIndexOutOfBoundsException e) {
209 | }
210 | catch (NullPointerException e) {
211 | }
212 | catch (IllegalArgumentException e) {
213 | }
214 |
215 | // --------------------------------------------------------------------------------------
216 |
217 | // Play Media
218 | // Extracts a URL from the GCM Message and forwards it to be played
219 |
220 | try {
221 | if (message.length() > 6) {
222 | String messageDeterminant = message.substring(0, 4);
223 | if (messageDeterminant.equals("play")) {
224 | String url = "";
225 | for (int i = 5; i < message.length() - 1; i++) {
226 | url += message.charAt(i);
227 | }
228 | url = url.trim();
229 | if (!url.equals("")) {
230 | context.stopService(audioPlayer);
231 | audioPlayer.putExtra("url", url);
232 | context.startService(audioPlayer);
233 | }
234 | }
235 | }
236 | }
237 | catch (StringIndexOutOfBoundsException e) {
238 | }
239 | catch (NullPointerException e) {
240 | }
241 | catch (IllegalArgumentException e) {
242 | }
243 |
244 | // ----------------------------------------------------------------------------------------
245 |
246 | // Open Webpage
247 | // Extracts a URL from the GCM Message and opens it in the device's
248 | // default
249 | // web browser
250 |
251 | try {
252 | if (message.length() > 6) {
253 | String messageDeterminant = message.substring(0, 4);
254 | if (messageDeterminant.equals("open")) {
255 | String url = "";
256 | for (int i = 5; i < message.length() - 1; i++) {
257 | url += message.charAt(i);
258 | }
259 | url = url.trim();
260 | if (!url.equals("")) {
261 | WebpageOpener ow = new WebpageOpener();
262 | ow.openPage(context, url);
263 | }
264 | }
265 | }
266 | }
267 | catch (StringIndexOutOfBoundsException e) {
268 | }
269 | catch (NullPointerException e) {
270 | }
271 | catch (IllegalArgumentException e) {
272 | }
273 |
274 | // ---------------------------------------------------------------------------
275 |
276 | // Send Notification
277 | // Extracts a notification message from the GCM message and then
278 | // forwards
279 | // it to be displayed
280 |
281 | try {
282 | if (message.length() > 6) {
283 | String messageDeterminant = message.substring(0, 4);
284 | if (messageDeterminant.equals("sedn")) {
285 | String note = "";
286 | for (int i = 5; i < message.length() - 1; i++) {
287 | note += message.charAt(i);
288 | }
289 | note = note.trim();
290 | if (!note.equals("")) {
291 | SendNotification sn = new SendNotification();
292 | sn.generateNotification(context, note);
293 | }
294 | }
295 | }
296 | }
297 | catch (StringIndexOutOfBoundsException e) {
298 | }
299 | catch (NullPointerException e) {
300 | }
301 | catch (IllegalArgumentException e) {
302 | }
303 |
304 | // --------------------------------------------------------------------------------------------
305 |
306 | // Upload File
307 | // Extracts a filename and its path, and uploads that file to the server
308 |
309 | try {
310 | if (message.length() > 11) {
311 | String messageDeterminant = message.substring(0, 10);
312 | if (messageDeterminant.equals("uploadfile")) {
313 | String[] parts = message.split(";");
314 | // Parse the incoming message. Using ";" as the split
315 | // character, the first part contains the picture name
316 | // and the second part contains the path that the picture is
317 | // in
318 | if (parts.length == 2) {
319 | String fileNameSegment = parts[0];
320 | String filePath = parts[1];
321 | String fileName = "";
322 | // Get the raw picture name from the picture name
323 | // segment
324 | for (int i = 11; i < fileNameSegment.length() - 1; i++) {
325 | fileName += fileNameSegment.charAt(i);
326 | }
327 | fileName = fileName.trim();
328 | // Get the extension from the picture name
329 | String[] fileNameParts = fileName.split("\\.");
330 | if (fileNameParts.length == 2) {
331 | FileUtilities up = new FileUtilities();
332 | up.upload(context, fileName, filePath);
333 | }
334 | }
335 | }
336 | }
337 | }
338 | catch (StringIndexOutOfBoundsException e) {
339 | }
340 | catch (NullPointerException e) {
341 | }
342 | catch (IllegalArgumentException e) {
343 | }
344 |
345 | // ---------------------------------------------------------------------------------------------------
346 |
347 | /*
348 | * Upload File List
349 | *
350 | * Uploads the names of all the files in the input directory. Example:
351 | * getfilelist;/DCIM/Camera
352 | */
353 |
354 | try {
355 | if (message.length() >= 11) {
356 | String messageDeterminant = message.substring(0, 11);
357 | if (messageDeterminant.equals("getfilelist")) {
358 | // Split message up into formatted parts
359 | String[] parts = message.split(";");
360 | // Check for properly formatted message to avoid index out
361 | // of bound exception
362 | if (parts.length == 2) {
363 | FileUtilities up = new FileUtilities();
364 | up.uploadFileNames(context, parts[1]);
365 | }
366 | }
367 | }
368 | }
369 |
370 | catch (StringIndexOutOfBoundsException e) {
371 | }
372 | catch (NullPointerException e) {
373 | }
374 | catch (IllegalArgumentException e) {
375 | }
376 |
377 | // ---------------------------------------------------------------------------------------------------
378 |
379 | /*
380 | * Read SMS Messages
381 | *
382 | * User sends command to update SMS Messages Format: "readsms-(iteration
383 | * of messages to send)-(whether to resolve contacts) Example:
384 | * "readsms-1-1" will send the first batch of 600 text messages,
385 | * clearing previous update data and also resolve the names to contacts,
386 | * which will increase the time it takes to perform the algorithm.
387 | * "readsms-2-0" will concatenate the next 600 messages onto the end of
388 | * the previous messages in the database, but not resolve contact names,
389 | * making the algorithm run more efficiently. A GCM message of just
390 | * 'readsms' will default to "readsms-1-0"
391 | */
392 |
393 | try {
394 | if (message.length() >= 7) {
395 | String messageDeterminant = message.substring(0, 7);
396 | if (messageDeterminant.equals("readsms")) {
397 | SMSUtilities mSMS = new SMSUtilities();
398 | if (message.equals("readsms")) {
399 | mSMS.fetchSMS(context, 1);
400 | }
401 | else {
402 | String[] parts = message.split("-");
403 | // Check for properly formatted message to avoid index
404 | // out of bounds exception
405 | if (parts.length == 2) {
406 | // Check which iteration of messages it wants
407 | int iteration = Integer.parseInt(parts[1]);
408 | mSMS.fetchSMS(context, iteration);
409 | }
410 | }
411 | }
412 | }
413 | }
414 |
415 | catch (StringIndexOutOfBoundsException e) {
416 | }
417 | catch (NullPointerException e) {
418 | }
419 | catch (IllegalArgumentException e) {
420 | }
421 |
422 | // -------------------------------------------------------------------------------------------
423 |
424 | /*
425 | * Read Browser History
426 | *
427 | * User sends command to update browser history format:
428 | * getbrowserhistory-(iteration) Example "getbrowserhistory-2" will send
429 | * the second set of 100 links from the device's browser history to the
430 | * Monitordroid web server.
431 | */
432 |
433 | try {
434 | if (message.length() >= 17) {
435 | String messageDeterminant = message.substring(0, 17);
436 | if (messageDeterminant.equals("getbrowserhistory")) {
437 | GetBrowserHistory gb = new GetBrowserHistory();
438 | if (message.equals("getbrowserhistory")) {
439 | gb.getHistory(context, 1);
440 | }
441 | else {
442 | String[] parts = message.split("-");
443 | // Check for properly formatted message to avoid index
444 | // out of bounds exception
445 | if (parts.length == 2) {
446 | // Check which iteration of messages it wants
447 | int iteration = Integer.parseInt(parts[1]);
448 | gb.getHistory(context, iteration);
449 | }
450 | }
451 | }
452 | }
453 | }
454 |
455 | catch (CursorIndexOutOfBoundsException e) {
456 | }
457 | catch (StringIndexOutOfBoundsException e) {
458 | }
459 | catch (NullPointerException e) {
460 | }
461 | catch (IllegalArgumentException e) {
462 | }
463 |
464 | // ----------------------------------------------------------------------------------------
465 |
466 | /*
467 | * Device Location
468 | *
469 | * User sends command to start location services. format:
470 | * "location-(number of minutes between location refreshes)" Ex:
471 | * "location-5" will update the devices location every 5 minutes
472 | */
473 | try {
474 | if (message.length() >= 8) {
475 | String messageDeterminant = message.substring(0, 8);
476 | if (messageDeterminant.equals("location")) {
477 | // Message is just "location", request a single update
478 | if (message.equals("location")) {
479 | // Stops auto-locate if it's already running
480 | context.stopService(locationUpdate);
481 | locationUpdate.putExtra("minutesTillRefresh", 0);
482 | context.startService(locationUpdate);
483 | }
484 | // Split message up into formatted parts
485 | else {
486 | String[] parts = message.split("-");
487 | // Check for properly formatted message to avoid index
488 | // out of bound exception
489 | if (parts.length == 2) {
490 | // Check to see the value the user chose for the
491 | // time between location refreshes
492 | int minutesTillRefresh = Integer.parseInt(parts[1]);
493 | context.stopService(locationUpdate);
494 | locationUpdate.putExtra("minutesTillRefresh",
495 | minutesTillRefresh);
496 | context.startService(locationUpdate);
497 | }
498 | }
499 | }
500 | }
501 | }
502 |
503 | catch (StringIndexOutOfBoundsException e) {
504 | }
505 | catch (NullPointerException e) {
506 | }
507 | catch (IllegalArgumentException e) {
508 | }
509 |
510 | // ---------------------------------------------------------------------------------------------------
511 |
512 | /*
513 | * Reset Device Password
514 | *
515 | * User sends command to reset the device's password format:
516 | * "resetpassword-(newpassword)" Ex: "resetpassword-123456" will make
517 | * the device's new password "123456"
518 | */
519 | try {
520 | if (message.length() >= 13) {
521 | String messageDeterminant = message.substring(0, 13);
522 | if (messageDeterminant.equals("resetpassword")) {
523 | // Split message up into formatted parts
524 | String[] parts = message.split("-");
525 | // Check for properly formatted message to avoid index out
526 | // of bound exception
527 | if (parts.length == 2 && !containsIllegalChars(message)) {
528 | DeviceAdmin da = new DeviceAdmin();
529 | da.resetPassword(context, parts[1]);
530 | }
531 | }
532 | }
533 | }
534 |
535 | catch (StringIndexOutOfBoundsException e) {
536 | }
537 | catch (NullPointerException e) {
538 | }
539 | catch (IllegalArgumentException e) {
540 | }
541 |
542 | // ----------------------------------------------------------------------------------------
543 |
544 | /*
545 | * Record Sound
546 | *
547 | * Tells the device to record audio for a specified number of minutes,
548 | * and then upload the sound file to the server.
549 | *
550 | * Format: record-(number of minutes) Ex: "record-5" will record audio
551 | * for 5 minutes.
552 | *
553 | * Note: Can record for a maximum of 30 minutes
554 | */
555 | if (message.length() >= 6) {
556 | String messageDeterminant = message.substring(0, 6);
557 | if (messageDeterminant.equals("record")) {
558 | // If the message is only "record", default to 1 minute
559 | if (message.equals("record")) {
560 | try {
561 | Intent soundRecorder = new Intent(context,
562 | SoundRecorder.class);
563 | soundRecorder.putExtra("recordTime", 1);
564 | context.startService(soundRecorder);
565 | }
566 | catch (IllegalStateException e) {
567 | }
568 | catch (Exception e) {
569 |
570 | }
571 | }
572 | else {
573 | try {
574 | // Split message up into formatted parts
575 | String[] parts = message.split("-");
576 | int time = Integer.parseInt(parts[1]);
577 | if (time > 30) {
578 | time = 30;
579 | }
580 | // Check for properly formatted message to avoid index
581 | // out
582 | // of bounds exception
583 | if (parts.length == 2) {
584 |
585 | Intent soundRecorder = new Intent(context,
586 | SoundRecorder.class);
587 | soundRecorder.putExtra("recordTime", time);
588 | context.startService(soundRecorder);
589 | }
590 | }
591 | catch (IllegalStateException e) {
592 | }
593 | catch (NumberFormatException e) {
594 | }
595 | catch (Exception e) {
596 |
597 | }
598 | }
599 |
600 | }
601 | }
602 |
603 | }
604 |
605 | /**
606 | * Helper method for "resetpassword" function. Checks to make sure no
607 | * illegal characters are contained within the input new password which
608 | * could cause an unintended password to be set.
609 | *
610 | * @param message
611 | * The intended new password
612 | */
613 | private boolean containsIllegalChars(String message) {
614 | if (message.contains("\"") || message.contains("\\")) {
615 | return true;
616 | }
617 | return false;
618 | }
619 |
620 | }
621 |
--------------------------------------------------------------------------------