mirror of
https://github.com/iweizime/StepChanger.git
synced 2026-10-17 13:40:29 +08:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 56605d7069 | |||
| 8cbbb38371 | |||
| 8d7847bc61 | |||
| 2084746f38 | |||
| 618baa0c52 | |||
| 31a189ca20 | |||
| 2165ef3abf | |||
| 60164cdf4b | |||
| 3a328f64aa | |||
| 5b63caf77d | |||
| 3d530ac18a | |||
| 4fe016832c |
+84
-5
@@ -1,6 +1,85 @@
|
||||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### Android template
|
||||
# Built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio Navigation editor temp files
|
||||
.navigation/
|
||||
|
||||
# Android Studio captures folder
|
||||
captures/
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/build
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/gradle.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/dictionaries
|
||||
.idea/libraries
|
||||
# Android Studio 3 in .gitignore file.
|
||||
.idea/caches
|
||||
.idea/modules.xml
|
||||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||
.idea/navEditor.xml
|
||||
|
||||
# Keystore files
|
||||
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||
#*.jks
|
||||
#*.keystore
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Freeline
|
||||
freeline.py
|
||||
freeline/
|
||||
freeline_project_description.json
|
||||
|
||||
# fastlane
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
fastlane/readme.md
|
||||
|
||||
# Version control
|
||||
vcs.xml
|
||||
|
||||
# lint
|
||||
lint/intermediates/
|
||||
lint/generated/
|
||||
lint/outputs/
|
||||
lint/tmp/
|
||||
# lint/reports/
|
||||
|
||||
|
||||
Generated
+3
@@ -3,6 +3,9 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<compositeConfiguration>
|
||||
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
||||
</compositeConfiguration>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
|
||||
Generated
+14
-16
@@ -1,43 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="4">
|
||||
<list size="10">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
||||
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
|
||||
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<list size="9">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
||||
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
|
||||
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
+17
-22
@@ -1,15 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion "26.0.1"
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '29.0.1'
|
||||
defaultConfig {
|
||||
applicationId "me.iweizi.stepchanger"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 26
|
||||
targetSdkVersion 27
|
||||
versionCode 1
|
||||
versionName '1.3'
|
||||
versionName '1.4'
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
setProperty("archivesBaseName", "StepChanger")
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -17,29 +18,23 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
output.outputFile = new File(
|
||||
output.outputFile.parent,
|
||||
"StepChanger-${variant.versionName}-${variant.buildType.name}.apk")
|
||||
}
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
androidTestImplementation ('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
|
||||
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
|
||||
compile 'com.android.support:support-v4:26.0.0-alpha1'
|
||||
compile 'com.android.support:design:26.0.0-alpha1'
|
||||
compile 'eu.chainfire:libsuperuser:1.0.0.201704021214'
|
||||
compile 'com.alibaba:fastjson:1.1.63.android'
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile 'com.android.support:cardview-v7:26.0.0-alpha1'
|
||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||
implementation 'com.android.support:support-v4:27.1.1'
|
||||
implementation 'com.android.support:design:27.1.1'
|
||||
implementation 'eu.chainfire:libsuperuser:1.1.0.+'
|
||||
implementation 'com.alibaba:fastjson:1.1.63.android'
|
||||
implementation'com.android.support.constraint:constraint-layout:1.1.3'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
implementation'com.android.support:cardview-v7:27.1.1'
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
|
||||
|
||||
<application
|
||||
android:name="me.iweizi.stepchanger.MyApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/running"
|
||||
android:label="@string/app_name"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.iweizi.stepchanger;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
public class MyApplication extends Application {
|
||||
private static Context ctx = null;
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
ctx = this;
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.util.Log;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
import me.iweizi.stepchanger.utils.Utils;
|
||||
@@ -230,7 +231,11 @@ public class StepData {
|
||||
isRead = booleans[0];
|
||||
mSuAvailable = Shell.SU.available();
|
||||
if (mSuAvailable) {
|
||||
Shell.SU.run(ROOT_CMD);
|
||||
try {
|
||||
Shell.Pool.SU.run(ROOT_CMD);
|
||||
} catch (Shell.ShellDiedException e) {
|
||||
Log.e("StepChanger", e.toString());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.content.SharedPreferences;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,8 +40,8 @@ public class NewPedoMeter extends StepData {
|
||||
private final String mNewPedometerPrivate;
|
||||
private final String mAlipayNewPedometer;
|
||||
private final String mAlipayNewPedometerPrivate;
|
||||
private final File mAlipayNewPedometerFile;
|
||||
private final File mAlipayNewPedometerPrivateFile;
|
||||
private final File mNewPedometerFile;
|
||||
private final File mNewPedometerPrivateFile;
|
||||
private SharedPreferences mNewPedometerSP;
|
||||
private SharedPreferences mNewPedometerPrivateSP;
|
||||
|
||||
@@ -51,8 +52,8 @@ public class NewPedoMeter extends StepData {
|
||||
mAlipayNewPedometer = ALIPAY_SP_DIR + NEW_PEDOMETER;
|
||||
mAlipayNewPedometerPrivate = ALIPAY_SP_DIR + NEW_PEDOMETER_PRIVATE;
|
||||
|
||||
mAlipayNewPedometerFile = new File(mAlipayNewPedometer);
|
||||
mAlipayNewPedometerPrivateFile = new File(mAlipayNewPedometerPrivate);
|
||||
mNewPedometerFile = new File(mNewPedometer);
|
||||
mNewPedometerPrivateFile = new File(mNewPedometerPrivate);
|
||||
|
||||
File sp_dir = new File(SP_DIR);
|
||||
if (!sp_dir.exists()) {
|
||||
@@ -60,9 +61,16 @@ public class NewPedoMeter extends StepData {
|
||||
sp_dir.mkdir();
|
||||
}
|
||||
|
||||
try {
|
||||
if (!mNewPedometerFile.exists()) mNewPedometerFile.createNewFile();
|
||||
if (!mNewPedometerPrivateFile.exists()) mNewPedometerPrivateFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ROOT_CMD = new String[]{
|
||||
"chmod o+rw " + mAlipayNewPedometer,
|
||||
"chmod o+rw " + mAlipayNewPedometerPrivate,
|
||||
"chmod g+rw " + mNewPedometer,
|
||||
"chmod g+rw " + mNewPedometerPrivate,
|
||||
};
|
||||
|
||||
mLoadButtonId = R.id.alipay_load_button;
|
||||
@@ -76,12 +84,12 @@ public class NewPedoMeter extends StepData {
|
||||
@Override
|
||||
public int read(Context context) {
|
||||
killAlipayProcess(context);
|
||||
Shell.SH.run(new String[]{
|
||||
"cp " + mAlipayNewPedometerPrivate + " " + mNewPedometerPrivate,
|
||||
"cp " + mAlipayNewPedometer + " " + mNewPedometer
|
||||
Shell.SU.run(new String[]{
|
||||
"cat " + mAlipayNewPedometerPrivate + " > " + mNewPedometerPrivate,
|
||||
"cat " + mAlipayNewPedometer + " > " + mNewPedometer
|
||||
});
|
||||
mNewPedometerSP = context.getSharedPreferences("NewPedoMeter", Context.MODE_PRIVATE);
|
||||
mNewPedometerPrivateSP = context.getSharedPreferences("NewPedoMeter_private", Context.MODE_PRIVATE);
|
||||
mNewPedometerSP = context.getSharedPreferences("NewPedoMeter", Context.MODE_MULTI_PROCESS);
|
||||
mNewPedometerPrivateSP = context.getSharedPreferences("NewPedoMeter_private", Context.MODE_MULTI_PROCESS);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -102,7 +110,7 @@ public class NewPedoMeter extends StepData {
|
||||
newLastRecord.setTime(lastUploadTime);
|
||||
newStepRecord.add(newLastRecord);
|
||||
saveStepRecord(newStepRecord);
|
||||
Shell.SH.run(new String[]{
|
||||
Shell.SU.run(new String[]{
|
||||
"cat " + mNewPedometerPrivate + " > " + mAlipayNewPedometerPrivate
|
||||
});
|
||||
return SUCCESS;
|
||||
@@ -160,12 +168,12 @@ public class NewPedoMeter extends StepData {
|
||||
|
||||
@Override
|
||||
protected boolean canRead() {
|
||||
return mAlipayNewPedometerFile.canRead() && mAlipayNewPedometerPrivateFile.canRead();
|
||||
return mNewPedometerFile.canRead() && mNewPedometerPrivateFile.canRead();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canWrite() {
|
||||
return mAlipayNewPedometerFile.canWrite() && mAlipayNewPedometerPrivateFile.canWrite();
|
||||
return mNewPedometerFile.canWrite() && mNewPedometerPrivateFile.canWrite();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class QQDetailsActivity extends BaseDetailsActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
mLayoutId = R.layout.activity_qq_details;
|
||||
mStepData = StepInfo.get();
|
||||
mStepData = StepInfo.get(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ public class QQFragment extends BaseFragment {
|
||||
|
||||
public QQFragment() {
|
||||
mLayoutId = R.layout.fragment_qq;
|
||||
mStepData = StepInfo.get();
|
||||
mDetailsClass = QQDetailsActivity.class;
|
||||
}
|
||||
|
||||
@@ -23,6 +22,7 @@ public class QQFragment extends BaseFragment {
|
||||
|
||||
@Override
|
||||
protected void findView(View view) {
|
||||
mStepData = StepInfo.get(getActivity());
|
||||
mLoadButton = view.findViewById(R.id.qq_load_button);
|
||||
mStoreButton = view.findViewById(R.id.qq_store_button);
|
||||
mDetailsButton = view.findViewById(R.id.qq_details_button);
|
||||
|
||||
@@ -2,14 +2,25 @@ package me.iweizi.stepchanger.qq;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Base64;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.Signature;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
import me.iweizi.stepchanger.R;
|
||||
import me.iweizi.stepchanger.StepData;
|
||||
import me.iweizi.stepchanger.utils.Utils;
|
||||
@@ -21,27 +32,58 @@ import me.iweizi.stepchanger.utils.Utils;
|
||||
|
||||
public class StepInfo extends StepData {
|
||||
|
||||
private static final StepInfo sStepInfo = new StepInfo();
|
||||
private static final String STEP_INFO = "/data/data/com.tencent.mobileqq/files/step.info";
|
||||
private static StepInfo sStepInfo = null;
|
||||
private static final String STEP_INFO = "/data/data/me.iweizi.stepchanger/files/step.info";
|
||||
private static final String STEP_SIGN_INFO = "/data/data/me.iweizi.stepchanger/files/stepSign.info";
|
||||
private static final String ORIG_STEP_INFO = "/data/data/com.tencent.mobileqq/files/step.info";
|
||||
private static final String ORIG_STEP_SIGN_INFO = "/data/data/com.tencent.mobileqq/files/stepSign.info";
|
||||
private static final String sKey = "4eY#X@~g.+U)2%$<";
|
||||
private static final String QQ = "com.tencent.mobileqq";
|
||||
private static final String QQ_MSF = "com.tencent.mobileqq:MSF";
|
||||
private static final String KEYSTORE_DIR = "/data/misc/keystore/user_0/";
|
||||
private static final int MAX_SUPPORT_VERSION_CODE = 730;
|
||||
|
||||
private static final File sStepInfoFile = new File(STEP_INFO);
|
||||
private static final File sStepSignInfoFile = new File(STEP_SIGN_INFO);
|
||||
private JSONObject mStepInfo;
|
||||
private Cryptor mCryptor;
|
||||
|
||||
private StepInfo() {
|
||||
ROOT_CMD = new String[]{
|
||||
"chmod o+rw " + STEP_INFO
|
||||
};
|
||||
private StepInfo(Context context) throws IOException {
|
||||
File dir = context.getFilesDir();
|
||||
if (!dir.exists())
|
||||
dir.mkdirs();
|
||||
if (!sStepInfoFile.exists())
|
||||
sStepInfoFile.createNewFile();
|
||||
if (!checkVersion(context)) {
|
||||
if (!sStepSignInfoFile.exists())
|
||||
sStepSignInfoFile.createNewFile();
|
||||
/* 复制key */
|
||||
int qq_uid = getUID("com.tencent.mobileqq", context);
|
||||
int my_uid = getUID("me.iweizi.stepchanger", context);
|
||||
ROOT_CMD = new String[]{
|
||||
"cp " + KEYSTORE_DIR + String.valueOf(qq_uid) + "_USRCERT_step_info "
|
||||
+ KEYSTORE_DIR + String.valueOf(my_uid) + "_USRCERT_step_info",
|
||||
"cp " + KEYSTORE_DIR + String.valueOf(qq_uid) + "_USRPKEY_step_info "
|
||||
+ KEYSTORE_DIR + String.valueOf(my_uid) + "_USRPKEY_step_info",
|
||||
"chown keystore:keystore " + KEYSTORE_DIR + String.valueOf(my_uid) + "_USRCERT_step_info",
|
||||
"chown keystore:keystore " + KEYSTORE_DIR + String.valueOf(my_uid) + "_USRPKEY_step_info"
|
||||
};
|
||||
}
|
||||
|
||||
mCryptor = new Cryptor(sKey.getBytes());
|
||||
mStepInfo = null;
|
||||
mLoadButtonId = R.id.qq_load_button;
|
||||
mStoreButtonId = R.id.qq_store_button;
|
||||
}
|
||||
|
||||
public static StepInfo get() {
|
||||
public static StepInfo get(Context context) {
|
||||
if (sStepInfo == null) {
|
||||
try {
|
||||
sStepInfo = new StepInfo(context);
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return sStepInfo;
|
||||
}
|
||||
|
||||
@@ -62,11 +104,23 @@ public class StepInfo extends StepData {
|
||||
byte[] ciphertext;
|
||||
byte[] plaintext;
|
||||
try {
|
||||
raf = new RandomAccessFile(STEP_INFO, "r");
|
||||
ciphertext = new byte[(int) raf.length()];
|
||||
raf.read(ciphertext);
|
||||
plaintext = mCryptor.decrypt(ciphertext);
|
||||
mStepInfo = new JSONObject(new String(plaintext));
|
||||
Shell.SU.run(new String[]{
|
||||
"cat " + ORIG_STEP_INFO + " > " + STEP_INFO
|
||||
});
|
||||
if(checkVersion(context)) {
|
||||
raf = new RandomAccessFile(STEP_INFO, "r");
|
||||
ciphertext = new byte[(int) raf.length()];
|
||||
raf.read(ciphertext);
|
||||
plaintext = mCryptor.decrypt(ciphertext);
|
||||
mStepInfo = new JSONObject(new String(plaintext));
|
||||
raf.close();
|
||||
} else {
|
||||
raf = new RandomAccessFile(STEP_INFO, "r");
|
||||
plaintext = new byte[(int) raf.length()];
|
||||
raf.read(plaintext);
|
||||
mStepInfo = new JSONObject(new String(plaintext));
|
||||
raf.close();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
return FAIL;
|
||||
}
|
||||
@@ -78,12 +132,36 @@ public class StepInfo extends StepData {
|
||||
protected int write(Context context) {
|
||||
killQQProcess(context);
|
||||
try {
|
||||
FileOutputStream outputStream = new FileOutputStream(STEP_INFO);
|
||||
String offsetKey = String.valueOf(Utils.beginOfToday()) + "_offset";
|
||||
int offset = mStepInfo.getInt(offsetKey);
|
||||
offset = offset + (int) (getStep() - getLastUploadStep());
|
||||
mStepInfo.put(offsetKey, offset);
|
||||
outputStream.write(mCryptor.encrypt(mStepInfo.toString().getBytes()));
|
||||
if (checkVersion(context)) {
|
||||
FileOutputStream outputStream = new FileOutputStream(STEP_INFO);
|
||||
String offsetKey = String.valueOf(Utils.beginOfToday()) + "_offset";
|
||||
int offset = mStepInfo.getInt(offsetKey);
|
||||
offset = offset + (int) (getStep() - getLastUploadStep());
|
||||
mStepInfo.put(offsetKey, offset);
|
||||
outputStream.write(mCryptor.encrypt(mStepInfo.toString().getBytes()));
|
||||
outputStream.close();
|
||||
} else {
|
||||
FileOutputStream stepOutputStream = new FileOutputStream(STEP_INFO);
|
||||
String offsetKey = String.valueOf(Utils.beginOfToday()) + "_offset";
|
||||
int offset = mStepInfo.getInt(offsetKey);
|
||||
offset = offset + (int) (getStep() - getLastUploadStep());
|
||||
mStepInfo.put(offsetKey, offset);
|
||||
stepOutputStream.write(mStepInfo.toString().getBytes());
|
||||
stepOutputStream.close();
|
||||
|
||||
FileOutputStream stepSignOutputStream = new FileOutputStream(STEP_SIGN_INFO);
|
||||
String base64 = Base64.encodeToString(getSign(mStepInfo.toString().getBytes()), 0);
|
||||
stepSignOutputStream.write(base64.getBytes());
|
||||
stepSignOutputStream.close();
|
||||
|
||||
Shell.SU.run(new String[]{
|
||||
"cat " + STEP_SIGN_INFO + " > " + ORIG_STEP_SIGN_INFO
|
||||
});
|
||||
}
|
||||
|
||||
Shell.SU.run(new String[]{
|
||||
"cat " + STEP_INFO + " > " + ORIG_STEP_INFO
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
return FAIL;
|
||||
}
|
||||
@@ -107,6 +185,14 @@ public class StepInfo extends StepData {
|
||||
String beginOfToday = String.valueOf(Utils.beginOfToday());
|
||||
if (mStepInfo != null) {
|
||||
try {
|
||||
if (!mStepInfo.has(beginOfToday+"_total")) {
|
||||
String beginOfYesterday = String.valueOf(Utils.beginOfToday() - 24 * 60 * 60 * 1000);
|
||||
int yesterday_total = mStepInfo.getInt(beginOfYesterday + "_total");
|
||||
mStepInfo.put(beginOfToday + "_total", yesterday_total);
|
||||
mStepInfo.put(beginOfToday + "_init", yesterday_total);
|
||||
mStepInfo.put(beginOfToday + "_offset", 0);
|
||||
}
|
||||
|
||||
return (mStepInfo.getInt(beginOfToday + "_total")
|
||||
- mStepInfo.getInt(beginOfToday + "_init")
|
||||
+ mStepInfo.getInt(beginOfToday + "_offset"));
|
||||
@@ -146,4 +232,51 @@ public class StepInfo extends StepData {
|
||||
am.killBackgroundProcesses(QQ);
|
||||
am.killBackgroundProcesses(QQ_MSF);
|
||||
}
|
||||
|
||||
private boolean checkVersion(Context context) {
|
||||
PackageInfo pi = null;
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
pi = pm.getPackageInfo(QQ, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pi.versionCode <= MAX_SUPPORT_VERSION_CODE;
|
||||
}
|
||||
|
||||
private int getUID(String packageName, Context context) {
|
||||
ApplicationInfo ai = null;
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
ai = pm.getApplicationInfo(packageName, 0);
|
||||
return ai.uid;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getSign(byte[] data) {
|
||||
try {
|
||||
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
|
||||
ks.load(null);
|
||||
Enumeration<String> aliases = ks.aliases();
|
||||
KeyStore.Entry entry = ks.getEntry("step_info", null);
|
||||
if (entry != null) {
|
||||
|
||||
Signature sig = Signature.getInstance("SHA256withRSA");
|
||||
sig.initSign(((KeyStore.PrivateKeyEntry)entry).getPrivateKey());
|
||||
sig.update(data);
|
||||
return sig.sign();
|
||||
}
|
||||
return null;
|
||||
} catch (KeyStoreException e) {
|
||||
return null;
|
||||
} catch (CertificateException e) {
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
package me.iweizi.stepchanger.wechat;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
abstract class StepBean {
|
||||
public long beginOfToday;
|
||||
public long lastSaveStepTime;
|
||||
public long lastWriteTime;
|
||||
public long sensorTimeStamp;
|
||||
public long preSensorStep;
|
||||
public long todayStep;
|
||||
public long lastSaveSensorStep;
|
||||
|
||||
protected HashMap<Integer, Object> mStepCounterMap;
|
||||
protected File mCfgFile;
|
||||
|
||||
protected StepBean(File cfgFile) {
|
||||
mCfgFile = cfgFile;
|
||||
}
|
||||
|
||||
public void read() throws IOException, ClassCastException , ClassNotFoundException{
|
||||
FileInputStream fis = new FileInputStream(mCfgFile);
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
// noinspection unchecked
|
||||
mStepCounterMap = (HashMap<Integer, Object>) ois.readObject();
|
||||
ois.close();
|
||||
fis.close();
|
||||
|
||||
readConfig();
|
||||
}
|
||||
|
||||
public void write(long step) throws IOException {
|
||||
// push
|
||||
FileOutputStream fos;
|
||||
ObjectOutputStream oos;
|
||||
|
||||
fos = new FileOutputStream(mCfgFile);
|
||||
oos = new ObjectOutputStream(fos);
|
||||
writeStep(step);
|
||||
oos.writeObject(mStepCounterMap);
|
||||
oos.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
|
||||
abstract void readConfig();
|
||||
|
||||
abstract void writeStep(long step);
|
||||
}
|
||||
|
||||
class StepBeanLegacy extends StepBean {
|
||||
public StepBeanLegacy(File cfgFile) {
|
||||
super(cfgFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readConfig() {
|
||||
this.beginOfToday = (Long) mStepCounterMap.get(202) * 10000L;
|
||||
this.todayStep = (Long) mStepCounterMap.get(201);
|
||||
this.preSensorStep = (Long) mStepCounterMap.get(203);
|
||||
this.lastSaveStepTime = (Long) mStepCounterMap.get(204);
|
||||
this.sensorTimeStamp = (Long) mStepCounterMap.get(209);
|
||||
this.lastSaveSensorStep = this.todayStep;
|
||||
this.lastWriteTime = this.lastSaveStepTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeStep(long step) {
|
||||
mStepCounterMap.put(201, step);
|
||||
}
|
||||
}
|
||||
|
||||
class StepBeanV7 extends StepBean {
|
||||
public StepBeanV7(File cfgFile) {
|
||||
super(cfgFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readConfig() {
|
||||
|
||||
String stringVec = (String) mStepCounterMap.get(301);
|
||||
|
||||
long[] lv = stringVec2long(stringVec);
|
||||
this.beginOfToday = lv[0];
|
||||
this.lastSaveStepTime = lv[1];
|
||||
this.lastWriteTime = lv[2];
|
||||
this.sensorTimeStamp = lv[3];
|
||||
this.preSensorStep = lv[4];
|
||||
this.todayStep = lv[5];
|
||||
this.lastSaveSensorStep = lv[6];
|
||||
|
||||
}
|
||||
|
||||
|
||||
private long[] stringVec2long(String data) {
|
||||
if (data == null || data.isEmpty()) {
|
||||
return new long[7];
|
||||
}
|
||||
String[] sv = data.split(",");
|
||||
long[] lv = new long[sv.length];
|
||||
|
||||
for (int i = 0; i < lv.length; ++i) {
|
||||
String s = sv[i];
|
||||
long l;
|
||||
if (s != null && !s.isEmpty()) {
|
||||
l = Long.valueOf(s);
|
||||
} else {
|
||||
l = 0;
|
||||
}
|
||||
lv[i] = l;
|
||||
}
|
||||
return lv;
|
||||
|
||||
}
|
||||
protected void writeStep(long step) {
|
||||
this.todayStep = step;
|
||||
String data = String.format(Locale.ENGLISH, "%d,%d,%d,%d,%d,%d,%d",
|
||||
this.beginOfToday,
|
||||
this.lastSaveStepTime,
|
||||
this.lastWriteTime,
|
||||
this.sensorTimeStamp,
|
||||
this.preSensorStep,
|
||||
this.todayStep,
|
||||
this.lastSaveSensorStep);
|
||||
mStepCounterMap.put(301, data);
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,19 @@ package me.iweizi.stepchanger.wechat;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell;
|
||||
import me.iweizi.stepchanger.MyApplication;
|
||||
import me.iweizi.stepchanger.R;
|
||||
import me.iweizi.stepchanger.StepData;
|
||||
|
||||
@@ -31,54 +35,103 @@ class StepCounterCfg extends StepData {
|
||||
private static final int LAST_UPLOAD_TIME = 3;
|
||||
private static final int LAST_UPLOAD_STEP = 4;
|
||||
|
||||
private static final File WX_DATA_DIR = new File("/data/data/com.tencent.mm/MicroMsg/");
|
||||
|
||||
@SuppressLint("SdCardPath")
|
||||
private static final String STEP_COUNTER_CFG = "/data/data/com.tencent.mm/MicroMsg/stepcounter.cfg";
|
||||
private static final String UPLOAD_STATUS_CFG = "MM_stepcounter.cfg";
|
||||
@SuppressLint("SdCardPath")
|
||||
private static final String MM_STEP_COUNTER_CFG = "/data/data/com.tencent.mm/MicroMsg/MM_stepcounter.cfg";
|
||||
private static final String V7_LOCAL_STEP_CFG = "PUSH_stepcounter.cfg";
|
||||
@SuppressLint("SdCardPath")
|
||||
private static final String LEGACY_LOCAL_STEP_CFG = "stepcounter.cfg";
|
||||
|
||||
private static final String WECHAT = "com.tencent.mm";
|
||||
private static final String WECHAT_EX = "com.tencent.mm:exdevice";
|
||||
private static final StepCounterCfg sStepCounterCfg = new StepCounterCfg();
|
||||
private final File mStepCounterCfgFile;
|
||||
private final File mMMStepCounterCfgFile;
|
||||
private HashMap<Integer, Long> mStepCounterMap = null;
|
||||
private static StepCounterCfg sStepCounterCfg = null;
|
||||
private HashMap<Integer, ?> mMMStepCounterMap = null;
|
||||
private StepBean mStepBean; // must sync with mod_step_cfg
|
||||
|
||||
private File wx_local_step_cfg;
|
||||
private File mod_step_cfg;
|
||||
|
||||
private File wx_upload_status_cfg;
|
||||
private File mod_upload_status_cfg;
|
||||
|
||||
|
||||
private StepCounterCfg() {
|
||||
super();
|
||||
|
||||
mStepCounterCfgFile = new File(STEP_COUNTER_CFG);
|
||||
mMMStepCounterCfgFile = new File(MM_STEP_COUNTER_CFG);
|
||||
|
||||
ROOT_CMD = new String[]{
|
||||
"chmod o+rw " + mStepCounterCfgFile.getAbsolutePath(),
|
||||
"chmod o+rw " + mMMStepCounterCfgFile.getAbsolutePath(),
|
||||
"chmod o+x " + mStepCounterCfgFile.getParent(),
|
||||
"chmod o+x " + mMMStepCounterCfgFile.getParent()
|
||||
};
|
||||
mLoadButtonId = R.id.wechat_load_button;
|
||||
mStoreButtonId = R.id.wechat_store_button;
|
||||
|
||||
Context ctx = MyApplication.getContext();
|
||||
int versionCode = getWeixinVersionCode();
|
||||
wx_upload_status_cfg = new File(WX_DATA_DIR, UPLOAD_STATUS_CFG);
|
||||
mod_upload_status_cfg = new File(ctx.getFilesDir(), UPLOAD_STATUS_CFG);
|
||||
if (versionCode == -1) {
|
||||
ROOT_CMD = new String[]{};
|
||||
Toast.makeText(ctx, "Weixin is not installed.", Toast.LENGTH_SHORT).show();
|
||||
wx_local_step_cfg = null;
|
||||
mod_step_cfg = null;
|
||||
mStepBean = null;
|
||||
} else if (versionCode >= 1363) {
|
||||
wx_local_step_cfg = new File(WX_DATA_DIR, V7_LOCAL_STEP_CFG);
|
||||
mod_step_cfg = new File(ctx.getFilesDir(), V7_LOCAL_STEP_CFG);
|
||||
mStepBean = new StepBeanV7(mod_step_cfg);
|
||||
} else {
|
||||
wx_local_step_cfg = new File(WX_DATA_DIR, LEGACY_LOCAL_STEP_CFG);
|
||||
mod_step_cfg = new File(ctx.getFilesDir(), LEGACY_LOCAL_STEP_CFG);
|
||||
mStepBean = new StepBeanLegacy(mod_step_cfg);
|
||||
}
|
||||
if (mod_step_cfg != null && mod_step_cfg.exists()) {
|
||||
mod_step_cfg.delete();
|
||||
}
|
||||
|
||||
if (mod_upload_status_cfg.exists()) {
|
||||
mod_upload_status_cfg.delete();
|
||||
}
|
||||
ROOT_CMD = new String[]{
|
||||
String.format("cp %s %s", wx_local_step_cfg, mod_step_cfg),
|
||||
"chmod o+w " + mod_step_cfg,
|
||||
String.format("cp %s %s", wx_upload_status_cfg, mod_upload_status_cfg),
|
||||
"chmod o+w " + mod_upload_status_cfg,
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private int getWeixinVersionCode() {
|
||||
Context ctx = MyApplication.getContext();
|
||||
|
||||
PackageManager pm = ctx.getPackageManager();
|
||||
try {
|
||||
PackageInfo pi = pm.getPackageInfo("com.tencent.mm", 0);
|
||||
return pi.versionCode;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static StepCounterCfg get() {
|
||||
if (sStepCounterCfg == null) {
|
||||
sStepCounterCfg = new StepCounterCfg();
|
||||
}
|
||||
return sStepCounterCfg;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int read(Context context) {
|
||||
if (mStepBean == null) {
|
||||
return FAIL;
|
||||
}
|
||||
FileInputStream fis;
|
||||
ObjectInputStream ois;
|
||||
|
||||
killWechatProcess(context);
|
||||
try {
|
||||
Shell.Pool.SU.run(ROOT_CMD);
|
||||
mStepBean.read();
|
||||
|
||||
fis = new FileInputStream(mStepCounterCfgFile);
|
||||
ois = new ObjectInputStream(fis);
|
||||
//noinspection unchecked
|
||||
mStepCounterMap = (HashMap<Integer, Long>) ois.readObject();
|
||||
ois.close();
|
||||
fis.close();
|
||||
|
||||
fis = new FileInputStream(mMMStepCounterCfgFile);
|
||||
fis = new FileInputStream(mod_upload_status_cfg);
|
||||
ois = new ObjectInputStream(fis);
|
||||
//noinspection unchecked
|
||||
mMMStepCounterMap = (HashMap<Integer, ?>) ois.readObject();
|
||||
@@ -91,20 +144,17 @@ class StepCounterCfg extends StepData {
|
||||
|
||||
@Override
|
||||
protected int write(Context context) {
|
||||
FileOutputStream fos;
|
||||
ObjectOutputStream oos;
|
||||
|
||||
if (mStepCounterMap == null) {
|
||||
if (mStepBean == null) {
|
||||
return FAIL;
|
||||
}
|
||||
try {
|
||||
killWechatProcess(context);
|
||||
fos = new FileOutputStream(STEP_COUNTER_CFG);
|
||||
oos = new ObjectOutputStream(fos);
|
||||
mStepCounterMap.put(CURRENT_TODAY_STEP, getStep());
|
||||
oos.writeObject(mStepCounterMap);
|
||||
oos.close();
|
||||
fos.close();
|
||||
mStepBean.write(getStep());
|
||||
String[] restore = new String[]{
|
||||
String.format("cp %s %s", mod_step_cfg, wx_local_step_cfg),
|
||||
String.format("cp %s %s", mod_upload_status_cfg, wx_upload_status_cfg),
|
||||
};
|
||||
Shell.Pool.SU.run(restore);
|
||||
return SUCCESS;
|
||||
} catch (Exception e) {
|
||||
return FAIL;
|
||||
@@ -113,12 +163,12 @@ class StepCounterCfg extends StepData {
|
||||
|
||||
@Override
|
||||
protected boolean canRead() {
|
||||
return mStepCounterCfgFile.canRead() && mMMStepCounterCfgFile.canRead();
|
||||
return mod_upload_status_cfg.canRead() && (mod_step_cfg != null && mod_step_cfg.canRead());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canWrite() {
|
||||
return mStepCounterCfgFile.canWrite() && mMMStepCounterCfgFile.canWrite();
|
||||
return mod_upload_status_cfg.canWrite() && (mod_step_cfg != null && mod_step_cfg.canWrite());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -143,8 +193,8 @@ class StepCounterCfg extends StepData {
|
||||
|
||||
@Override
|
||||
public long getLastSaveTime() {
|
||||
if (mStepCounterMap != null) {
|
||||
return mStepCounterMap.get(LAST_SAVE_STEP_TIME);
|
||||
if (mStepBean != null) {
|
||||
return mStepBean.lastSaveStepTime;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -152,8 +202,9 @@ class StepCounterCfg extends StepData {
|
||||
|
||||
@Override
|
||||
public long getLastSaveSensorStep() {
|
||||
if (mStepCounterMap != null) {
|
||||
return mStepCounterMap.get(PRE_SENSOR_STEP);
|
||||
|
||||
if (mStepBean != null) {
|
||||
return mStepBean.preSensorStep;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -161,7 +212,7 @@ class StepCounterCfg extends StepData {
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return mMMStepCounterMap != null && mStepCounterMap != null;
|
||||
return mMMStepCounterMap != null && mStepBean != null;
|
||||
}
|
||||
|
||||
private void killWechatProcess(Context context) {
|
||||
@@ -170,4 +221,6 @@ class StepCounterCfg extends StepData {
|
||||
am.killBackgroundProcesses(WECHAT);
|
||||
am.killBackgroundProcesses(WECHAT_EX);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-1
@@ -2,10 +2,11 @@
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
classpath 'com.android.tools.build:gradle:3.3.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@@ -14,6 +15,7 @@ buildscript {
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
+11
-5
@@ -1,13 +1,19 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
## 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.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
# 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
|
||||
#Mon Sep 25 18:31:59 CST 2017
|
||||
systemProp.http.proxyHost=127.0.0.1
|
||||
systemProp.http.nonProxyHosts=192.168.*
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
systemProp.http.proxyPort=1080
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Mon Sep 04 18:39:38 CST 2017
|
||||
#Fri May 08 20:32:03 CST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user