1.导入依赖
//Retrofit 核心库
implementation("com.squareup.retrofit2:retrofit:2.9.0")
//响应数据自动序列化
//JSON
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
//String类型
implementation("com.squareup.retrofit2:converter-scalars:2.9.0")
//拦截器 logging
implementation("com.squareup.okhttp3:logging-interceptor:3.14.+")
2.需要配置清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.OkHttp"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:authorities="${applicationId}.provider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>
3.网络权限和 provider
provider_paths.xml
<?xml version="1.0" encoding="utf-8" ?>
<paths>
<external-path
name="aaa"
path="."/>
</paths>
network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
4.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/upload"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="上传图片"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
5.ApiService
package com.tiger.retrofel.api;
import java.util.List;
import java.util.Map;
import okhttp3.MultipartBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.Query;
public interface ApiService {
@POST("findList")
@FormUrlEncoded
Call<Map<String,Object>> test(
@Field("start") Integer start,
@Field("count") Integer count
);
@POST("uploadPic")
@Multipart
Call<Map<String,Object>> upload(
@Part MultipartBody.Part part
);
}
6.权限工具类
package com.tiger.retrofel;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class PermissionUtil {
public static final String[] PERMISSIONS_EXTERNAL_STORAGE = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static final int PERMISSIONS_EXTERNAL_STORAGE_TAG = 1;
//检查多个权限。返回true表示已完全启用权限,返回false 表示 未完全启用权限
public static boolean checkPermission(Activity act, String[] permissions, int requestCode) {
//Android 6.0之后开始采用动态权限管理
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int check = PackageManager.PERMISSION_GRANTED;
for (String permission : permissions) {
check = ContextCompat.checkSelfPermission(act, permission);
if (check != PackageManager.PERMISSION_GRANTED) {
break;
}
}
//未开启该权限,则请求系统弹窗,好让用户选择 是否立即开启权限
if (check != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(act, permissions, requestCode);
return false;
}
}
return true;
}
public static boolean checkGrant(int[] grantResults) {
if (grantResults != null) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
} else {
return false;
}
}
}
7.Activity
package com.tiger.retrofel;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.tiger.retrofel.api.ApiService;
import com.tiger.retrofel.api.Subject;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
public class MainActivity extends AppCompatActivity {
Retrofit retrofit;
private OkHttpClient client;
private ApiService apiService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i("TAG", message);
}
}).setLevel(HttpLoggingInterceptor.Level.BASIC);
client = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build();
retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.202.55:8999/")
.client(client)
// .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
Button viewById = findViewById(R.id.upload);
viewById.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showPhoto();
}
});
syncRequest();
}
//同步的请求
private void syncRequest() {
//同步
new Thread(() -> {
Response<Map<String,Object>> execute = null;
try {
execute = apiService.test(0, 2).execute();
} catch (IOException e) {
throw new RuntimeException(e);
}
Map<String,Object> body = execute.body();
Log.i("ning", "run:response:" + body);
}).start();
}
//异步的请求
private void ayncRequest() {
//同步
try {
apiService.test(0, 2).enqueue(new Callback<Map<String,Object>>() {
@Override
public void onResponse(Call<Map<String,Object>> call, Response<Map<String,Object>> response) {
}
@Override
public void onFailure(Call<Map<String,Object>> call, Throwable t) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void showPhoto() {
if (PermissionUtil.checkPermission(this, PermissionUtil.PERMISSIONS_EXTERNAL_STORAGE, PermissionUtil.PERMISSIONS_EXTERNAL_STORAGE_TAG)) {
//有权限
// 跳转到系统相册,选择图片,并返回
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,1);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Log.d("ning","进来了"+resultCode+":"+resultCode);
//获取图片路径
if (requestCode==1 && resultCode == Activity.RESULT_OK &&data!=null){
Uri selectedImage = data.getData();
String[] filePathColumns ={MediaStore.Images.Media.DATA};
Cursor query = getContentResolver().query(selectedImage, filePathColumns, null, null, null);
query.moveToFirst();
int columnIndex = query.getColumnIndex(filePathColumns[0]);
String string = query.getString(columnIndex);
Log.d("ning",string);
uploadFile(string);
query.close();
}
}
public void uploadFile(String path){
File file = new File(path);
RequestBody requestBody = RequestBody.create(MediaType.parse("image/jp"),file);
MultipartBody.Part part = MultipartBody.Part.createFormData("pic",file.getName(),requestBody);
apiService.upload(part).enqueue(new Callback<Map<String, Object>>() {
@Override
public void onResponse(Call<Map<String, Object>> call, Response<Map<String, Object>> response) {
Log.d("ning",response.body().get("result").toString());
}
@Override
public void onFailure(Call<Map<String, Object>> call, Throwable t) {
}
});
}
}
8.实体类
public class Subject {
private String episodes_info;
private String rate;
private Integer cover_x;
private String title;
private String url;
private Boolean playable;
private String cover;
private String id;
private Integer cover_y;
private Boolean is_new;