What i do:
public interface ApiInterface { @Multipart @POST("/android/upload/index.php") Observable<Response> postImage(@Part MultipartBody.Part image, @Part("name") RequestBody name); } Model:
public interface Model { Observable<Response> postImage(MultipartBody.Part image, RequestBody name); } Impl:
public class ModelImpl implements Model { ApiModule apiModule = ApiModule.getInstance(); @Override public Observable<Response> postImage(MultipartBody.Part image, RequestBody name) { return apiModule.getApi().postImage(image,name); } } Presenter:
RxPhoto.requestUri(context, TypeRequest.GALLERY) .flatMap(new Func1<Uri, Observable<Response>>() { @Override public Observable<Response> call(Uri uri) { File file = new File(uri.getPath()); RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile); RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test"); return model.postImage(body, name); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<Response>() { @Override public void onError(Throwable e) { Log.d(tag, "error:" + e); } }); I have error:
error:java.lang.IllegalArgumentException: Unable to create call adapter for rx.Observable for method ApiInterface.postImage
UPD:
I change interface and others to :
Observable<uploadAnswer> public class uploadAnswer { @SerializedName("success") @Expose private String success; public String getSuccess() { return this.success; } } after that my first error gone, now i have this error:
java.io.FileNotFoundException: /document/image:52214: open failed: ENOENT (No such file or directory)
What to do?
UPD2:
I use this function to get file uri:
public String getRealPathFromURIPath(Uri contentURI) { Cursor cursor = context.getApplicationContext().getContentResolver().query(contentURI, null, null, null, null); if (cursor == null) { return contentURI.getPath(); } else { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); return cursor.getString(idx); } } After that i have this error (is it mean, that i'm right ?? ):
error:android.os.NetworkOnMainThreadException
UPD3:
My short code:
RxPhoto.requestUri(context,TypeRequest.GALLERY) .observeOn(AndroidSchedulers.mainThread()) .doOnNext(new Action1<Uri>(){ @Override public void call(Uri uri) { Log.d(tag, "up => " + uri); File file = new File(uri.getPath()); RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile); RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test"); //model.postImage(body, name); GetDataSubscription = model.postImage(body,name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(); } }) .subscribe(); I still have errors:
E/AndroidRuntime: FATAL EXCEPTION: main Process: info.masterskaya.om.near, PID: 8348 java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add onError handling. at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.OnErrorNotImplementedException: Unable to create call adapter for rx.Observable for method ApiInterface.postImage at rx.Observable$26.onError(Observable.java:8524) at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157) at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) at rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:71) at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:189) at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:215) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) ... 9 more Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for rx.Observable for method ApiInterface.postImage at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:695) at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:233) at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:159) at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166) at retrofit2.Retrofit$1.invoke(Retrofit.java:145) at $Proxy0.postImage(Native Method) at info.masterskaya.om.near.mvp.model.ModelImpl.postImage(ModelImpl.java:53) at info.masterskaya.om.near.mvp.presenter.PresenterImpl$1.call(PresenterImpl.java:133) at info.masterskaya.om.near.mvp.presenter.PresenterImpl$1.call(PresenterImpl.java:119) at rx.Observable$11.onNext(Observable.java:4820) at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:80) ... 11 more Caused by: java.lang.IllegalStateException: Response must be parameterized as Response or Response at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory.getCallAdapter(RxJavaCallAdapterFactory.java:119) at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory.get(RxJavaCallAdapterFactory.java:105) at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:217) at retrofit2.Retrofit.callAdapter(Retrofit.java:201) at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:231) ... 20 more Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: android.net.Uri$HierarchicalUri.class at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:189) at rx.internal.operators.OperatorDoOnEach$1.onNext(OperatorDoOnEach.java:82) ... 11 more
if i change my interface to:
@Multipart @POST("/upload/index.php") Observable<String> postImage(@Part MultipartBody.Part image, @Part("name") RequestBody name); I have this trace:
*E/AndroidRuntime: FATAL EXCEPTION: main Process: info.masterskaya.om.near, PID: 8618 java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add onError
UPD4:
I have some results.
Interface:
@Multipart @POST("/upload/index.php") Observable<Void> postImage(@Part MultipartBody.Part image, @Part("name") RequestBody name); Main function:
RxPhoto.requestUri(context,TypeRequest.GALLERY) .observeOn(AndroidSchedulers.mainThread()) .doOnNext(new Action1<Uri>(){ @Override public void call(Uri uri) { Log.d(tag, "up => " + uri); Log.d(tag, "getPath => " + getPath(context,uri)); String URL = getPath(context,uri); File file = new File( URL+"" ); RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile); RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test"); GetDataSubscription = model.postImage(body,name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(); } }) .subscribe(); /~~~~~~~/
getPath(context,uri) i find HERE
Now i have server error:
12-09 05:37:55.760 10230-10372/* D/OkHttp: --857d62de-296c-4d23-8683-92b3b340a658 12-09 05:37:55.760 10230-10372/ D/OkHttp: Content-Disposition: form-data; name="upload"; filename="IMG_20161206_092257.jpg" 12-09 05:37:55.760 10230-10372/ D/OkHttp: Content-Type: multipart/form-data 12-09 05:37:55.760 10230-10372/* D/OkHttp: Content-Length: 26188
...
12-09 05:37:55.770 10230-10372/* D/OkHttp: --857d62de-296c-4d23-8683-92b3b340a658 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Disposition: form-data; name="name" 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Transfer-Encoding: binary 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Type: multipart/form-data; charset=utf-8 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Length: 11 12-09 05:37:55.770 10230-10372/ D/OkHttp: upload_test 12-09 05:37:55.770 10230-10372/ D/OkHttp: --857d62de-296c-4d23-8683-92b3b340a658-- 12-09 05:37:55.770 10230-10372/ D/OkHttp: --> END POST (26620-byte body) 12-09 05:37:55.800 10230-10334/ D/GoogleCertificatesImpl: Fetched 363 Google certificates 12-09 05:37:56.340 10230-10230/ I/Choreographer: Skipped 42 frames! The application may be doing too much work on its main thread. 12-09 05:37:56.390 10230-10372/ D/OkHttp: <-- 200 OK http://www./upload/index.php (604ms) 12-09 05:37:56.390 10230-10372/ D/OkHttp: Date: Fri, 09 Dec 2016 10:37:56 GMT 12-09 05:37:56.390 10230-10372/ D/OkHttp: Server: Apache 12-09 05:37:56.390 10230-10372/ D/OkHttp: Vary: Accept-Encoding 12-09 05:37:56.390 10230-10372/ D/OkHttp: Content-Type: text/html; charset=UTF-8 12-09 05:37:56.390 10230-10372/ D/OkHttp: X-Cache: MISS from t7..ru 12-09 05:37:56.390 10230-10372/ D/OkHttp: X-Cache-Lookup: MISS from t7..ru:6666 12-09 05:37:56.390 10230-10372/ D/OkHttp: Connection: keep-alive 12-09 05:37:56.390 10230-10372/ D/OkHttp: OkHttp-Sent-Millis: 1481279876016 12-09 05:37:56.390 10230-10372/ D/OkHttp: OkHttp-Received-Millis: 1481279876396 12-09 05:37:56.390 10230-10372/* D/OkHttp: {"result": "fail"} 12-09 05:37:56.390 10230-10372/*** D/OkHttp: <-- END HTTP (18-byte body)
Server:
<?php $file_path = "up/"; $file_path = $file_path . basename( $_FILES['uploaded_file']['name']); if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path) ){ echo '{"result": "success"}'; } else{ echo '{"result": "fail"}'; } ?> UPD5:
I done this f*cking upload!
php test code:
<?php error_reporting(E_ALL); ini_set('display_errors', 1); define('ROOT_DIR', dirname(__FILE__)); $file_path = ROOT_DIR . ""; $file_path = $file_path . basename( $_FILES['upload']['name']); if(move_uploaded_file($_FILES['upload']['tmp_name'], $file_path) ){ echo '{"result": "success"}'; } else{ echo '{"result": "fail"}'; } ?> All my problems was with right uri on device. Try API 16,19 and 24 all successfull