# Conflicts:
#	autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/SpinnerInflater.java
This commit is contained in:
hyb1996
2018-09-07 09:01:16 +08:00
16 changed files with 581 additions and 65 deletions

Binary file not shown.

View File

@@ -8,8 +8,8 @@ android {
applicationId "org.autojs.autojs" applicationId "org.autojs.autojs"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 23 targetSdkVersion 23
versionCode 403 versionCode 406
versionName "4.0.2 Alpha" versionName "4.0.2 Alpha2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
ndk { ndk {

View File

@@ -54,7 +54,7 @@ public class FloatyWindowManger {
} }
public static boolean showCircularMenu() { public static boolean showCircularMenu() {
if (!SettingsCompat.canDrawOverlays(GlobalAppContext.get())) { if (!FloatingPermission.canDrawOverlays(GlobalAppContext.get())) {
Toast.makeText(GlobalAppContext.get(), R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show(); Toast.makeText(GlobalAppContext.get(), R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
manageDrawOverlays(GlobalAppContext.get()); manageDrawOverlays(GlobalAppContext.get());
return false; return false;

View File

@@ -1,14 +0,0 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"program": "${file}"
}
]
}

View File

@@ -72,21 +72,12 @@ runtime.init();
Image = com.stardust.autojs.core.image.ImageWrapper; Image = com.stardust.autojs.core.image.ImageWrapper;
//重定向require以便支持相对路径 //重定向require以便支持相对路径
(function(){ (function(){
var __require__ = require; var loadAssets = function(path){
var builtInModules = ["lodash.js"]; eval(files.readAssets(path));
global.require = function(path){ }
if(!path.endsWith(".js")){ loadAssets("jvm-npm.js");
path = path + ".js";
}
if(builtInModules.indexOf(path) >= 0 && !files.exists(path)){
return __require__(path);
}
if(path.startsWith("http://") || path.startsWith("https://")){
return __require__(path);
}
return __require__(files.path(path));
};
})(); })();

View File

@@ -0,0 +1,294 @@
/**
* Copyright 2014-2016 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Since we intend to use the Function constructor.
/* jshint evil: true */
module = (typeof module === 'undefined') ? {} : module;
(function () {
var builtInModules = ["lodash.js"];
var System = java.lang.System;
var Scanner = java.util.Scanner;
var File = java.io.File;
NativeRequire = (typeof NativeRequire === 'undefined') ? {} : NativeRequire;
if (typeof require === 'function' && !NativeRequire.require) {
NativeRequire.require = require;
}
function Module (id, parent, core) {
this.id = id;
this.core = core;
this.parent = parent;
this.children = [];
this.filename = id;
this.loaded = false;
Object.defineProperty(this, 'exports', {
get: function () {
return this._exports;
}.bind(this),
set: function (val) {
Require.cache[this.filename] = val;
this._exports = val;
}.bind(this)
});
this.exports = {};
if (parent && parent.children) parent.children.push(this);
this.require = function (id) {
return Require(id, this);
}.bind(this);
}
Module._load = function _load (file, parent, core, main) {
var module = new Module(file, parent, core);
var body = readFile(module.filename, module.core);
var dir = new File(module.filename).getParent();
var func = new Function('exports', 'module', 'require', '__filename', '__dirname', body);
func.apply(module,
[module.exports, module, module.require, module.filename, dir]);
module.loaded = true;
module.main = main;
return module.exports;
};
Module.runMain = function runMain (main) {
var file = Require.resolve(main);
Module._load(file, undefined, false, true);
};
function Require (id, parent) {
var normalizePath = normalizeName(id);
if(builtInModules.indexOf(normalizePath) >= 0 && !files.exists(normalizePath)){
return NativeRequire.require(normalizePath);
}
if(id.startsWith("http://") || id.startsWith("https://")){
return NativeRequire.require(id);
}
var core;
var native_;
var file = Require.resolve(id, parent);
if (!file) {
if (typeof NativeRequire.require === 'function') {
if (Require.debug) {
System.out.println(['Cannot resolve', id, 'defaulting to native'].join(' '));
}
native_ = NativeRequire.require(id);
if (native_) return native_;
}
System.err.println('Cannot find module ' + id);
throw new ModuleError('Cannot find module ' + id, 'MODULE_NOT_FOUND');
}
if (file.core) {
file = file.path;
core = true;
}
try {
if (Require.cache[file]) {
return Require.cache[file];
} else if (file.endsWith('.js')) {
return Module._load(file, parent, core);
} else if (file.endsWith('.json')) {
return loadJSON(file);
}
} catch (ex) {
if (ex instanceof java.lang.Exception) {
throw new ModuleError('Cannot load module ' + id, 'LOAD_ERROR', ex);
} else {
System.out.println('Cannot load module ' + id + ' LOAD_ERROR');
throw ex;
}
}
}
Require.resolve = function (id, parent) {
var roots = findRoots(parent);
for (var i = 0; i < roots.length; ++i) {
var root = roots[i];
var result = resolveCoreModule(id, root) ||
resolveAsFile(id, root, '.js') ||
resolveAsFile(id, root, '.json') ||
resolveAsDirectory(id, root) ||
resolveAsNodeModule(id, root);
if (result) {
return result;
}
}
return false;
};
Require.root = files.cwd();//System.getProperty('user.dir');
Require.NODE_PATH = undefined;
function findRoots (parent) {
var r = [];
r.push(findRoot(parent));
return r.concat(Require.paths());
}
function parsePaths (paths) {
if (!paths) {
return [];
}
if (paths === '') {
return [];
}
var osName = java.lang.System.getProperty('os.name').toLowerCase();
var separator;
if (osName.indexOf('win') >= 0) {
separator = ';';
} else {
separator = ':';
}
return paths.split(separator);
}
Require.paths = function () {
var r = [];
r.push(java.lang.System.getProperty('user.home') + '/.node_modules');
r.push(java.lang.System.getProperty('user.home') + '/.node_libraries');
if (Require.NODE_PATH) {
r = r.concat(parsePaths(Require.NODE_PATH));
} else {
var NODE_PATH = java.lang.System.getenv().NODE_PATH;
if (NODE_PATH) {
r = r.concat(parsePaths(NODE_PATH));
}
}
// r.push( $PREFIX + "/node/library" )
return r;
};
function findRoot (parent) {
if (!parent || !parent.id) { return Require.root; }
var pathParts = parent.id.split(/[\/|\\,]+/g);
pathParts.pop();
return pathParts.join('/');
}
Require.debug = true;
Require.cache = {};
Require.extensions = {};
require = Require;
module.exports = Module;
function loadJSON (file) {
var json = JSON.parse(readFile(file));
Require.cache[file] = json;
return json;
}
function resolveAsNodeModule (id, root) {
var base = [root, 'node_modules'].join('/');
return resolveAsFile(id, base) ||
resolveAsDirectory(id, base) ||
(root ? resolveAsNodeModule(id, new File(root).getParent()) : false);
}
function resolveAsDirectory (id, root) {
var base = [root, id].join('/');
var file = new File([base, 'package.json'].join('/'));
if (file.exists()) {
try {
var body = readFile(file.getCanonicalPath());
var package_ = JSON.parse(body);
if (package_.main) {
return (resolveAsFile(package_.main, base) ||
resolveAsDirectory(package_.main, base));
}
// if no package.main exists, look for index.js
return resolveAsFile('index.js', base);
} catch (ex) {
throw new ModuleError('Cannot load JSON file', 'PARSE_ERROR', ex);
}
}
return resolveAsFile('index.js', base);
}
function resolveAsFile (id, root, ext) {
var file;
if (id.length > 0 && id[0] === '/') {
file = new File(normalizeName(id, ext));
if (!file.exists()) {
return resolveAsDirectory(id);
}
} else {
file = new File([root, normalizeName(id, ext)].join('/'));
}
if (file.exists()) {
return file.getCanonicalPath();
}
}
function resolveCoreModule (id, root) {
var name = normalizeName(id);
var classloader = java.lang.Thread.currentThread().getContextClassLoader();
if (classloader.getResource(name)) {
return { path: name, core: true };
}
}
function normalizeName (fileName, ext) {
var extension = ext || '.js';
if (fileName.endsWith(extension)) {
return fileName;
}
return fileName + extension;
}
function readFile (filename, core) {
var input;
try {
if (core) {
var classloader = java.lang.Thread.currentThread().getContextClassLoader();
input = classloader.getResourceAsStream(filename);
} else {
input = new File(filename);
}
// TODO: I think this is not very efficient
return new Scanner(input).useDelimiter('\\A').next();
} catch (e) {
throw new ModuleError('Cannot read file [' + input + ']: ', 'IO_ERROR', e);
}
}
function ModuleError (message, code, cause) {
this.code = code || 'UNDEFINED';
this.message = message || 'Error loading module';
this.cause = cause;
}
// Helper function until ECMAScript 6 is complete
if (typeof String.prototype.endsWith !== 'function') {
String.prototype.endsWith = function (suffix) {
if (!suffix) return false;
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
ModuleError.prototype = new Error();
ModuleError.prototype.constructor = ModuleError;
}());

View File

@@ -10,6 +10,7 @@ import com.stardust.autojs.annotation.ScriptInterface;
import com.stardust.autojs.runtime.api.AbstractConsole; import com.stardust.autojs.runtime.api.AbstractConsole;
import com.stardust.autojs.runtime.api.Console; import com.stardust.autojs.runtime.api.Console;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException; import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.util.FloatingPermission;
import com.stardust.concurrent.ConcurrentArrayList; import com.stardust.concurrent.ConcurrentArrayList;
import com.stardust.enhancedfloaty.FloatyService; import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow; import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow;
@@ -151,8 +152,8 @@ public class StardustConsole extends AbstractConsole {
if (mShown) { if (mShown) {
return; return;
} }
if (!SettingsCompat.canDrawOverlays(mUiHandler.getContext())) { if (!FloatingPermission.canDrawOverlays(mUiHandler.getContext())) {
SettingsCompat.manageDrawOverlays(mUiHandler.getContext()); FloatingPermission.manageDrawOverlays(mUiHandler.getContext());
mUiHandler.toast(R.string.text_no_floating_window_permission); mUiHandler.toast(R.string.text_no_floating_window_permission);
return; return;
} }

View File

@@ -38,6 +38,7 @@ import com.stardust.autojs.core.ui.inflater.inflaters.TimePickerInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.ToolbarInflater; import com.stardust.autojs.core.ui.inflater.inflaters.ToolbarInflater;
import com.stardust.autojs.core.ui.inflater.inflaters.ViewGroupInflater; import com.stardust.autojs.core.ui.inflater.inflaters.ViewGroupInflater;
import com.stardust.autojs.core.ui.inflater.util.Res; import com.stardust.autojs.core.ui.inflater.util.Res;
import com.stardust.autojs.core.ui.widget.JsSpinner;
import com.stardust.autojs.core.ui.widget.JsTabLayout; import com.stardust.autojs.core.ui.widget.JsTabLayout;
import com.stardust.autojs.core.ui.widget.JsToolbar; import com.stardust.autojs.core.ui.widget.JsToolbar;
import com.stardust.autojs.core.ui.xml.XmlConverter; import com.stardust.autojs.core.ui.xml.XmlConverter;
@@ -126,7 +127,7 @@ public class DynamicLayoutInflater {
registerViewAttrSetter(DatePicker.class.getName(), new DatePickerInflater(mResourceParser)); registerViewAttrSetter(DatePicker.class.getName(), new DatePickerInflater(mResourceParser));
registerViewAttrSetter(RadioGroup.class.getName(), new RadioGroupInflater<>(mResourceParser)); registerViewAttrSetter(RadioGroup.class.getName(), new RadioGroupInflater<>(mResourceParser));
registerViewAttrSetter(ProgressBar.class.getName(), new ProgressBarInflater<>(mResourceParser)); registerViewAttrSetter(ProgressBar.class.getName(), new ProgressBarInflater<>(mResourceParser));
registerViewAttrSetter(Spinner.class.getName(), new SpinnerInflater(mResourceParser)); registerViewAttrSetter(JsSpinner.class.getName(), new SpinnerInflater(mResourceParser));
registerViewAttrSetter(TimePicker.class.getName(), new TimePickerInflater(mResourceParser)); registerViewAttrSetter(TimePicker.class.getName(), new TimePickerInflater(mResourceParser));
registerViewAttrSetter(AppBarLayout.class.getName(), new AppBarInflater<>(mResourceParser)); registerViewAttrSetter(AppBarLayout.class.getName(), new AppBarInflater<>(mResourceParser));
registerViewAttrSetter(JsTabLayout.class.getName(), new TabLayoutInflater<>(mResourceParser)); registerViewAttrSetter(JsTabLayout.class.getName(), new TabLayoutInflater<>(mResourceParser));

View File

@@ -2,17 +2,22 @@ package com.stardust.autojs.core.ui.inflater.inflaters;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.TypedValue;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.SimpleAdapter; import android.widget.SimpleAdapter;
import android.widget.Spinner; import android.widget.Spinner;
import com.stardust.autojs.R;
import com.stardust.autojs.core.ui.inflater.ResourceParser; import com.stardust.autojs.core.ui.inflater.ResourceParser;
import com.stardust.autojs.core.ui.inflater.ViewCreator; import com.stardust.autojs.core.ui.inflater.ViewCreator;
import com.stardust.autojs.core.ui.inflater.util.Colors;
import com.stardust.autojs.core.ui.inflater.util.Dimensions; import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Strings; import com.stardust.autojs.core.ui.inflater.util.Strings;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper; import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
import com.stardust.autojs.core.ui.widget.JsSpinner;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -21,7 +26,7 @@ import java.util.Map;
* Created by Stardust on 2017/11/29. * Created by Stardust on 2017/11/29.
*/ */
public class SpinnerInflater extends BaseViewInflater<Spinner> { public class SpinnerInflater extends BaseViewInflater<JsSpinner> {
protected static final ValueMapper<Integer> SPINNER_MODES = new ValueMapper<Integer>("spinnerMode") protected static final ValueMapper<Integer> SPINNER_MODES = new ValueMapper<Integer>("spinnerMode")
.map("dialog", Spinner.MODE_DIALOG) .map("dialog", Spinner.MODE_DIALOG)
@@ -32,38 +37,48 @@ public class SpinnerInflater extends BaseViewInflater<Spinner> {
} }
@Override @Override
public boolean setAttr(Spinner view, String attr, String value, ViewGroup parent, Map<String, String> attrs) { public boolean setAttr(JsSpinner view, String attr, String value, ViewGroup parent, Map<String, String> attrs) {
switch (attr) { switch (attr) {
case "dropDownHorizontalOffset": case "dropDownHorizontalOffset":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { view.setDropDownHorizontalOffset(Dimensions.parseToIntPixel(value, view));
view.setDropDownHorizontalOffset(Dimensions.parseToIntPixel(value, view));
}
break; break;
case "dropDownSelector": case "dropDownSelector":
Exceptions.unsupports(view, attr, value); Exceptions.unsupports(view, attr, value);
break; break;
case "dropDownVerticalOffset": case "dropDownVerticalOffset":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { view.setDropDownVerticalOffset(Dimensions.parseToIntPixel(value, view));
view.setDropDownVerticalOffset(Dimensions.parseToIntPixel(value, view));
}
break; break;
case "dropDownWidth": case "dropDownWidth":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { view.setDropDownWidth(Dimensions.parseToIntPixel(value, view));
view.setDropDownWidth(Dimensions.parseToIntPixel(value, view));
}
break; break;
case "popupBackground": case "popupBackground":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { view.setPopupBackgroundDrawable(getDrawables().parse(view, value));
view.setPopupBackgroundDrawable(getDrawables().parse(view, value));
}
break; break;
case "prompt": case "prompt":
view.setPrompt(Strings.parse(view, value)); view.setPrompt(Strings.parse(view, value));
break; break;
case "entries": case "entries":
view.setAdapter(new ArrayAdapter<>(view.getContext(), view.setAdapter(view.new Adapter(view.getContext(),
android.R.layout.simple_spinner_dropdown_item, value.split("[|]"))); android.R.layout.simple_spinner_dropdown_item, value.split("[|]")));
break; break;
case "textStyle":
view.setTextStyle(TextViewInflater.TEXT_STYLES.split(value));
break;
case "textColor":
view.setTextColor(Colors.parse(view.getContext(), value));
break;
case "textSize":
view.setTextSize(Dimensions.parseToPixel(value, view));
break;
case "entryTextStyle":
view.setEntryTextStyle(TextViewInflater.TEXT_STYLES.split(value));
break;
case "entryTextColor":
view.setEntryTextColor(Colors.parse(view.getContext(), value));
break;
case "entryTextSize":
view.setEntryTextSize(Dimensions.parseToPixel(value, view));
break;
default: default:
return super.setAttr(view, attr, value, parent, attrs); return super.setAttr(view, attr, value, parent, attrs);
} }
@@ -76,16 +91,11 @@ public class SpinnerInflater extends BaseViewInflater<Spinner> {
return (context, attrs) -> { return (context, attrs) -> {
String mode = attrs.remove("android:spinnerMode"); String mode = attrs.remove("android:spinnerMode");
if (mode == null) { if (mode == null) {
return new Spinner(context); return new JsSpinner(context);
} }
return new Spinner(context, SPINNER_MODES.get(mode)); return new JsSpinner(context, SPINNER_MODES.get(mode));
}; };
} }
private static class EntryAdapter extends SimpleAdapter {
public EntryAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}
}
} }

View File

@@ -1,6 +1,5 @@
package com.stardust.autojs.core.ui.inflater.inflaters; package com.stardust.autojs.core.ui.inflater.inflaters;
import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Color; import android.graphics.Color;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@@ -15,7 +14,6 @@ import com.stardust.autojs.core.ui.inflater.util.Colors;
import com.stardust.autojs.core.ui.inflater.util.Dimensions; import com.stardust.autojs.core.ui.inflater.util.Dimensions;
import com.stardust.autojs.core.ui.inflater.util.Gravities; import com.stardust.autojs.core.ui.inflater.util.Gravities;
import com.stardust.autojs.core.ui.inflater.util.ValueMapper; import com.stardust.autojs.core.ui.inflater.util.ValueMapper;
import com.stardust.autojs.core.ui.widget.JsTabLayout;
import java.util.Map; import java.util.Map;

View File

@@ -98,7 +98,7 @@ public class TextViewInflater<V extends TextView> extends BaseViewInflater<V> {
.map("number", InputType.TYPE_CLASS_NUMBER) .map("number", InputType.TYPE_CLASS_NUMBER)
.map("signed", InputType.TYPE_NUMBER_FLAG_SIGNED); .map("signed", InputType.TYPE_NUMBER_FLAG_SIGNED);
private static final ValueMapper<Integer> TEXT_STYLES = new ValueMapper<Integer>("textStyle") static final ValueMapper<Integer> TEXT_STYLES = new ValueMapper<Integer>("textStyle")
.map("bold", Typeface.BOLD) .map("bold", Typeface.BOLD)
.map("italic", Typeface.ITALIC) .map("italic", Typeface.ITALIC)
.map("normal", Typeface.NORMAL); .map("normal", Typeface.NORMAL);

View File

@@ -0,0 +1,163 @@
package com.stardust.autojs.core.ui.widget;
import android.content.Context;
import android.content.res.Resources;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class JsSpinner extends android.support.v7.widget.AppCompatSpinner {
private float mTextSize = -1;
private int mTextStyle = -1;
private int mTextColor = 0;
private float mEntryTextSize = -1;
private int mEntryTextStyle = -1;
private int mEntryTextColor = 0;
public JsSpinner(Context context) {
super(context);
}
public JsSpinner(Context context, int mode) {
super(context, mode);
}
public JsSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public JsSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public JsSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode) {
super(context, attrs, defStyleAttr, mode);
}
public JsSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode, Resources.Theme popupTheme) {
super(context, attrs, defStyleAttr, mode, popupTheme);
}
public float getTextSize() {
return mTextSize;
}
public float getEntryTextSize() {
return mEntryTextSize;
}
public void setEntryTextSize(float entryTextSize) {
mEntryTextSize = entryTextSize;
}
public int getEntryTextStyle() {
return mEntryTextStyle;
}
public void setEntryTextStyle(int entryTextStyle) {
mEntryTextStyle = entryTextStyle;
}
public int getEntryTextColor() {
return mEntryTextColor;
}
public void setEntryTextColor(int entryTextColor) {
mEntryTextColor = entryTextColor;
}
public void setTextSize(float textSize) {
mTextSize = textSize;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof TextView) {
((TextView) child).setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
}
}
}
public int getTextStyle() {
return mTextStyle;
}
public void setTextStyle(int textStyle) {
mTextStyle = textStyle;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof TextView) {
((TextView) child).setTypeface(((TextView) child).getTypeface(), mTextStyle);
}
}
}
public int getTextColor() {
return mTextColor;
}
public void setTextColor(int textColor) {
mTextColor = textColor;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof TextView) {
((TextView) child).setTextColor(mTextColor);
}
}
}
public class Adapter extends ArrayAdapter<String> {
public Adapter(@NonNull Context context, int resource, @NonNull String[] objects) {
super(context, resource, objects);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (!(view instanceof TextView)) {
return view;
}
TextView textView = (TextView) view;
if (mTextColor != 0) {
textView.setTextColor(mTextColor);
}
if (mTextSize != -1) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
}
if (mTextStyle != -1) {
textView.setTypeface(textView.getTypeface(), mTextStyle);
}
return textView;
}
@Override
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View view = super.getDropDownView(position, convertView, parent);
if (!(view instanceof TextView)) {
return view;
}
TextView textView = (TextView) view;
if (mEntryTextColor != 0) {
textView.setTextColor(mEntryTextColor);
}
if (mEntryTextSize != -1) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mEntryTextSize);
}
if (mEntryTextStyle != -1) {
textView.setTypeface(textView.getTypeface(), mEntryTextStyle);
}
return textView;
}
}
}

