BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId "org.autojs.autojs"
|
applicationId "org.autojs.autojs"
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 23
|
targetSdkVersion 23
|
||||||
versionCode 404
|
versionCode 403
|
||||||
versionName "4.0.1 Beta"
|
versionName "4.0.2 Alpha"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
ndk {
|
ndk {
|
||||||
|
|||||||
@@ -236,14 +236,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<!-- 声明广告SDK所需要的组件 -->
|
|
||||||
<service
|
|
||||||
android:name="com.qq.e.comm.DownloadService"
|
|
||||||
android:exported="false"/>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name="com.qq.e.ads.ADActivity"
|
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"/>
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.autojs.autojs.autojs.build;
|
package org.autojs.autojs.autojs.build;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.stardust.app.GlobalAppContext;
|
import com.stardust.app.GlobalAppContext;
|
||||||
import com.stardust.autojs.apkbuilder.ApkBuilder;
|
import com.stardust.autojs.apkbuilder.ApkBuilder;
|
||||||
@@ -8,6 +9,7 @@ import com.stardust.autojs.apkbuilder.ManifestEditor;
|
|||||||
import com.stardust.autojs.apkbuilder.util.StreamUtils;
|
import com.stardust.autojs.apkbuilder.util.StreamUtils;
|
||||||
import com.stardust.autojs.project.ProjectConfig;
|
import com.stardust.autojs.project.ProjectConfig;
|
||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
|
|
||||||
import org.autojs.autojs.App;
|
import org.autojs.autojs.App;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -156,8 +158,10 @@ public class AutoJsApkBuilder extends ApkBuilder {
|
|||||||
projectConfig.setName(config.appName)
|
projectConfig.setName(config.appName)
|
||||||
.setPackageName(config.packageName)
|
.setPackageName(config.packageName)
|
||||||
.setVersionCode(config.versionCode)
|
.setVersionCode(config.versionCode)
|
||||||
.setVersionName(config.versionName)
|
.setVersionName(config.versionName);
|
||||||
.setMainScriptFile("main.js");
|
if (TextUtils.isEmpty(projectConfig.getMainScriptFile())) {
|
||||||
|
projectConfig.setMainScriptFile("main.js");
|
||||||
|
}
|
||||||
updateProjectConfigAssets(projectConfig, config.jsPath, config.jsPath);
|
updateProjectConfigAssets(projectConfig, config.jsPath, config.jsPath);
|
||||||
PFiles.write(ProjectConfig.configFileOfDir(config.jsPath), projectConfig.toJson());
|
PFiles.write(ProjectConfig.configFileOfDir(config.jsPath), projectConfig.toJson());
|
||||||
}
|
}
|
||||||
@@ -173,7 +177,7 @@ public class AutoJsApkBuilder extends ApkBuilder {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String relative = new File(projectDir).toURI().relativize(file.toURI()).getPath();
|
String relative = new File(projectDir).toURI().relativize(file.toURI()).getPath();
|
||||||
config.getAssets().add(relative);
|
config.addAsset(relative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.autojs.autojs.network.entity.VersionInfo;
|
|||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Headers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/9/20.
|
* Created by Stardust on 2017/9/20.
|
||||||
@@ -12,6 +13,7 @@ import retrofit2.http.GET;
|
|||||||
public interface UpdateCheckApi {
|
public interface UpdateCheckApi {
|
||||||
|
|
||||||
@GET("/assets/autojs/version.json")
|
@GET("/assets/autojs/version.json")
|
||||||
|
@Headers("Cache-Control: no-cache")
|
||||||
Observable<VersionInfo> checkForUpdates();
|
Observable<VersionInfo> checkForUpdates();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
package org.autojs.autojs.network.download;
|
package org.autojs.autojs.network.download;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||||
import com.stardust.concurrent.VolatileBox;
|
import com.stardust.concurrent.VolatileBox;
|
||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
|
|
||||||
|
import org.autojs.autojs.R;
|
||||||
|
import org.autojs.autojs.model.script.ScriptFile;
|
||||||
import org.autojs.autojs.network.NodeBB;
|
import org.autojs.autojs.network.NodeBB;
|
||||||
import org.autojs.autojs.network.api.DownloadApi;
|
import org.autojs.autojs.network.api.DownloadApi;
|
||||||
|
import org.autojs.autojs.tool.SimpleObserver;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -14,6 +23,7 @@ import java.net.URLDecoder;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import io.reactivex.subjects.PublishSubject;
|
import io.reactivex.subjects.PublishSubject;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
@@ -28,6 +38,7 @@ import retrofit2.Retrofit;
|
|||||||
|
|
||||||
public class DownloadManager {
|
public class DownloadManager {
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "DownloadManager";
|
||||||
private static DownloadManager sInstance;
|
private static DownloadManager sInstance;
|
||||||
|
|
||||||
private static final int RETRY_COUNT = 3;
|
private static final int RETRY_COUNT = 3;
|
||||||
@@ -81,6 +92,44 @@ public class DownloadManager {
|
|||||||
return task.progress();
|
return task.progress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Observable<File> downloadWithProgress(Context context, String url, String path) {
|
||||||
|
String fileName = DownloadManager.parseFileNameLocally(url);
|
||||||
|
return download(url, path, createDownloadProgressDialog(context, url, fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private MaterialDialog createDownloadProgressDialog(Context context, String url, String fileName) {
|
||||||
|
return new MaterialDialog.Builder(context)
|
||||||
|
.progress(false, 100)
|
||||||
|
.title(fileName)
|
||||||
|
.cancelable(false)
|
||||||
|
.positiveText(R.string.text_cancel_download)
|
||||||
|
.onPositive((dialog, which) -> DownloadManager.getInstance().cancelDownload(url))
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Observable<File> download(String url, String path, MaterialDialog progressDialog) {
|
||||||
|
PublishSubject<File> subject = PublishSubject.create();
|
||||||
|
DownloadManager.getInstance().download(url, path)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doOnNext(progressDialog::setProgress)
|
||||||
|
.subscribe(new SimpleObserver<Integer>() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
progressDialog.dismiss();
|
||||||
|
subject.onNext(new File(path));
|
||||||
|
subject.onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable error) {
|
||||||
|
Log.e(LOG_TAG, "Download failed", error);
|
||||||
|
progressDialog.dismiss();
|
||||||
|
subject.onError(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
public void cancelDownload(String url) {
|
public void cancelDownload(String url) {
|
||||||
VolatileBox<Boolean> status = mDownloadStatuses.get(url);
|
VolatileBox<Boolean> status = mDownloadStatuses.get(url);
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.stardust.app.GlobalAppContext;
|
|||||||
import com.stardust.pio.PFile;
|
import com.stardust.pio.PFile;
|
||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
import com.stardust.pio.UncheckedIOException;
|
import com.stardust.pio.UncheckedIOException;
|
||||||
|
|
||||||
import org.autojs.autojs.R;
|
import org.autojs.autojs.R;
|
||||||
import org.autojs.autojs.external.ScriptIntents;
|
import org.autojs.autojs.external.ScriptIntents;
|
||||||
import org.autojs.autojs.storage.file.TmpScriptFiles;
|
import org.autojs.autojs.storage.file.TmpScriptFiles;
|
||||||
@@ -260,48 +261,15 @@ public class ScriptOperations {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.flatMap(savePath -> download(url, savePath, createDownloadProgressDialog(url, fileName)));
|
.flatMap(savePath -> DownloadManager.getInstance().downloadWithProgress(mContext, url, savePath))
|
||||||
}
|
.map(ScriptFile::new);
|
||||||
|
|
||||||
private MaterialDialog createDownloadProgressDialog(String url, String fileName) {
|
|
||||||
return new MaterialDialog.Builder(mContext)
|
|
||||||
.progress(false, 100)
|
|
||||||
.title(fileName)
|
|
||||||
.cancelable(false)
|
|
||||||
.positiveText(R.string.text_cancel_download)
|
|
||||||
.onPositive((dialog, which) -> DownloadManager.getInstance().cancelDownload(url))
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Observable<ScriptFile> download(String url, String path, MaterialDialog progressDialog) {
|
|
||||||
PublishSubject<ScriptFile> subject = PublishSubject.create();
|
|
||||||
DownloadManager.getInstance().download(url, path)
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.doOnNext(progressDialog::setProgress)
|
|
||||||
.subscribe(new SimpleObserver<Integer>() {
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
progressDialog.dismiss();
|
|
||||||
subject.onNext(new ScriptFile(path));
|
|
||||||
subject.onComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable error) {
|
|
||||||
Log.e(LOG_TAG, "Download failed", error);
|
|
||||||
progressDialog.dismiss();
|
|
||||||
showMessage(R.string.text_download_failed);
|
|
||||||
subject.onError(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return subject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<ScriptFile> temporarilyDownload(String url) {
|
public Observable<ScriptFile> temporarilyDownload(String url) {
|
||||||
String fileName = DownloadManager.parseFileNameLocally(url);
|
|
||||||
return Observable.fromCallable(() -> TmpScriptFiles.create(mContext))
|
return Observable.fromCallable(() -> TmpScriptFiles.create(mContext))
|
||||||
.flatMap(tmpFile ->
|
.flatMap(tmpFile ->
|
||||||
download(url, tmpFile.getPath(), createDownloadProgressDialog(url, fileName)));
|
DownloadManager.getInstance().downloadWithProgress(mContext, url, tmpFile.getPath()))
|
||||||
|
.map(ScriptFile::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importFile() {
|
public void importFile() {
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkPermissions() {
|
private void checkPermissions() {
|
||||||
checkPermission(Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE);
|
checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showAccessibilitySettingPromptIfDisabled() {
|
private void showAccessibilitySettingPromptIfDisabled() {
|
||||||
@@ -245,18 +245,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
|
|||||||
if (getGrantResult(Manifest.permission.READ_EXTERNAL_STORAGE, permissions, grantResults) == PackageManager.PERMISSION_GRANTED) {
|
if (getGrantResult(Manifest.permission.READ_EXTERNAL_STORAGE, permissions, grantResults) == PackageManager.PERMISSION_GRANTED) {
|
||||||
StorageFileProvider.getDefault().notifyStoragePermissionGranted();
|
StorageFileProvider.getDefault().notifyStoragePermissionGranted();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED) {
|
|
||||||
new ThemeColorMaterialDialogBuilder(this)
|
|
||||||
.title(R.string.text_no_phone_state_permission)
|
|
||||||
.content(R.string.info_no_phone_state_permission)
|
|
||||||
.positiveText(R.string.text_request_permission)
|
|
||||||
.negativeText(R.string.text_exit)
|
|
||||||
.cancelable(false)
|
|
||||||
.onPositive(((dialog, which) -> checkPermissions()))
|
|
||||||
.onNegative((dialog, which) -> finish())
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getGrantResult(String permission, String[] permissions, int[] grantResults) {
|
private int getGrantResult(String permission, String[] permissions, int[] grantResults) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.autojs.autojs.ui.main.community;
|
package org.autojs.autojs.ui.main.community;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.design.widget.BottomSheetDialog;
|
import android.support.design.widget.BottomSheetDialog;
|
||||||
@@ -7,6 +8,7 @@ import android.support.design.widget.Snackbar;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.webkit.ValueCallback;
|
import android.webkit.ValueCallback;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.autojs.autojs.R;
|
import org.autojs.autojs.R;
|
||||||
import org.autojs.autojs.network.NodeBB;
|
import org.autojs.autojs.network.NodeBB;
|
||||||
@@ -62,6 +64,7 @@ public class CommunityWebView extends EWebView {
|
|||||||
mBottomSheetDialog.show();
|
mBottomSheetDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
@Optional
|
@Optional
|
||||||
@OnClick(R.id.save)
|
@OnClick(R.id.save)
|
||||||
void save() {
|
void save() {
|
||||||
@@ -69,14 +72,18 @@ public class CommunityWebView extends EWebView {
|
|||||||
new ScriptOperations(getContext(), CommunityWebView.this)
|
new ScriptOperations(getContext(), CommunityWebView.this)
|
||||||
.download(mUrl)
|
.download(mUrl)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.onErrorResumeNext(Observable.empty())
|
|
||||||
.subscribe(file ->
|
.subscribe(file ->
|
||||||
Snackbar.make(CommunityWebView.this, getResources().getString(R.string.format_file_downloaded, file.getPath())
|
Snackbar.make(CommunityWebView.this, getResources().getString(R.string.format_file_downloaded, file.getPath())
|
||||||
, Snackbar.LENGTH_LONG)
|
, Snackbar.LENGTH_LONG)
|
||||||
.setAction(R.string.text_open, v -> Scripts.edit(file))
|
.setAction(R.string.text_open, v -> Scripts.edit(file))
|
||||||
.show());
|
.show(),
|
||||||
|
error -> {
|
||||||
|
error.printStackTrace();
|
||||||
|
Snackbar.make(CommunityWebView.this, R.string.text_download_failed, Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
@Optional
|
@Optional
|
||||||
@OnClick(R.id.run)
|
@OnClick(R.id.run)
|
||||||
void run() {
|
void run() {
|
||||||
@@ -84,10 +91,12 @@ public class CommunityWebView extends EWebView {
|
|||||||
new ScriptOperations(getContext(), CommunityWebView.this)
|
new ScriptOperations(getContext(), CommunityWebView.this)
|
||||||
.temporarilyDownload(mUrl)
|
.temporarilyDownload(mUrl)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.onErrorResumeNext(Observable.empty())
|
|
||||||
.subscribe(file -> {
|
.subscribe(file -> {
|
||||||
Snackbar.make(CommunityWebView.this, R.string.text_start_running, Snackbar.LENGTH_SHORT).show();
|
Snackbar.make(CommunityWebView.this, R.string.text_start_running, Snackbar.LENGTH_SHORT).show();
|
||||||
Scripts.run(file);
|
Scripts.run(file);
|
||||||
|
}, error -> {
|
||||||
|
error.printStackTrace();
|
||||||
|
Snackbar.make(CommunityWebView.this, R.string.text_download_failed, Toast.LENGTH_SHORT).show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.autojs.autojs.ui.update;
|
package org.autojs.autojs.ui.update;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
@@ -14,15 +15,18 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
|
import com.stardust.util.IntentUtil;
|
||||||
|
|
||||||
import org.autojs.autojs.BuildConfig;
|
import org.autojs.autojs.BuildConfig;
|
||||||
import org.autojs.autojs.R;
|
import org.autojs.autojs.R;
|
||||||
|
import org.autojs.autojs.network.download.DownloadManager;
|
||||||
import org.autojs.autojs.network.entity.VersionInfo;
|
import org.autojs.autojs.network.entity.VersionInfo;
|
||||||
import org.autojs.autojs.storage.file.StorageFileProvider;
|
import org.autojs.autojs.storage.file.StorageFileProvider;
|
||||||
import org.autojs.autojs.tool.IntentTool;
|
import org.autojs.autojs.tool.IntentTool;
|
||||||
import com.stardust.util.DownloadTask;
|
|
||||||
import com.stardust.util.IntentUtil;
|
|
||||||
import org.autojs.autojs.ui.widget.CommonMarkdownView;
|
import org.autojs.autojs.ui.widget.CommonMarkdownView;
|
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on 2017/4/9.
|
* Created by Stardust on 2017/4/9.
|
||||||
*/
|
*/
|
||||||
@@ -103,44 +107,26 @@ public class UpdateInfoDialogBuilder extends MaterialDialog.Builder {
|
|||||||
}
|
}
|
||||||
Button button = (Button) View.inflate(getContext(), R.layout.dialog_update_info_btn, null);
|
Button button = (Button) View.inflate(getContext(), R.layout.dialog_update_info_btn, null);
|
||||||
button.setText(R.string.text_directly_download);
|
button.setText(R.string.text_directly_download);
|
||||||
button.setOnClickListener(new View.OnClickListener() {
|
button.setOnClickListener(v -> directlyDownload(info.downloadUrl));
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
directlyDownload(info.downloadUrl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
container.addView(button);
|
container.addView(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
private void directlyDownload(String downloadUrl) {
|
private void directlyDownload(String downloadUrl) {
|
||||||
final MaterialDialog dialog = new MaterialDialog.Builder(getContext())
|
|
||||||
.title(R.string.text_downloading)
|
|
||||||
.progress(false, 100)
|
|
||||||
.show();
|
|
||||||
final String path = StorageFileProvider.getDefaultDirectoryPath() + "AutoJs.apk";
|
final String path = StorageFileProvider.getDefaultDirectoryPath() + "AutoJs.apk";
|
||||||
final DownloadTask task = new DownloadTask() {
|
DownloadManager.getInstance().downloadWithProgress(getContext(), downloadUrl, path)
|
||||||
@Override
|
.subscribeOn(AndroidSchedulers.mainThread())
|
||||||
protected void onProgressUpdate(Integer... values) {
|
.subscribe(file -> IntentUtil.installApk(getContext(), file.getPath()),
|
||||||
super.onProgressUpdate(values);
|
error -> {
|
||||||
dialog.setProgress(values[0]);
|
error.printStackTrace();
|
||||||
}
|
Toast.makeText(getContext(), R.string.text_download_failed, Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
super.onPostExecute(result);
|
|
||||||
dialog.dismiss();
|
|
||||||
if (!result) {
|
|
||||||
Toast.makeText(getContext(), R.string.text_download_failed, Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
|
||||||
IntentUtil.installApk(getContext(), path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
task.execute(downloadUrl, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setReleaseNotes(View view, VersionInfo info) {
|
private void setReleaseNotes(View view, VersionInfo info) {
|
||||||
CommonMarkdownView markdownView = (CommonMarkdownView) view.findViewById(R.id.release_notes);
|
CommonMarkdownView markdownView = view.findViewById(R.id.release_notes);
|
||||||
markdownView.loadMarkdown(info.releaseNotes);
|
markdownView.loadMarkdown(info.releaseNotes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.autojs.autojs.network.VersionService;
|
|||||||
import org.autojs.autojs.network.entity.VersionInfo;
|
import org.autojs.autojs.network.entity.VersionInfo;
|
||||||
import org.autojs.autojs.tool.SimpleObserver;
|
import org.autojs.autojs.tool.SimpleObserver;
|
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.functions.Consumer;
|
import io.reactivex.functions.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +40,7 @@ public class VersionGuard {
|
|||||||
|
|
||||||
private void checkForUpdatesIfNeeded() {
|
private void checkForUpdatesIfNeeded() {
|
||||||
mVersionService.checkForUpdatesIfNeededAndUsingWifi(mActivity)
|
mVersionService.checkForUpdatesIfNeededAndUsingWifi(mActivity)
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(new SimpleObserver<VersionInfo>() {
|
.subscribe(new SimpleObserver<VersionInfo>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,23 +78,15 @@ public class VersionGuard {
|
|||||||
.negativeText(R.string.text_exit)
|
.negativeText(R.string.text_exit)
|
||||||
.cancelable(false)
|
.cancelable(false)
|
||||||
.autoDismiss(false)
|
.autoDismiss(false)
|
||||||
.onAny(new MaterialDialog.SingleButtonCallback() {
|
.onAny((dialog, which) -> {
|
||||||
@Override
|
if (which == DialogAction.POSITIVE) {
|
||||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
new UpdateCheckDialog(mActivity)
|
||||||
if (which == DialogAction.POSITIVE) {
|
.show();
|
||||||
new UpdateCheckDialog(mActivity)
|
} else {
|
||||||
.show();
|
mActivity.finish();
|
||||||
} else {
|
|
||||||
mActivity.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.dismissListener(new DialogInterface.OnDismissListener() {
|
|
||||||
@Override
|
|
||||||
public void onDismiss(DialogInterface dialog) {
|
|
||||||
mDeprecatedDialog = null;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.dismissListener(dialog -> mDeprecatedDialog = null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
@@ -15,7 +14,6 @@ import android.view.MotionEvent;
|
|||||||
|
|
||||||
import com.stardust.autojs.core.eventloop.EventEmitter;
|
import com.stardust.autojs.core.eventloop.EventEmitter;
|
||||||
import com.stardust.autojs.core.eventloop.SimpleEvent;
|
import com.stardust.autojs.core.eventloop.SimpleEvent;
|
||||||
import com.stardust.autojs.core.ui.inflater.inflaters.Exceptions;
|
|
||||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||||
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
|
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
|
||||||
import com.stardust.autojs.engine.ScriptEngine;
|
import com.stardust.autojs.engine.ScriptEngine;
|
||||||
@@ -157,6 +155,7 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
IntentExtras extras = IntentExtras.newExtras().putAll(mIntentExtras);
|
IntentExtras extras = IntentExtras.newExtras().putAll(mIntentExtras);
|
||||||
outState.putInt(IntentExtras.EXTRA_ID, extras.getId());
|
outState.putInt(IntentExtras.EXTRA_ID, extras.getId());
|
||||||
|
emit("save_instance_state", outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,12 +190,6 @@ public class ScriptExecuteActivity extends AppCompatActivity {
|
|||||||
emit("restore_instance_state", savedInstanceState);
|
emit("restore_instance_state", savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
|
|
||||||
super.onSaveInstanceState(outState, outPersistentState);
|
|
||||||
emit("save_instance_state", outState, outPersistentState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
SimpleEvent e = new SimpleEvent();
|
SimpleEvent e = new SimpleEvent();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
import com.stardust.pio.PFiles;
|
import com.stardust.pio.PFiles;
|
||||||
import com.stardust.pio.UncheckedIOException;
|
import com.stardust.pio.UncheckedIOException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -80,7 +81,6 @@ public class ProjectConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
@@ -128,11 +128,24 @@ public class ProjectConfig {
|
|||||||
|
|
||||||
public List<String> getAssets() {
|
public List<String> getAssets() {
|
||||||
if (mAssets == null) {
|
if (mAssets == null) {
|
||||||
mAssets = new ArrayList<>();
|
mAssets = Collections.emptyList();
|
||||||
}
|
}
|
||||||
return mAssets;
|
return mAssets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean addAsset(String assetRelativePath) {
|
||||||
|
if (mAssets == null) {
|
||||||
|
mAssets = new ArrayList<>();
|
||||||
|
}
|
||||||
|
for (String asset : mAssets) {
|
||||||
|
if (new File(asset).equals(new File(assetRelativePath))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mAssets.add(assetRelativePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void setAssets(List<String> assets) {
|
public void setAssets(List<String> assets) {
|
||||||
mAssets = assets;
|
mAssets = assets;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.stardust.autojs.runtime.api;
|
package com.stardust.autojs.runtime.api;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
@@ -98,6 +100,7 @@ public class Device {
|
|||||||
@SuppressLint("HardwareIds")
|
@SuppressLint("HardwareIds")
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getIMEI() {
|
public String getIMEI() {
|
||||||
|
checkReadPhoneStatePermission();
|
||||||
try {
|
try {
|
||||||
return ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
|
return ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
@@ -105,6 +108,7 @@ public class Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint("HardwareIds")
|
@SuppressLint("HardwareIds")
|
||||||
public String getAndroidId() {
|
public String getAndroidId() {
|
||||||
return Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID);
|
return Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||||
@@ -287,6 +291,16 @@ public class Device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkReadPhoneStatePermission() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
if (mContext.checkSelfPermission(Manifest.permission.READ_PHONE_STATE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
throw new SecurityException(mContext.getString(R.string.no_read_phone_state_permissin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// just to avoid warning of null pointer to make android studio happy..
|
// just to avoid warning of null pointer to make android studio happy..
|
||||||
@NonNull
|
@NonNull
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<string name="text_requires_app_version_to_run_the_script" formatted="true">本脚本需要Auto.js版本号%d以上才能运行</string>
|
<string name="text_requires_app_version_to_run_the_script" formatted="true">本脚本需要Auto.js版本号%d以上才能运行</string>
|
||||||
<string name="text_drawer_open">打开侧拉菜单</string>
|
<string name="text_drawer_open">打开侧拉菜单</string>
|
||||||
<string name="text_drawer_close">关闭侧拉菜单</string>
|
<string name="text_drawer_close">关闭侧拉菜单</string>
|
||||||
|
<string name="no_read_phone_state_permissin">没有读取设备信息权限</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
package com.stardust.util;
|
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
|
|
||||||
import com.stardust.net.AutoHttpURLConnection;
|
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Stardust on 2017/4/10.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class DownloadTask extends AsyncTask<String, Integer, Boolean> {
|
|
||||||
|
|
||||||
public interface ProgressListener {
|
|
||||||
void publishProgress(int i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Download implements Callable<Boolean> {
|
|
||||||
|
|
||||||
private String mUrl;
|
|
||||||
private String mPath;
|
|
||||||
private ProgressListener mListener;
|
|
||||||
private volatile boolean mCanceled = false;
|
|
||||||
|
|
||||||
public Download(String url, String path, ProgressListener listener) {
|
|
||||||
mUrl = url;
|
|
||||||
mPath = path;
|
|
||||||
mListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean call() throws IOException {
|
|
||||||
try (AutoHttpURLConnection connection = new AutoHttpURLConnection(mUrl)) {
|
|
||||||
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int total = connection.getContentLength();
|
|
||||||
InputStream input = connection.getInputStream();
|
|
||||||
FileOutputStream output = new FileOutputStream(mPath);
|
|
||||||
return download(input, output, total);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancel() {
|
|
||||||
mCanceled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean download(InputStream input, FileOutputStream output, int total) throws IOException {
|
|
||||||
byte buffer[] = new byte[8192];
|
|
||||||
long downloaded = 0;
|
|
||||||
int read;
|
|
||||||
while ((read = input.read(buffer)) != -1) {
|
|
||||||
if (mCanceled) {
|
|
||||||
input.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
downloaded += read;
|
|
||||||
if (total > 0)
|
|
||||||
publishProgress((int) (downloaded * 100 / total));
|
|
||||||
output.write(buffer, 0, read);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void publishProgress(int i) {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.publishProgress(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Download mDownload;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean doInBackground(String... params) {
|
|
||||||
mDownload = new Download(params[0], params[1], new ProgressListener() {
|
|
||||||
@Override
|
|
||||||
public void publishProgress(int i) {
|
|
||||||
DownloadTask.this.publishProgress(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
return mDownload.call();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
mDownload = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCancelled() {
|
|
||||||
super.onCancelled();
|
|
||||||
if (mDownload != null)
|
|
||||||
mDownload.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -86,6 +86,7 @@ public class IntentUtil {
|
|||||||
|
|
||||||
public static void installApk(Context context, String path) {
|
public static void installApk(Context context, String path) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
|
||||||
intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
|
intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
|
|||||||
15
version.json
15
version.json
@@ -1,12 +1,15 @@
|
|||||||
{
|
{
|
||||||
"versionCode": 404,
|
"versionCode": 163,
|
||||||
"versionName": "4.0.1 Beta",
|
"versionName": "2.0.16 Beta2",
|
||||||
"releaseNotes": "* 全新的文档、界面\n* 更丰富的功能\n期待您的体验~",
|
"releaseNotes": "* 优化root录制,录制脚本接近完美,可自行录制游戏脚本\n* 提高部分脚本的运行速度\n* 新增 按键事件、通知事件监听\n*修复 一些问题",
|
||||||
"downloadUrl": "http://i.autojs.org/autojs/release-4.0.1Beta.apk",
|
|
||||||
"downloads" : [
|
"downloads" : [
|
||||||
{
|
{
|
||||||
"name": "酷安",
|
"name": "应用宝",
|
||||||
"url": "https://www.coolapk.com/apk/188448"
|
"url": "http://a.app.qq.com/o/simple.jsp?pkgname=org.autojs.autojs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "百度手机助手",
|
||||||
|
"url": "http://shouji.baidu.com/software/22060055.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"oldVersions": [
|
"oldVersions": [
|
||||||
|
|||||||
Reference in New Issue
Block a user