diff --git a/.gitignore b/.gitignore index c41efc45a..6176cc099 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,25 @@ -# Gradle -build/ -.gradle +# built application files +*.apk +*.ap_ + +# files for the dex VM +*.dex + +# Java class files +*.class -#Java -.class +# generated files +bin/ +gen/ -#Android -.apk -.dex +# Local configuration file (sdk path, etc) +local.properties + +# Eclipse project files +.classpath +.project +.settings + +# Gradle +.gradle +build/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 725fdac18..42a67eb09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,4 +32,5 @@ before_script: - adb shell input keyevent 82 & script: - - ./gradlew build + #- ./gradlew build + - ./gradlew connectedInstrumentTest diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 212678a98..fd17e6719 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -18,7 +18,13 @@ - + + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 5410a93c4..227392d89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ ## CHANGE LOG + +### v6.0.3 +2014-07-11 issue [#49](https://github.com/qiniu/android-sdk/pull/49) + +- [#45] block count 计数修正 +- [#47] file Uri 修正 +- [#48] 调整上传默认为upload.qiniu.com + ### v6.0.2 2014-04-15 issue [#43](https://github.com/qiniu/android-sdk/pull/43) diff --git a/build.gradle b/build.gradle index 0a0000a2f..50ac05585 100644 --- a/build.gradle +++ b/build.gradle @@ -25,9 +25,18 @@ android { } instrumentTest.setRoot('tests') + instrumentTest { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['tests/src'] + res.srcDirs = ['res'] + assets.srcDirs = ['assets'] + resources.srcDirs = ['tests/src'] + } + } dependencies { compile fileTree(dir: 'libs', include: '*.jar') } } +// if don't find sdk, please set the local.properties \ No newline at end of file diff --git a/src/com/qiniu/conf/Conf.java b/src/com/qiniu/conf/Conf.java index 46f31c7b0..e5cb9cf3b 100644 --- a/src/com/qiniu/conf/Conf.java +++ b/src/com/qiniu/conf/Conf.java @@ -2,5 +2,5 @@ public class Conf { public static final String USER_AGENT = "qiniu android-sdk v6.0.0"; - public static final String UP_HOST = "http://up.qiniu.com"; + public static final String UP_HOST = "http://upload.qiniu.com"; } diff --git a/src/com/qiniu/io/IO.java b/src/com/qiniu/io/IO.java index 506279dc4..ce035016e 100644 --- a/src/com/qiniu/io/IO.java +++ b/src/com/qiniu/io/IO.java @@ -94,18 +94,15 @@ public void onFailure(Exception ex) { */ public void putFile(Context mContext, String key, Uri uri, PutExtra extra, final JSONObjectRet ret) { if (!uri.toString().startsWith("file")) uri = convertFileUri(mContext, uri); - try { - File file = new File(new URI(uri.toString())); - if (file.exists()) { - putAndClose(key, InputStreamAt.fromFile(file), extra, ret); - return; - } - ret.onFailure(new Exception("file not exist: " + uri.toString())); - } catch (URISyntaxException e) { - e.printStackTrace(); - ret.onFailure(e); + + File file = new File(uri.getEncodedPath()); + if (file.exists()) { + putAndClose(key, InputStreamAt.fromFile(file), extra, ret); + return; } + ret.onFailure(new Exception("file not exist: " + uri.toString())); } + public void putFile(String key, File file, PutExtra extra, JSONObjectRet callback) { putAndClose(key, InputStreamAt.fromFile(file), extra, callback); } diff --git a/src/com/qiniu/resumableio/ResumableIO.java b/src/com/qiniu/resumableio/ResumableIO.java index e9564e840..4b4eb2902 100644 --- a/src/com/qiniu/resumableio/ResumableIO.java +++ b/src/com/qiniu/resumableio/ResumableIO.java @@ -63,7 +63,7 @@ public void onFailure(Exception ex) { } public int put(final String key, final InputStreamAt input, final PutExtra extra, final JSONObjectRet ret) { - final int blkCount = (int) (input.length() / BLOCK_SIZE) + 1; + final int blkCount = (int) ((input.length() + BLOCK_SIZE - 1) / BLOCK_SIZE); if (extra.processes == null) extra.processes = new PutRet[blkCount]; extra.totalSize = input.length(); final int[] success = new int[] {0}; @@ -149,14 +149,13 @@ public int putFile(String key, File file, PutExtra extra, final JSONObjectRet re public int putFile(Context mContext, String key, Uri uri, PutExtra extra, final JSONObjectRet ret) { if (!uri.toString().startsWith("file")) uri = convertFileUri(mContext, uri); - try { - File file = new File(new URI(uri.toString())); - if (file.exists()) return putAndClose(key, InputStreamAt.fromFile(file), extra, ret); - ret.onFailure(new Exception("file not exist: " + uri.toString())); - } catch (URISyntaxException e) { - e.printStackTrace(); - ret.onFailure(e); + + File file = new File(uri.getEncodedPath()); + if (file.exists()) { + return putAndClose(key, InputStreamAt.fromFile(file), extra, ret); } + ret.onFailure(new Exception("file not exist: " + uri.toString())); + return -1; } diff --git a/tests/src/com/qiniu/test/UploadTest.java b/tests/src/com/qiniu/test/UploadTest.java new file mode 100644 index 000000000..a09704055 --- /dev/null +++ b/tests/src/com/qiniu/test/UploadTest.java @@ -0,0 +1,193 @@ +package com.qiniu.test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.UUID; + +import junit.framework.Assert; + +import org.json.JSONException; +import org.json.JSONObject; + +import com.qiniu.auth.JSONObjectRet; +import com.qiniu.io.IO; +import com.qiniu.resumableio.ResumableIO; + +import android.content.Context; +import android.net.Uri; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +public class UploadTest extends AndroidTestCase { + private String uptoken = "anEC5u_72gw1kZPSy3Dsq1lo_DPXyvuPDaj4ePkN:zmaikrTu1lgLb8DTvKQbuFZ5ai0=:eyJzY29wZSI6ImFuZHJvaWRzZGsiLCJyZXR1cm5Cb2R5Ijoie1wiaGFzaFwiOlwiJChldGFnKVwiLFwia2V5XCI6XCIkKGtleSlcIixcImZuYW1lXCI6XCIgJChmbmFtZSkgXCIsXCJmc2l6ZVwiOlwiJChmc2l6ZSlcIixcIm1pbWVUeXBlXCI6XCIkKG1pbWVUeXBlKVwiLFwieDphXCI6XCIkKHg6YSlcIn0iLCJkZWFkbGluZSI6MTQ2NjIyMjcwMX0="; + + private File file; + + private boolean uploading; + private boolean success; + private JSONObjectRet jsonRet; + private JSONObject resp; + private Exception e; + + private Context context; + private Uri uri; + private com.qiniu.io.PutExtra extra; + private String key = IO.UNDEFINED_KEY; + + private com.qiniu.resumableio.PutExtra rextra; + + public void setUp() throws Exception { + key = UUID.randomUUID().toString(); + uploading = true; + success = false; + + extra = new com.qiniu.io.PutExtra(); + extra.params = new HashMap(); + extra.params.put("x:a", "测试中文 信息"); + + rextra = new com.qiniu.resumableio.PutExtra(); + rextra.params = new HashMap(); + rextra.params.put("x:a", "测试中文 信息"); + + context = this.getContext(); + jsonRet = new JSONObjectRet() { + @Override + public void onProcess(long current, long total) { + //Log.d("UploadTest", current + "/" + total); + // Assert.assertEquals(file.length(), total); // 内部实现原因,可能不相等 + } + + @Override + public void onSuccess(JSONObject res) { + uploading = false; + success = true; + resp = res; + Log.d("UploadTest", "上传成功! " + resp.toString()); + System.out.println("上传成功! " + resp.toString()); + } + + @Override + public void onFailure(Exception ex) { + uploading = false; + success = false; + e = ex; + Log.d("UploadTest", "上传失败! " + ex.getMessage()); + System.out.println("上传失败! " + ex.getMessage()); + } + }; + } + + + public void tearDown() throws Exception { + if(file != null){ + file.delete(); + } + } + + @SmallTest + public void testS() throws IOException, JSONException { + file = createFile(0.2, ".test"); + uri = Uri.fromFile(file); + IO.putFile(context, uptoken, key, uri, extra, jsonRet); + sleepLimit(60); + successCheck(); + } + + @MediumTest + public void testM() throws IOException, JSONException { + file = createFile(4, "--—— 地 方.test"); + uri = Uri.fromFile(file); + IO.putFile(context, uptoken, key, uri, extra, jsonRet); + sleepLimit(60 * 5); + successCheck(); + } + + @SmallTest + public void testRS() throws IOException, JSONException { + file = createFile(0.2, ".test"); + uri = Uri.fromFile(file); + ResumableIO.putFile(context, uptoken, key, uri, rextra, jsonRet); + sleepLimit(60); + successCheck(); + } + + @MediumTest + public void testRM() throws IOException, JSONException { + file = createFile(4, ".test"); + uri = Uri.fromFile(file); + ResumableIO.putFile(context, uptoken, key, uri, rextra, jsonRet); + sleepLimit(60 * 5); + successCheck(); + } + + @MediumTest + public void testRL() throws IOException, JSONException { + file = createFile(8.6, ".test"); + uri = Uri.fromFile(file); + ResumableIO.putFile(context, uptoken, key, uri, rextra, jsonRet); + sleepLimit(60 * 5); + successCheck(); + } + + + private void successCheck() throws JSONException{ + Assert.assertTrue(success); + Assert.assertNotNull(resp.optString("hash")); + Assert.assertEquals(file.length(), resp.getLong("fsize")); + } + + private void sleepLimit(int limit){ + int t = 5; + while(uploading && t < limit){ + try { + t += 5; + Thread.sleep(1000 * 5); + } catch (InterruptedException e) { + + } + } + } + + private File createFile(double fileSize, String suf) throws IOException { + FileOutputStream fos = null; + try{ + long size = (long)(1024 * 1024 * fileSize); + File f = File.createTempFile("qiniu_", suf); + f.createNewFile(); + fos = new FileOutputStream(f); + byte [] b = getByte(); + long s = 0; + while(s < size){ + int l = (int)Math.min(b.length, size - s); + fos.write(b, 0, l); + s += l; + } + fos.flush(); + return f; + }finally{ + if(fos != null){ + try { + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + private byte[] getByte(){ + byte [] b = new byte[1024 * 4]; + b[0] = 'A'; + for(int i=1; i < 1024 * 4 ; i++){ + b[i] = 'b'; + } + b[1024 * 4 - 2] = '\r'; + b[1024 * 4 - 1] = '\n'; + return b; + } + +} \ No newline at end of file