View File

@@ -25,6 +25,7 @@ import com.stardust.autojs.core.ui.widget.JsImageView;
import com.stardust.autojs.core.ui.widget.JsLinearLayout; import com.stardust.autojs.core.ui.widget.JsLinearLayout;
import com.stardust.autojs.core.ui.widget.JsListView; import com.stardust.autojs.core.ui.widget.JsListView;
import com.stardust.autojs.core.ui.widget.JsRelativeLayout; import com.stardust.autojs.core.ui.widget.JsRelativeLayout;
import com.stardust.autojs.core.ui.widget.JsSpinner;
import com.stardust.autojs.core.ui.widget.JsTabLayout; import com.stardust.autojs.core.ui.widget.JsTabLayout;
import com.stardust.autojs.core.ui.widget.JsTextView; import com.stardust.autojs.core.ui.widget.JsTextView;
import com.stardust.autojs.core.ui.widget.JsToolbar; import com.stardust.autojs.core.ui.widget.JsToolbar;
@@ -68,7 +69,7 @@ public class XmlConverter {
.map("webview", JsWebView.class.getName()) .map("webview", JsWebView.class.getName())
.map("progressbar", ProgressBar.class.getName()) .map("progressbar", ProgressBar.class.getName())
.map("seekbar", SeekBar.class.getName()) .map("seekbar", SeekBar.class.getName())
.map("spinner", Spinner.class.getName()) .map("spinner", JsSpinner.class.getName())
.map("radio", RadioButton.class.getName()) .map("radio", RadioButton.class.getName())
.map("radiogroup", RadioGroup.class.getName()) .map("radiogroup", RadioGroup.class.getName())
.map("checkbox", CheckBox.class.getName()) .map("checkbox", CheckBox.class.getName())

View File

@@ -4,9 +4,11 @@ import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.pio.PFileInterface; import com.stardust.pio.PFileInterface;
import com.stardust.pio.PFiles; import com.stardust.pio.PFiles;
import com.stardust.pio.UncheckedIOException;
import com.stardust.util.Func1; import com.stardust.util.Func1;
import java.io.File; import java.io.File;
import java.io.IOException;
/** /**
* Created by Stardust on 2018/1/23. * Created by Stardust on 2018/1/23.
@@ -82,10 +84,23 @@ public class Files {
return PFiles.read(path(path), encoding); return PFiles.read(path(path), encoding);
} }
public String read(String path) { public String read(String path) {
return PFiles.read(path(path)); return PFiles.read(path(path));
} }
public String readAssets(String path, String encoding){
try {
return PFiles.read(mRuntime.getUiHandler().getContext().getAssets().open(path), encoding);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public String readAssets(String path){
return readAssets(path, "UTF-8");
}
public byte[] readBytes(String path){ public byte[] readBytes(String path){
return PFiles.readBytes(path(path)); return PFiles.readBytes(path(path));
} }
@@ -185,4 +200,5 @@ public class Files {
public String getSimplifiedPath(String path) { public String getSimplifiedPath(String path) {
return PFiles.getSimplifiedPath(path); return PFiles.getSimplifiedPath(path);
} }
} }

View File

@@ -1,8 +1,14 @@
package com.stardust.autojs.util; package com.stardust.autojs.util;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.widget.Toast; import android.widget.Toast;
import com.stardust.R; import com.stardust.R;
@@ -10,6 +16,11 @@ import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.enhancedfloaty.util.FloatingWindowPermissionUtil; import com.stardust.enhancedfloaty.util.FloatingWindowPermissionUtil;
import com.stardust.lang.ThreadCompat; import com.stardust.lang.ThreadCompat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import ezy.assist.compat.RomUtil;
import ezy.assist.compat.SettingsCompat; import ezy.assist.compat.SettingsCompat;
/** /**
@@ -19,8 +30,20 @@ import ezy.assist.compat.SettingsCompat;
public class FloatingPermission { public class FloatingPermission {
private static final int OP_SYSTEM_ALERT_WINDOW = 24;
private static Method sCheckOp;
static {
try {
sCheckOp = SettingsCompat.class.getDeclaredMethod("checkOp", Context.class, int.class);
sCheckOp.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void ensurePermissionGranted(Context context) { public static void ensurePermissionGranted(Context context) {
if (!SettingsCompat.canDrawOverlays(context)) { if (!canDrawOverlays(context)) {
Toast.makeText(context, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show(); Toast.makeText(context, R.string.text_no_floating_window_permission, Toast.LENGTH_SHORT).show();
manageDrawOverlays(context); manageDrawOverlays(context);
return; return;
@@ -28,7 +51,7 @@ public class FloatingPermission {
} }
public static void waitForPermissionGranted(Context context) throws InterruptedException { public static void waitForPermissionGranted(Context context) throws InterruptedException {
if (SettingsCompat.canDrawOverlays(context)) { if (canDrawOverlays(context)) {
return; return;
} }
Runnable r = () -> { Runnable r = () -> {
@@ -41,7 +64,7 @@ public class FloatingPermission {
r.run(); r.run();
} }
while (true) { while (true) {
if (SettingsCompat.canDrawOverlays(context)) if (canDrawOverlays(context))
return; return;
Thread.sleep(200); Thread.sleep(200);
} }
@@ -51,11 +74,42 @@ public class FloatingPermission {
public static void manageDrawOverlays(Context context) { public static void manageDrawOverlays(Context context) {
try { try {
SettingsCompat.manageDrawOverlays(context); if (RomUtil.isMiui() && TextUtils.equals("V10", RomUtil.getVersion())
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manageDrawOverlaysForAndroidM(context);
} else {
SettingsCompat.manageDrawOverlays(context);
}
} catch (Exception ex) { } catch (Exception ex) {
FloatingWindowPermissionUtil.goToAppDetailSettings(context, context.getPackageName()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manageDrawOverlaysForAndroidM(context);
} else {
FloatingWindowPermissionUtil.goToAppDetailSettings(context, context.getPackageName());
}
} }
} }
@RequiresApi(api = Build.VERSION_CODES.M)
public static void manageDrawOverlaysForAndroidM(Context context) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
public static boolean canDrawOverlays(Context context) {
return SettingsCompat.canDrawOverlays(context);
}
private static boolean checkOp(Context context, int op) {
if (sCheckOp == null) {
return SettingsCompat.canDrawOverlays(context);
}
try {
return (boolean) sCheckOp.invoke(null, context, op);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
} }

View File

@@ -84,6 +84,7 @@ public class IntentUtil {
return goToAppDetailSettings(context, context.getPackageName()); return goToAppDetailSettings(context, context.getPackageName());
} }
// FIXME: 2018/7/11 Permission denial
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);