Repository: YiuChoi/FakeGps Branch: master Commit: 7041d356204c Files: 46 Total size: 73.1 KB Directory structure: gitextract_kc7cb7wz/ ├── .gitignore ├── .idea/ │ ├── .name │ ├── compiler.xml │ ├── copyright/ │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── libs/ │ │ ├── AMap_2DMap_V2.8.1_20160202.jar │ │ └── AMap_Search_V3.2.1_20160308.jar │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ └── xposed_init │ ├── java/ │ │ └── name/ │ │ └── caiyao/ │ │ └── fakegps/ │ │ ├── data/ │ │ │ ├── AppInfo.java │ │ │ ├── AppInfoProvider.java │ │ │ └── DbHelper.java │ │ ├── hook/ │ │ │ ├── HookUtils.java │ │ │ └── MainHook.java │ │ └── ui/ │ │ ├── AMapActivity.java │ │ └── MainActivity.java │ └── res/ │ ├── layout/ │ │ ├── activity_amap.xml │ │ ├── activity_main.xml │ │ ├── app_item.xml │ │ ├── content_main.xml │ │ ├── dialog_lac_cid.xml │ │ └── dialog_search.xml │ ├── menu/ │ │ ├── menu_main.xml │ │ └── menu_map.xml │ ├── values/ │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── values-en/ │ │ └── strings.xml │ ├── values-v21/ │ │ └── styles.xml │ └── values-w820dp/ │ └── dimens.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures ================================================ FILE: .idea/.name ================================================ FakeGps ================================================ FILE: .idea/compiler.xml ================================================ ================================================ FILE: .idea/copyright/profiles_settings.xml ================================================ ================================================ FILE: .idea/encodings.xml ================================================ ================================================ FILE: .idea/gradle.xml ================================================ ================================================ FILE: .idea/misc.xml ================================================ ================================================ FILE: .idea/modules.xml ================================================ ================================================ FILE: .idea/runConfigurations.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion '24.0.2' defaultConfig { applicationId "name.caiyao.fakegps" minSdkVersion 9 targetSdkVersion 22 versionCode 6 versionName "1.2.2" } buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { provided 'de.robv.android.xposed:api:81' compile files('libs/AMap_2DMap_V2.8.1_20160202.jar') compile 'com.android.support:appcompat-v7:24.2.1' compile 'com.android.support:design:24.2.1' compile files('libs/AMap_Search_V3.2.1_20160308.jar') } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in D:\Android\sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} -keep public class name.caiyao.fakegps.hook.MainHook -keep class com.amap.api.maps2d.**{*;} -dontwarn com.amap.api.** -keep class com.amap.api.mapcore2d.**{*;} ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/assets/xposed_init ================================================ name.caiyao.fakegps.hook.MainHook ================================================ FILE: app/src/main/java/name/caiyao/fakegps/data/AppInfo.java ================================================ package name.caiyao.fakegps.data; import android.graphics.drawable.Drawable; /** * Created by 蔡小木 on 2016/5/3 0003. */ public class AppInfo { public String appName = ""; public String packageName = ""; public String versionName = ""; public int versionCode = 0; public boolean isChecked = false; public Drawable appIcon = null; public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } public String getVersionName() { return versionName; } public void setVersionName(String versionName) { this.versionName = versionName; } public int getVersionCode() { return versionCode; } public void setVersionCode(int versionCode) { this.versionCode = versionCode; } public Drawable getAppIcon() { return appIcon; } public void setAppIcon(Drawable appIcon) { this.appIcon = appIcon; } public boolean isChecked() { return isChecked; } public void setChecked(boolean checked) { isChecked = checked; } } ================================================ FILE: app/src/main/java/name/caiyao/fakegps/data/AppInfoProvider.java ================================================ package name.caiyao.fakegps.data; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; /** * Created by 蔡小木 on 2016/5/4 0004. */ public class AppInfoProvider extends ContentProvider { public static final String AUTHRITY = "name.caiyao.fakegps.data.AppInfoProvider"; public static final Uri APP_CONTENT_URI = Uri.parse("content://" + AUTHRITY + "/app"); public static final int APP_URI_CODE = 0; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sUriMatcher.addURI(AUTHRITY, "app", APP_URI_CODE); } private SQLiteDatabase mSQLiteDatabase; @Override public boolean onCreate() { mSQLiteDatabase = new DbHelper(getContext()).getWritableDatabase(); return true; } @Nullable @Override public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { String table = getTableName(uri); if (table == null) throw new IllegalArgumentException("Unsupported URI:" + uri); return mSQLiteDatabase.query(table, projection, selection, selectionArgs, null, null, sortOrder, null); } @Nullable @Override public String getType(@NonNull Uri uri) { return null; } @Nullable @Override public Uri insert(@NonNull Uri uri, ContentValues values) { String table = getTableName(uri); if (table == null) throw new IllegalArgumentException("Unsupported URI:" + uri); mSQLiteDatabase.insert(table, null, values); getContext().getContentResolver().notifyChange(uri, null); return uri; } @Override public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) { String table = getTableName(uri); if (table == null) throw new IllegalArgumentException("Unsupported URI:" + uri); int count = mSQLiteDatabase.delete(table, selection, selectionArgs); if (count > 0) { getContext().getContentResolver().notifyChange(uri, null); } return count; } @Override public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) { String table = getTableName(uri); if (table == null) throw new IllegalArgumentException("Unsupported URI:" + uri); int row = mSQLiteDatabase.update(table,values,selection,selectionArgs); if (row>0){ getContext().getContentResolver().notifyChange(uri, null); } return row; } private String getTableName(Uri uri) { String tableName = null; switch (sUriMatcher.match(uri)) { case APP_URI_CODE: tableName = DbHelper.APP_TABLE_NAME; break; } return tableName; } } ================================================ FILE: app/src/main/java/name/caiyao/fakegps/data/DbHelper.java ================================================ package name.caiyao.fakegps.data; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by 蔡小木 on 2016/5/4 0004. */ public class DbHelper extends SQLiteOpenHelper { private final static String DB_NAME = "applist.db"; public final static String APP_TABLE_NAME = "app"; private final static int DB_VERSION = 1; public DbHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String CREATE_APP_TABLE = "CREATE TABLE IF NOT EXISTS " + APP_TABLE_NAME + "(package_name TEXT PRIMARY KEY," + "latitude DOUBLE,longitude DOUBLE,lac Integer,cid Integer)"; db.execSQL(CREATE_APP_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } ================================================ FILE: app/src/main/java/name/caiyao/fakegps/hook/HookUtils.java ================================================ package name.caiyao.fakegps.hook; import android.location.Criteria; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Build; import android.os.SystemClock; import android.telephony.CellIdentityCdma; import android.telephony.CellIdentityGsm; import android.telephony.CellIdentityLte; import android.telephony.CellIdentityWcdma; import android.telephony.CellInfoCdma; import android.telephony.CellInfoGsm; import android.telephony.CellInfoLte; import android.telephony.CellInfoWcdma; import android.telephony.CellLocation; import android.telephony.gsm.GsmCellLocation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; /** * Created by 蔡小木 on 2016/5/4 0004. */ class HookUtils { static void HookAndChange(ClassLoader classLoader, final double latitude, final double longtitude, final int lac, final int cid) { // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getNetworkOperatorName", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(""); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getNetworkOperator", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(""); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getSimOperatorName", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(""); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getSimOperator", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(null); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getSimCountryIso", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(""); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getNetworkCountryIso", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(""); // } // }); // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getNetworkType", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(TelephonyManager.NETWORK_TYPE_UNKNOWN); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getPhoneType", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(TelephonyManager.PHONE_TYPE_NONE); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getCurrentPhoneType", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(0); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getDataState", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(TelephonyManager.DATA_DISCONNECTED); // } // }); // // XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, // "getSimState", new XC_MethodHook() { // @Override // protected void afterHookedMethod(MethodHookParam param) throws Throwable { // param.setResult(TelephonyManager.SIM_STATE_UNKNOWN); // } // }); XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, "getCellLocation", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { GsmCellLocation gsmCellLocation = new GsmCellLocation(); gsmCellLocation.setLacAndCid(lac, cid); param.setResult(gsmCellLocation); } }); XposedHelpers.findAndHookMethod("android.telephony.PhoneStateListener", classLoader, "onCellLocationChanged", CellLocation.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { GsmCellLocation gsmCellLocation = new GsmCellLocation(); gsmCellLocation.setLacAndCid(lac, cid); param.setResult(gsmCellLocation); } }); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, "getPhoneCount", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(1); } }); } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, "getNeighboringCellInfo", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(new ArrayList<>()); } }); } if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) { XposedHelpers.findAndHookMethod("android.telephony.TelephonyManager", classLoader, "getAllCellInfo", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(getCell(460, 0, lac, cid, 0, 0)); } }); XposedHelpers.findAndHookMethod("android.telephony.PhoneStateListener", classLoader, "onCellInfoChanged", List.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { param.setResult(getCell(460, 0, lac, cid, 0,0)); } }); } XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "getScanResults", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(new ArrayList<>()); } }); XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "getWifiState", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(1); } }); XposedHelpers.findAndHookMethod("android.net.wifi.WifiManager", classLoader, "isWifiEnabled", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(true); } }); XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getMacAddress", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult("00-00-00-00-00-00-00-00"); } }); XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getSSID", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult("null"); } }); XposedHelpers.findAndHookMethod("android.net.wifi.WifiInfo", classLoader, "getBSSID", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult("00-00-00-00-00-00-00-00"); } }); XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader, "getTypeName", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult("WIFI"); } }); XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader, "isConnectedOrConnecting", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(true); } }); XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader, "isConnected", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(true); } }); XposedHelpers.findAndHookMethod("android.net.NetworkInfo", classLoader, "isAvailable", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(true); } }); XposedHelpers.findAndHookMethod("android.telephony.CellInfo", classLoader, "isRegistered", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(true); } }); XposedHelpers.findAndHookMethod(LocationManager.class, "getLastLocation", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Location l = new Location(LocationManager.GPS_PROVIDER); l.setLatitude(latitude); l.setLongitude(longtitude); l.setAccuracy(100f); l.setTime(System.currentTimeMillis()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); } param.setResult(l); } }); XposedHelpers.findAndHookMethod(LocationManager.class, "getLastKnownLocation", String.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Location l = new Location(LocationManager.GPS_PROVIDER); l.setLatitude(latitude); l.setLongitude(longtitude); l.setAccuracy(100f); l.setTime(System.currentTimeMillis()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); } param.setResult(l); } }); XposedBridge.hookAllMethods(LocationManager.class, "getProviders", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { ArrayList arrayList = new ArrayList<>(); arrayList.add("gps"); param.setResult(arrayList); } }); XposedHelpers.findAndHookMethod(LocationManager.class, "getBestProvider", Criteria.class, Boolean.TYPE, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult("gps"); } }); XposedHelpers.findAndHookMethod(LocationManager.class, "addGpsStatusListener", GpsStatus.Listener.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { if (param.args[0] != null) { XposedHelpers.callMethod(param.args[0], "onGpsStatusChanged", 1); XposedHelpers.callMethod(param.args[0], "onGpsStatusChanged", 3); } } }); XposedHelpers.findAndHookMethod(LocationManager.class, "addNmeaListener", GpsStatus.NmeaListener.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { param.setResult(false); } }); XposedHelpers.findAndHookMethod("android.location.LocationManager", classLoader, "getGpsStatus", GpsStatus.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { GpsStatus gss = (GpsStatus) param.getResult(); if (gss == null) return; Class clazz = GpsStatus.class; Method m = null; for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals("setStatus")) { if (method.getParameterTypes().length > 1) { m = method; break; } } } if (m == null) return; //access the private setStatus function of GpsStatus m.setAccessible(true); //make the apps belive GPS works fine now int svCount = 5; int[] prns = {1, 2, 3, 4, 5}; float[] snrs = {0, 0, 0, 0, 0}; float[] elevations = {0, 0, 0, 0, 0}; float[] azimuths = {0, 0, 0, 0, 0}; int ephemerisMask = 0x1f; int almanacMask = 0x1f; //5 satellites are fixed int usedInFixMask = 0x1f; XposedHelpers.callMethod(gss, "setStatus", svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask); param.args[0] = gss; param.setResult(gss); try { m.invoke(gss, svCount, prns, snrs, elevations, azimuths, ephemerisMask, almanacMask, usedInFixMask); param.setResult(gss); } catch (Exception e) { XposedBridge.log(e); } } }); for (Method method : LocationManager.class.getDeclaredMethods()) { if (method.getName().equals("requestLocationUpdates") && !Modifier.isAbstract(method.getModifiers()) && Modifier.isPublic(method.getModifiers())) { XposedBridge.hookMethod(method, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { if (param.args.length >= 4 && (param.args[3] instanceof LocationListener)) { LocationListener ll = (LocationListener) param.args[3]; Class clazz = LocationListener.class; Method m = null; for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals("onLocationChanged") && !Modifier.isAbstract(method.getModifiers())) { m = method; break; } } Location l = new Location(LocationManager.GPS_PROVIDER); l.setLatitude(latitude); l.setLongitude(longtitude); l.setAccuracy(10.00f); l.setTime(System.currentTimeMillis()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); } XposedHelpers.callMethod(ll, "onLocationChanged", l); try { if (m != null) { m.invoke(ll, l); } } catch (Exception e) { XposedBridge.log(e); } } } }); } if (method.getName().equals("requestSingleUpdate ") && !Modifier.isAbstract(method.getModifiers()) && Modifier.isPublic(method.getModifiers())) { XposedBridge.hookMethod(method, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { if (param.args.length >= 3 && (param.args[1] instanceof LocationListener)) { LocationListener ll = (LocationListener) param.args[3]; Class clazz = LocationListener.class; Method m = null; for (Method method : clazz.getDeclaredMethods()) { if (method.getName().equals("onLocationChanged") && !Modifier.isAbstract(method.getModifiers())) { m = method; break; } } try { if (m != null) { Location l = new Location(LocationManager.GPS_PROVIDER); l.setLatitude(latitude); l.setLongitude(longtitude); l.setAccuracy(100f); l.setTime(System.currentTimeMillis()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); } m.invoke(ll, l); } } catch (Exception e) { XposedBridge.log(e); } } } }); } } } private static ArrayList getCell(int mcc, int mnc, int lac, int cid, int sid, int networkType) { ArrayList arrayList = new ArrayList(); CellInfoGsm cellInfoGsm = (CellInfoGsm) XposedHelpers.newInstance(CellInfoGsm.class); XposedHelpers.callMethod(cellInfoGsm, "setCellIdentity", XposedHelpers.newInstance(CellIdentityGsm.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf( lac), Integer.valueOf(cid)})); CellInfoCdma cellInfoCdma = (CellInfoCdma) XposedHelpers.newInstance(CellInfoCdma.class); XposedHelpers.callMethod(cellInfoCdma, "setCellIdentity", XposedHelpers.newInstance(CellIdentityCdma.class, new Object[]{Integer.valueOf(lac), Integer.valueOf(sid), Integer.valueOf(cid), Integer.valueOf(0), Integer.valueOf(0)})); CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) XposedHelpers.newInstance(CellInfoWcdma.class); XposedHelpers.callMethod(cellInfoWcdma, "setCellIdentity", XposedHelpers.newInstance(CellIdentityWcdma.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(lac), Integer.valueOf(cid), Integer.valueOf(300)})); CellInfoLte cellInfoLte = (CellInfoLte) XposedHelpers.newInstance(CellInfoLte.class); XposedHelpers.callMethod(cellInfoLte, "setCellIdentity", XposedHelpers.newInstance(CellIdentityLte.class, new Object[]{Integer.valueOf(mcc), Integer.valueOf(mnc), Integer.valueOf(cid), Integer.valueOf(300), Integer.valueOf(lac)})); if (networkType == 1 || networkType == 2) { arrayList.add(cellInfoGsm); } else if (networkType == 13) { arrayList.add(cellInfoLte); } else if (networkType == 4 || networkType == 5 || networkType == 6 || networkType == 7 || networkType == 12 || networkType == 14) { arrayList.add(cellInfoCdma); } else if (networkType == 3 || networkType == 8 || networkType == 9 || networkType == 10 || networkType == 15) { arrayList.add(cellInfoWcdma); } return arrayList; } } ================================================ FILE: app/src/main/java/name/caiyao/fakegps/hook/MainHook.java ================================================ package name.caiyao.fakegps.hook; import android.content.Context; import android.database.Cursor; import android.net.Uri; import java.util.Random; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; /** * Created by 蔡小木 on 2016/4/17 0017. */ public class MainHook implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { final Object activityThread = XposedHelpers.callStaticMethod(XposedHelpers.findClass("android.app.ActivityThread", null), "currentActivityThread"); final Context systemContext = (Context) XposedHelpers.callMethod(activityThread, "getSystemContext"); Uri uri = Uri.parse("content://name.caiyao.fakegps.data.AppInfoProvider/app"); Cursor cursor = systemContext.getContentResolver().query(uri, new String[]{"latitude", "longitude","lac","cid"}, "package_name=?", new String[]{loadPackageParam.packageName}, null); if (cursor != null && cursor.moveToNext()) { //41019, 18511 double latitude = cursor.getDouble(cursor.getColumnIndex("latitude")) + (double) new Random().nextInt(100) / 1000000 + ((double) new Random().nextInt(99999999)) / 100000000000000d; double longitude = cursor.getDouble(cursor.getColumnIndex("longitude")) + (double) new Random().nextInt(100) / 1000000 + ((double) new Random().nextInt(99999999)) / 100000000000000d; int lac = cursor.getInt(cursor.getColumnIndex("lac")); int cid = cursor.getInt(cursor.getColumnIndex("cid")); XposedBridge.log("模拟位置:" + loadPackageParam.packageName + "," + latitude + "," + longitude + "," + lac + "," + cid); HookUtils.HookAndChange(loadPackageParam.classLoader, latitude, longitude, lac, cid); cursor.close(); } } } ================================================ FILE: app/src/main/java/name/caiyao/fakegps/ui/AMapActivity.java ================================================ package name.caiyao.fakegps.ui; import android.content.ContentValues; import android.content.DialogInterface; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.support.design.widget.TextInputEditText; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; import android.widget.Toast; import com.amap.api.maps2d.AMap; import com.amap.api.maps2d.CameraUpdateFactory; import com.amap.api.maps2d.MapView; import com.amap.api.maps2d.model.LatLng; import com.amap.api.maps2d.model.MarkerOptions; import com.amap.api.services.core.PoiItem; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import java.lang.reflect.Field; import java.util.ArrayList; import name.caiyao.fakegps.R; import name.caiyao.fakegps.data.DbHelper; public class AMapActivity extends AppCompatActivity implements AMap.OnMapClickListener { private MapView mv; private AMap aMap; private LatLng latLng; private String pacakgeName; private int lac = 0, cid = 0; private SQLiteDatabase mSQLiteDatabase; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_amap); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); pacakgeName = getIntent().getStringExtra("package_name"); mv = (MapView) findViewById(R.id.mv); assert mv != null; mv.onCreate(savedInstanceState); aMap = mv.getMap(); mSQLiteDatabase = new DbHelper(this).getWritableDatabase(); Cursor cursor = mSQLiteDatabase.query(DbHelper.APP_TABLE_NAME, new String[]{"latitude,longitude"}, "package_name=?", new String[]{pacakgeName}, null, null, null); if (cursor != null && cursor.moveToNext()) { double lat = cursor.getDouble(cursor.getColumnIndex("latitude")); double lon = cursor.getDouble(cursor.getColumnIndex("longitude")); LatLng latLng1 = new LatLng(lat, lon); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng1); markerOptions.draggable(true); markerOptions.title("经度:" + latLng1.longitude + ",纬度:" + latLng1.latitude); aMap.addMarker(markerOptions); aMap.moveCamera(CameraUpdateFactory.changeLatLng(latLng1)); aMap.moveCamera(CameraUpdateFactory.zoomTo(aMap.getMaxZoomLevel())); cursor.close(); } aMap.setMapType(AMap.MAP_TYPE_NORMAL); aMap.setOnMapClickListener(this); } @Override protected void onResume() { super.onResume(); mv.onResume(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_map, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.ok: if (latLng == null) { Toast.makeText(this, "请点击地图选择一个地点!", Toast.LENGTH_SHORT).show(); return true; } new AlertDialog.Builder(AMapActivity.this).setTitle("注意").setMessage("部分应用的定位如qq附近的人,钉钉签到等使用的是基站定位,如需使用相关功能请同时填写基站信息") .setPositiveButton("知道了", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .show(); ContentValues contentValues = new ContentValues(); contentValues.put("package_name", pacakgeName); contentValues.put("latitude", latLng.latitude); contentValues.put("longitude", latLng.longitude); contentValues.put("lac", lac); contentValues.put("cid", cid); mSQLiteDatabase.insertWithOnConflict(DbHelper.APP_TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE); break; case R.id.search: View view = LayoutInflater.from(this).inflate(R.layout.dialog_search, null, false); final EditText et_key = (EditText) view.findViewById(R.id.key); new AlertDialog.Builder(this).setView(view) .setTitle("搜索位置") .setPositiveButton("搜索", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { search(et_key.getText().toString()); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); break; case R.id.lac: View view1 = getLayoutInflater().inflate(R.layout.dialog_lac_cid, null, false); final TextInputEditText etLac = (TextInputEditText) view1.findViewById(R.id.lac); final TextInputEditText etCid = (TextInputEditText) view1.findViewById(R.id.cid); new AlertDialog.Builder(AMapActivity.this).setTitle("填写基站信息").setView(view1).setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { canCloseDialog(dialog, false); if (TextUtils.isEmpty(etLac.getText())) { etLac.setError("lac的值不应该为空"); } if (TextUtils.isEmpty(etCid.getText())) { etCid.setError("cid的值不应该为空"); } if (!TextUtils.isEmpty(etLac.getText()) && !TextUtils.isEmpty(etCid.getText())) { int lac1 = Integer.parseInt(etLac.getText().toString()); int cid1 = Integer.parseInt(etCid.getText().toString()); if (lac1 <= 0 || lac1 >= 65535) { etLac.setError("lac的值应该是0~65535"); lac1 = 0; } if (cid1 <= 0 || cid1 >= 65535) { etCid.setError("cid的值应该是0~65535"); cid1 = 0; } lac = lac1; cid = cid1; } ContentValues contentValues = new ContentValues(); contentValues.put("package_name", pacakgeName); contentValues.put("lac", lac); contentValues.put("cid", cid); mSQLiteDatabase.insertWithOnConflict(DbHelper.APP_TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); break; } return super.onOptionsItemSelected(item); } private void canCloseDialog(DialogInterface dialogInterface, boolean close) { try { Field field = dialogInterface.getClass().getSuperclass().getDeclaredField("mShowing"); field.setAccessible(true); field.set(dialogInterface, close); } catch (Exception e) { e.printStackTrace(); } } @Override protected void onPause() { super.onPause(); mv.onPause(); } private void search(final String key) { PoiSearch.Query query = new PoiSearch.Query(key, null, null); query.setPageSize(10); query.setPageNum(0); PoiSearch poiSearch = new PoiSearch(this, query); poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() { @Override public void onPoiSearched(PoiResult poiResult, int i) { if (i == 1000) { final ArrayList poiItems = poiResult.getPois(); if (poiItems.size() != 0) { String[] keyList = new String[poiItems.size()]; for (int j = 0; j < poiItems.size(); j++) { keyList[j] = poiItems.get(j).getTitle(); } new AlertDialog.Builder(AMapActivity.this) .setTitle("选择位置") .setSingleChoiceItems(keyList, 0, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(poiItems.get(which).getLatLonPoint().getLatitude(), poiItems.get(which).getLatLonPoint().getLongitude()))); aMap.moveCamera(CameraUpdateFactory.zoomTo(aMap.getMaxZoomLevel())); dialog.dismiss(); } }).show(); } else { Toast.makeText(AMapActivity.this, "没有搜索结果", Toast.LENGTH_SHORT).show(); } } } @Override public void onPoiItemSearched(PoiItem poiItem, int i) { } }); poiSearch.searchPOIAsyn(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mv.onSaveInstanceState(outState); } @Override protected void onDestroy() { super.onDestroy(); mv.onDestroy(); mSQLiteDatabase.close(); } @Override public void onMapClick(LatLng latLng) { aMap.clear(); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.draggable(true); markerOptions.title("经度:" + latLng.longitude + ",纬度:" + latLng.latitude); aMap.addMarker(markerOptions); this.latLng = latLng; } } ================================================ FILE: app/src/main/java/name/caiyao/fakegps/ui/MainActivity.java ================================================ package name.caiyao.fakegps.ui; import android.app.ProgressDialog; import android.content.Intent; import android.content.pm.PackageInfo; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import name.caiyao.fakegps.BuildConfig; import name.caiyao.fakegps.R; import name.caiyao.fakegps.data.AppInfo; public class MainActivity extends AppCompatActivity { private ProgressDialog mProgressDialog; private AppAdapter mAppAdapter; private ArrayList mAppInfos = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv_app); assert recyclerView != null; recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); recyclerView.setHasFixedSize(true); mAppAdapter = new AppAdapter(mAppInfos); recyclerView.setAdapter(mAppAdapter); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mProgressDialog = new ProgressDialog(this); mProgressDialog.setMax(100); mProgressDialog.setMessage("正在扫描应用程序"); mProgressDialog.show(); GetAppInfoTask getAppInfoTask = new GetAppInfoTask(); getAppInfoTask.execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main,menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.setting: break; case R.id.donate: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://qr.alipay.com/apoy1zw1o2xpc7915d"))); break; case R.id.about: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://caiyao.name/releases"))); break; } return super.onOptionsItemSelected(item); } private class GetAppInfoTask extends AsyncTask> { @Override protected ArrayList doInBackground(Integer[] params) { ArrayList appList = new ArrayList<>(); List packages = getPackageManager().getInstalledPackages(0); for (int i = 0; i < packages.size(); i++) { PackageInfo packageInfo = packages.get(i); AppInfo tmpInfo = new AppInfo(); tmpInfo.appName = packageInfo.applicationInfo.loadLabel(getPackageManager()).toString(); tmpInfo.packageName = packageInfo.packageName; tmpInfo.versionName = packageInfo.versionName; tmpInfo.versionCode = packageInfo.versionCode; tmpInfo.appIcon = packageInfo.applicationInfo.loadIcon(getPackageManager()); if (!packageInfo.packageName.equals(BuildConfig.APPLICATION_ID)) appList.add(tmpInfo); publishProgress(i / packages.size() * 100); } return appList; } @Override protected void onProgressUpdate(Integer... values) { mProgressDialog.setProgress(values[0]); } @Override protected void onPostExecute(ArrayList o) { mProgressDialog.dismiss(); mAppInfos.addAll(o); mAppAdapter.notifyDataSetChanged(); } } class AppAdapter extends RecyclerView.Adapter { ArrayList mAppInfos; AppAdapter(ArrayList appInfos) { this.mAppInfos = appInfos; } @Override public AppViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new AppViewHolder(getLayoutInflater().inflate(R.layout.app_item, parent, false)); } @Override public void onBindViewHolder(final AppViewHolder holder, int position) { holder.ivIcon.setImageDrawable(mAppInfos.get(position).getAppIcon()); holder.tvName.setText(mAppInfos.get(position).getAppName()); holder.tvPackageName.setText(mAppInfos.get(position).getPackageName()); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, AMapActivity.class).putExtra("package_name", mAppInfos.get(holder.getAdapterPosition()).getPackageName())); } }); } @Override public int getItemCount() { return mAppInfos.size(); } class AppViewHolder extends RecyclerView.ViewHolder { ImageView ivIcon; TextView tvName; TextView tvPackageName; AppViewHolder(View itemView) { super(itemView); ivIcon = (ImageView) itemView.findViewById(R.id.iv_icon); tvName = (TextView) itemView.findViewById(R.id.tv_name); tvPackageName = (TextView) itemView.findViewById(R.id.tv_package_name); } } } } ================================================ FILE: app/src/main/res/layout/activity_amap.xml ================================================ ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: app/src/main/res/layout/app_item.xml ================================================ ================================================ FILE: app/src/main/res/layout/content_main.xml ================================================ ================================================ FILE: app/src/main/res/layout/dialog_lac_cid.xml ================================================ ================================================ FILE: app/src/main/res/layout/dialog_search.xml ================================================ ================================================ FILE: app/src/main/res/menu/menu_main.xml ================================================ ================================================ FILE: app/src/main/res/menu/menu_map.xml ================================================ ================================================ FILE: app/src/main/res/values/colors.xml ================================================ #3F51B5 #303F9F #FF4081 ================================================ FILE: app/src/main/res/values/dimens.xml ================================================ 16dp 16dp 16dp ================================================ FILE: app/src/main/res/values/strings.xml ================================================ 模拟位置 开始 停止 支付宝捐赠 关于 ================================================ FILE: app/src/main/res/values/styles.xml ================================================ ================================================ FILE: app/src/main/res/values-w820dp/dimens.xml ================================================ 64dp ================================================ FILE: build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ #Sat Oct 08 16:10:49 CST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip ================================================ FILE: gradle.properties ================================================ ## Project-wide Gradle settings. # # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx1024m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Sat Oct 08 16:07:45 CST 2016 systemProp.http.proxyHost=127.0.0.1 systemProp.http.proxyPort=1081 ================================================ FILE: gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: settings.gradle ================================================ include ':app'