diff --git a/app/src/main/assets/sample/HTTP网络请求/文件上传.js b/app/src/main/assets/sample/HTTP网络请求/文件上传.js new file mode 100644 index 00000000..f08289f9 --- /dev/null +++ b/app/src/main/assets/sample/HTTP网络请求/文件上传.js @@ -0,0 +1,41 @@ +//如果遇到SocketTimeout的异常,重新多运行几次脚本即可 + +console.show(); +example1(); +example2(); +example3(); +example4(); +example5(); + +function example1(){ + var res = http.postMultipart("http://posttestserver.com/post.php", { + "file": open("/sdcard/1.txt") + }); + log("例子1:"); + log(res.body.string()); +} + +function example2(){ + var res = http.postMultipart("http://posttestserver.com/post.php", { + "file": ["1.txt", "/sdcard/1.txt"] + }); + log("例子2:"); + log(res.body.string()); +} + +function example3(){ + var res = http.postMultipart("http://posttestserver.com/post.php", { + "file": ["1.txt", "text/plain", "/sdcard/1.txt"] + }); + log("例子3:"); + log(res.body.string()); +} + +function example4(){ + var res = http.postMultipart("http://posttestserver.com/post.php", { + "file": open("/sdcard/1.txt"), + "aKey": "aValue" + }); + log("例子4:"); + log(res.body.string()); +} \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index c0dc1608..d1765b89 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -31,8 +31,13 @@ import com.stardust.util.UiHandler; import org.autojs.dynamiclayoutinflater.ImageLoader; import org.autojs.dynamiclayoutinflater.util.Drawables; +import java.io.File; import java.lang.ref.WeakReference; +import okhttp3.Headers; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; + /** * Created by Stardust on 2017/1/27. */ @@ -71,8 +76,8 @@ public class App extends MultiDexApplication { return; } LeakCanary.install(this); - //if (!BuildConfig.DEBUG) - Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class)); + if (!BuildConfig.DEBUG) + Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class)); } private void init() { diff --git a/autojs/build.gradle b/autojs/build.gradle index 6ca9c70f..863837a6 100644 --- a/autojs/build.gradle +++ b/autojs/build.gradle @@ -51,6 +51,8 @@ dependencies { compile 'com.github.hyb1996:EnhancedFloaty:0.17' compile 'com.github.hyb1996:OpenCvLib:2.4.13.4-imgproc' compile 'com.makeramen:roundedimageview:2.3.0' + // OkHttp + compile 'com.squareup.okhttp3:okhttp:3.9.0' //JDeferred compile 'org.jdeferred:jdeferred-android-aar:1.2.6' diff --git a/autojs/src/androidTest/java/com/stardust/autojs/ExampleInstrumentedTest.java b/autojs/src/androidTest/java/com/stardust/autojs/ExampleInstrumentedTest.java index 0a71cea4..4ad83ee2 100644 --- a/autojs/src/androidTest/java/com/stardust/autojs/ExampleInstrumentedTest.java +++ b/autojs/src/androidTest/java/com/stardust/autojs/ExampleInstrumentedTest.java @@ -7,6 +7,16 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.io.File; +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + import static org.junit.Assert.assertEquals; /** @@ -18,9 +28,6 @@ import static org.junit.Assert.assertEquals; public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - assertEquals("com.stardust.autojs.test", appContext.getPackageName()); } } diff --git a/autojs/src/main/assets/modules/__http__.js b/autojs/src/main/assets/modules/__http__.js index 2d56fed5..c7afac9e 100644 --- a/autojs/src/main/assets/modules/__http__.js +++ b/autojs/src/main/assets/modules/__http__.js @@ -30,6 +30,14 @@ module.exports = function(runtime, scope){ return http.post(url, data, options, callback); } + http.postMultipart = function(url, files, options, callback){ + options = options || {}; + options.method = "POST"; + options.contentType = "multipart/form-data"; + options.files = files; + return http.request(url, options, callback); + } + http.request = function(url, options, callback){ var call = http.client().newCall(http.buildRequest(url, options)); if(!callback){ @@ -56,12 +64,53 @@ module.exports = function(runtime, scope){ } if(options.body){ r.method(options.method, parseBody(options, options.body)); - }else{ + }else if(options.files){ + r.method(options.method, parseMultipart(options.files)); + }else { r.method(options.method, null); } return r.build(); } + function parseMultipart(files){ + var builder = new MultipartBody.Builder() + .setType(MultipartBody.FORM); + for(var key in files){ + if(!files.hasOwnProperty(key)){ + continue; + } + var value = files[key]; + if(typeof(value) == 'string'){ + builder.addFormDataPart(key, value); + continue; + } + var path, mimeType, fileName; + if(typeof(value.getPath) == 'function'){ + path = value.getPath(); + }else if(value.length == 2){ + fileName = value[0]; + path = value[1]; + }else if(value.length >= 3){ + fileName = value[0]; + mimeType = value[1] + path = value[2]; + } + var file = new com.stardust.pio.PFile(path); + fileName = fileName || file.getName(); + mimeType = mimeType || parseMimeType(file.getExtension()); + builder.addFormDataPart(key, fileName, RequestBody.create(MediaType.parse(mimeType), file)); + } + return builder.build(); + } + + function parseMimeType(ext){ + if(ext.length == 0){ + return "application/octet-stream"; + } + return android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext) + || "application/octet-stream"; + } + function fillPostData(options, data){ if(options.contentType == "application/x-www-form-urlencoded"){ var b = new FormBody.Builder(); @@ -89,6 +138,8 @@ module.exports = function(runtime, scope){ function parseBody(options, body){ if(typeof(body) == "string"){ body = RequestBody.create(MediaType.parse(options.contentType), body); + }else if(body instanceof RequestBody){ + return body; }else{ body = new RequestBody({ contentType: function(){ diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java index 7f3224eb..648c915d 100644 --- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java +++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java @@ -51,6 +51,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine { mAndroidContext = context; mContext = createContext(); mScriptable = createScope(mContext); + } @Override diff --git a/autojs/src/test/java/com/stardust/autojs/ExampleUnitTest.java b/autojs/src/test/java/com/stardust/autojs/ExampleUnitTest.java index 5d8c23ee..4cca63a9 100644 --- a/autojs/src/test/java/com/stardust/autojs/ExampleUnitTest.java +++ b/autojs/src/test/java/com/stardust/autojs/ExampleUnitTest.java @@ -1,7 +1,21 @@ package com.stardust.autojs; +import android.webkit.MimeTypeMap; + +import com.stardust.pio.PFiles; + import org.junit.Test; +import java.io.File; +import java.io.IOException; + +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + /** * Example local unit test, which will execute on the development machine (host). * @@ -11,8 +25,21 @@ public class ExampleUnitTest { @Test - public void test() { - + public void test() throws IOException { + MimeTypeMap.getSingleton().getMimeTypeFromExtension(); + File file = new File("C:\\Users\\Stardust\\Desktop\\1.txt"); + System.out.println(PFiles.read(file)); + String url = "http://posttestserver.com/post.php?dir=example"; + OkHttpClient client = new OkHttpClient(); + RequestBody formBody = new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("file", file.getName(), + RequestBody.create(MediaType.parse("text/plain"), file)) + .addFormDataPart("other_field", "other_field_value") + .build(); + Request request = new Request.Builder().url(url).post(formBody).build(); + Response response = client.newCall(request).execute(); + System.out.println(response.body().string()); } public boolean equals(int i, int j) { diff --git a/common/src/main/java/com/stardust/pio/PFileInterface.java b/common/src/main/java/com/stardust/pio/PFileInterface.java new file mode 100644 index 00000000..6fe6ba95 --- /dev/null +++ b/common/src/main/java/com/stardust/pio/PFileInterface.java @@ -0,0 +1,9 @@ +package com.stardust.pio; + +/** + * Created by Stardust on 2017/12/5. + */ + +public interface PFileInterface { + String getPath(); +} diff --git a/common/src/main/java/com/stardust/pio/PFiles.java b/common/src/main/java/com/stardust/pio/PFiles.java index 88c9d633..17a40abb 100644 --- a/common/src/main/java/com/stardust/pio/PFiles.java +++ b/common/src/main/java/com/stardust/pio/PFiles.java @@ -31,7 +31,7 @@ public class PFiles { static final int DEFAULT_BUFFER_SIZE = 8192; static final String DEFAULT_ENCODING = Charset.defaultCharset().name(); - public static Object open(String path, String mode, String encoding, int bufferSize) { + public static PFileInterface open(String path, String mode, String encoding, int bufferSize) { switch (mode) { case "r": return new PReadableTextFile(path, encoding, bufferSize); diff --git a/common/src/main/java/com/stardust/pio/PReadableTextFile.java b/common/src/main/java/com/stardust/pio/PReadableTextFile.java index 549c49f9..935d4ac1 100644 --- a/common/src/main/java/com/stardust/pio/PReadableTextFile.java +++ b/common/src/main/java/com/stardust/pio/PReadableTextFile.java @@ -8,12 +8,13 @@ import java.util.List; * Created by Stardust on 2017/4/1. */ -public class PReadableTextFile implements Closeable { +public class PReadableTextFile implements Closeable, PFileInterface { private BufferedReader mBufferedReader; private FileInputStream mFileInputStream; private int mBufferingSize; private String mEncoding; + private String mPath; public PReadableTextFile(String path) { this(path, PFiles.DEFAULT_ENCODING); @@ -26,6 +27,7 @@ public class PReadableTextFile implements Closeable { public PReadableTextFile(String path, String encoding, int bufferingSize) { mEncoding = encoding; mBufferingSize = bufferingSize; + mPath = path; try { mFileInputStream = new FileInputStream(path); } catch (FileNotFoundException e) { @@ -103,4 +105,9 @@ public class PReadableTextFile implements Closeable { throw new UncheckedIOException(e); } } + + @Override + public String getPath() { + return mPath; + } } diff --git a/common/src/main/java/com/stardust/pio/PWritableTextFile.java b/common/src/main/java/com/stardust/pio/PWritableTextFile.java index a7208f1a..6db5919e 100644 --- a/common/src/main/java/com/stardust/pio/PWritableTextFile.java +++ b/common/src/main/java/com/stardust/pio/PWritableTextFile.java @@ -16,7 +16,7 @@ import static com.stardust.pio.PFiles.DEFAULT_BUFFER_SIZE; * Created by Stardust on 2017/4/1. */ -public class PWritableTextFile implements Closeable { +public class PWritableTextFile implements Closeable, PFileInterface { public static PWritableTextFile open(String path, String encoding, int bufferSize) { return new PWritableTextFile(path, encoding, bufferSize, false); @@ -35,8 +35,10 @@ public class PWritableTextFile implements Closeable { } private BufferedWriter mBufferedWriter; + private String mPath; public PWritableTextFile(String path, String encoding, int bufferingSize, boolean append) { + mPath = path; if (bufferingSize <= 0) { bufferingSize = DEFAULT_BUFFER_SIZE; } @@ -116,4 +118,8 @@ public class PWritableTextFile implements Closeable { } + @Override + public String getPath() { + return mPath; + } }