今天和大家分享一个okhttp网络请求的实战案例,欢迎新手学生,大佬指点,话不多说直接上干货。
我是直接手动添加的架包,手动导入,记住一定要导入。添加依赖也可以哈,看个人爱好(要架包的私信或者留言,留邮箱,或者什么我发给你们)
然后在添加依赖:(允许我装个x用rxjava2了,加载图片用的是glide,支持多张上传图片)
implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.google.code.gson:gson:2.8.5'
最重要的一步来了,记住了 添加网络权限:
!--相机权限-->
<uses-permission android:name="android.permission.CAMERA" />
<!--读文件权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--使用特性-->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
配置的都差不多准备完成了开始干代码吧:用rxjava接口是要有的:
public interface MyNetWorkCallback<T> {
void onSuccess(T t);
void onError(int errorCode, String errorMsg);
}
继续在上:
public interface IHttp {
<T> void get(String url, MyNetWorkCallback<T> callback);
<T> void get(String url, Map<String, String> params, MyNetWorkCallback<T> callback);
<T> void get(String url, Map<String, String> params, Map<String, String> headers, MyNetWorkCallback<T> callback);
<T> void post(String url, Map<String, String> params, MyNetWorkCallback<T> callback);
<T> void postraw(String url, String params, MyNetWorkCallback<T> callback);
<T> void postrawfile(String url, File file, MyNetWorkCallback<T> callback);
void upload(String url, String path, Map<String, String> params, String fileType, MediaType MEDIA_TYPE, final MyNetWorkCallback<String> callback);
<T> void download(String url,MyNetWorkCallback<String> callback);
void loadImage(String url, ImageView imageView);
}
这个类干啥来的忘记了,场时间不用了,但是也写山了,你们可以不用
public class HttpFactroy {
public static IHttp create(){
return OkHttpUtils.getInstance();
}
}
主要的类来了,单例走起:
public class OkHttpUtils implements IHttp {
private OkHttpClient okHttpClient;
//构造函数私有化
private OkHttpUtils() {
okHttpClient = new OkHttpClient.Builder().build();
}
private static OkHttpUtils okHttpUtils;
//提供一个公共的、静态的、返回值类型是当前本类的对象
public static OkHttpUtils getInstance() {
if (okHttpUtils == null) {
synchronized (OkHttpUtils.class) {
if (okHttpUtils == null) {
okHttpUtils = new OkHttpUtils();
}
}
}
return okHttpUtils;
}
private ProgressDialog progressDialog;
@Override
public <T> void get(String url, MyNetWorkCallback<T> callback) {
}
/**
* 上传多张图片及参数
*
* @param reqUrl URL地址
* @param paramssa 参数
* @param pic_key 上传图片的关键字
* @return
*/
public Observable<String> sendMultipart(final String reqUrl, final Map<String, String> paramssa, final String pic_key, final List<File> filessa) {
return Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
multipartBodyBuilder.setType(MultipartBody.FORM);
//遍历map中所有参数到builder
if (paramssa != null) {
for (String key : paramssa.keySet()) {
multipartBodyBuilder.addFormDataPart(key, paramssa.get(key));
}
}
//遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key
if (filessa != null) {
for (File file : filessa) {
multipartBodyBuilder.addFormDataPart(pic_key, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
}
}
//构建请求体
RequestBody requestBody = multipartBodyBuilder.build();
Request.Builder RequestBuilder = new Request.Builder();
RequestBuilder.url(reqUrl);// 添加URL地址
RequestBuilder.post(requestBody);
Request request = RequestBuilder.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
emitter.onError(e);
emitter.onComplete();
call.cancel();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
emitter.onNext(str);
emitter.onComplete();
call.cancel();
}
});
}
});
}
/**
* 发送get请求
*
* @param url 请求地址
* @param params 请求参数
* @param callback 回调
* @param <T> 请求回来的数据对应的JavaBean
*/
@Override
public <T> void get(String url, Map<String, String> params, final MyNetWorkCallback<T> callback) {
StringBuffer sb = new StringBuffer(url);
if (params != null && params.size() > 0) {
sb.append("?");
Set<String> keys = params.keySet();
for (String key : keys) {
String value = params.get(key);
sb.append(key).append("=").append(value).append("&");
}
url = sb.deleteCharAt(sb.length() - 1).toString();
}
Request request = new Request.Builder().url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onError(404, e.getMessage().toString());
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String jsonData = response.body().string();
//执行在子线程中
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onSuccess(getGeneric(jsonData, callback));
}
});
}
});
}
@Override
public <T> void get(String url, Map<String, String> params, Map<String, String> headers, final MyNetWorkCallback<T> callback) {
StringBuffer sb = new StringBuffer(url);
if (params != null && params.size() > 0) {
sb.append("?");
Set<String> keys = params.keySet();
for (String key : keys) {
String value = params.get(key);
sb.append(key).append("=").append(value).append("&");
}
url = sb.deleteCharAt(sb.length() - 1).toString();
}
Request.Builder builder = new Request.Builder();
if (headers != null && headers.size() > 0) {
Set<String> keys = headers.keySet();
for (String key : keys) {
String value = headers.get(key);
builder.addHeader(key, value);
}
}
Request request = builder.url(url).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onError(404, e.getMessage().toString());
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String jsonData = response.body().string();
//执行在子线程中
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onSuccess(getGeneric(jsonData, callback));
}
});
}
});
}
/**
* post方法上传表单
*
* @param url
* @param params
* @param callback
* @param <T>
*/
@Override
public <T> void post(String url, Map<String, String> params, final MyNetWorkCallback<T> callback) {
FormBody.Builder builder = new FormBody.Builder();
if (params != null && params.size() > 0) {
Set<String> keys = params.keySet();
for (String key : keys) {
String value = params.get(key);
builder.add(key, value);
}
}
Request request = new Request.Builder().url(url).post(builder.build()).build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onError(404, e.getMessage().toString());
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String jsonData = response.body().string();
//执行在子线程中
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onSuccess((T) jsonData);
}
});
}
});
}
/**
* post方法上传raw表单
*
* @param url
* @param postBody
* @param callback
* @param <T>
*/
@Override
public <T> void postraw(String url, String postBody, MyNetWorkCallback<T> callback) {
MediaType MEDIA_TYPE_TEXT = MediaType.parse("application/json; charset=utf-8");
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(MEDIA_TYPE_TEXT, postBody))
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onError(404, e.getMessage().toString());
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String jsonData = response.body().string();
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onSuccess((T) jsonData);
}
});
}
});
}
/**
* post方法上传raw文件
*
* @param url
* @param file
* @param callback
* @param <T>
*/
@Override
public <T> void postrawfile(String url, File file, MyNetWorkCallback<T> callback) {
final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onError(404, e.getMessage().toString());
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String jsonData = response.body().string();
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onSuccess((T) jsonData);
}
});
}
});
}
@Override
public void upload(String url, String path, Map<String, String> params, String fileType, MediaType MEDIA_TYPE, final MyNetWorkCallback<String> callback) {
File file = new File(path);
MultipartBody.Builder multiRequestBody = new MultipartBody.Builder();
if (params != null && params.size() > 0) {
Set<String> keys = params.keySet();
for (String key : keys) {
String value = params.get(key);
multiRequestBody.setType(MultipartBody.FORM)
.addFormDataPart(key, value);// 提交普通字段
}
}
// 上传文件使用MultipartBody.Builder
RequestBody requestBody = multiRequestBody
.setType(MultipartBody.FORM)
.addFormDataPart(fileType, file.getName(), RequestBody.create(MEDIA_TYPE, file)) // 提交图片,第一个参数是键(name="第一个参数"),第二个参数是文件名,第三个是一个RequestBody
.build();
// POST请求
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onError(404, e.getMessage().toString());
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String upLoadResult = response.body().string();
//执行在子线程中
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
//执行在主线程
callback.onSuccess(upLoadResult);
}
});
}
});
}
private boolean xiazaipanduan=true;
//下载apk以及安装
@Override
public <T> void download(String url, final MyNetWorkCallback<String> callback) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
Request request = new Request.Builder().url(url).build();
OkHttpClient okHttpClient = new OkHttpClient();
xiazaipanduan=true;
progressDialog = new ProgressDialog(App.context); //进度条,在下载的时候实时更新进度,提高用户友好度
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setTitle("正在下载");
progressDialog.setMessage("请稍候...");
progressDialog.setProgress(0);
//点击意外不消失
progressDialog.setCanceledOnTouchOutside(false);
//这是取消后即使下载完成也不安装,取消网络请求
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
progressDialog.dismiss();
xiazaipanduan=false;
okHttpClient.newCall(request).cancel();
}
});
progressDialog.show();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
callback.onError(110, "请求失败,下载失败");
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;//输入流
FileOutputStream fos = null;//输出流
try {
is = response.body().byteStream();//获取输入流
long total = response.body().contentLength();//获取文件大小
Log.e("下载文件长度为", total + "");
setMax(total);//为progressDialog设置大小
if (is != null) {
Log.d("下载数据", "onResponse: 不为空");
File file = new File(Environment.getExternalStorageDirectory(), "qianyan.apk");// 设置路径
fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int ch = -1;
int process = 0;
while ((ch = is.read(buf)) != -1) {
fos.write(buf, 0, ch);
process += ch;
downLoading(process); //这里就是关键的实时更新进度了!
}
}
fos.flush();
// 下载完成
if (fos != null) {
fos.close();
}
// downSuccess();
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
if(xiazaipanduan){
callback.onSuccess("下载完成");
}
}
});
} catch (Exception e) {
downFial();
Log.d("SettingPresenter", e.toString());
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
try {
if (fos != null)
fos.close();
} catch (IOException e) {
}
}
}
});
} else {
Toast.makeText(App.context, "SD卡不可用,请插入SD卡", Toast.LENGTH_LONG).show();
}
}
@Override
public void loadImage(String url, ImageView imageView) {
Glide.with(App.context).load(url).into(imageView);
}
/**
* 自动解析json至回调中的JavaBean
*
* @param jsonData
* @param callBack
* @param <T>
* @return
*/
private <T> T getGeneric(String jsonData, MyNetWorkCallback<T> callBack) {
Gson gson = new Gson();
//通过反射获取泛型的实例
Type[] types = callBack.getClass().getGenericInterfaces();
Type[] actualTypeArguments = ((ParameterizedType) types[0]).getActualTypeArguments();
Type type = actualTypeArguments[0];
String s = jsonData.substring(1, jsonData.length());
T t = gson.fromJson(jsonData, type);
return t;
}
//取消
public void cancel(String url, Map<String, String> params) {
FormBody.Builder builder = new FormBody.Builder();
if (params != null && params.size() > 0) {
Set<String> keys = params.keySet();
for (String key : keys) {
String value = params.get(key);
builder.add(key, value);
}
}
Request request = new Request.Builder().url(url).post(builder.build()).build();
okHttpClient.newCall(request).cancel();
}
//显示更新错误
public void showError(final String msg) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(App.context, msg, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 进度条实时更新
*
* @param i
*/
public void downLoading(final int i) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setProgress(i);
}
});
}
/**
* 下载成功
*/
public void downSuccess() {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
AlertDialog.Builder builder = new AlertDialog.Builder(App.context);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("下载完成");
builder.setMessage("是否安装");
builder.setCancelable(false);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //aandroid N的权限问题
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(App.context, "com.example.myapplication.fileprovider", new File(Environment.getExternalStorageDirectory(), "qianyan.apk"));//注意修改
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "qianyan.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
App.context.startActivity(intent);
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
});
}
/**
* 下载失败
*/
public void downFial() {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.cancel();
Toast.makeText(App.context, "更新失败", Toast.LENGTH_LONG).show();
}
});
}
public void setMax(final long total) {
App.context.runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.setMax((int) total);
}
});
}
}
你会发现很多问题哈红的什么的APP类得有吧()要不怎么检测更新呢:
public class App extends Application {
public static MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
public static MainActivity context = null;
}
准备工作都完成了,别拖延大家时间了开始使用吧:表单请求:
private Map<String, String> map = new HashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//很重要的一行,要不然你就空指针去吧
App.context = this;
}
随便写个方法看你心情吧:
map.put("currentLang", "2");
OkHttpUtils.getInstance().post(ApiUrl.HTTP_LOG, map, new MyNetWorkCallback<写自己的Bean>() {
@Override
public void onSuccess(写自己的Bean s) {
//解析
Gson gson = new Gson();
//变成实体类了自己用吧,随便用已经在子线程了随便吐司。
写自己的Bean logBean = gson.fromJson(s, 写自己的Bean.class);
Toast.makeText(MainActivity.this, "登入成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(int errorCode, String errorMsg) {
Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
}
});
要图片的吗?来了:
Map<String, String> map = new HashMap<>();
map.put("accessToken", toKen);
OkHttpUtils.getInstance().sendMultipart(path, map, "imgData", 存放图片的集合listfiles)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable throwable) {
dialog.dismiss();
Toast.makeText(ComputerRoomPatrolavtivity.this, "上传失败了", Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(String s) {
s = s.trim();
s = s.substring(1, s.length() - 1);//去除首尾双引号。
String str = s.replace("\\", "");//去除所有的\
Gson gson = new Gson();
Log.e("TAG", "str=" + str);
ToastShow.show(ComputerRoomPatrolavtivity.this, "上传成功");
} else {
dialog.dismiss();
ToastShow.show(ComputerRoomPatrolavtivity.this, "失败" + bean.getErrorMessage());
}
}
});
友情提示一下,我的张片上传之前都压缩了,这样上传比较爽。我用的是鲁班压缩可能很旧了凑合看吧
implementation 'top.zibin:Luban:1.1.3'
Luban.get(this)
.load(file) //传人要压缩的图片
.putGear(Luban.THIRD_GEAR) //设定压缩档次,默认三挡
.setCompressListener(new OnCompressListener() { //设置回调
@Override
public void onStart() {
// TODO 压缩开始前调用,可以在方法内启动 loading UI
}
@Override
public void onSuccess(File file) {
// TODO 压缩成功后调用,返回压缩后的图片文件
listFileImages.add(file);
//网络请求
httpssa(listFileImages,toKen,dataId);
}
@Override
public void onError(Throwable e) {
// TODO 当压缩过去出现问题时调用
}
}).launch();
raw上传实战使用案例:
//和map同理。和添加map一样,因为我这边约定的是健值对的json传的串。
//为什么不用form-data,问后台把我也不清楚,咱们移动端请求就完了。
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("userName","用户名");
jsonObject.put("passWord","密码");
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "数据加入失败转型json", Toast.LENGTH_SHORT).show();
}
String postBody=jsonObject.toString();
OkHttpUtils.getInstance().postraw(url, postBody, new MyNetWorkCallback<String>() {
@Override
public void onSuccess(String s) {
Toast.makeText(MainActivity.this, "登入成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "登入失败请从新登入", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onError(int errorCode, String errorMsg) {
Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
}
});
软件更新配置文件:androidmanifest文件下配置:注意在application里
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="对应的包名.fileprovider"
android:grantUriPermissions="true"
android:exported="false"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
然后在res中创建xml包,存放file_paths.xml文件:
<paths>
<external-path path="Android/data/com.earn/" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
注意:在跳转到安装界面时,android 6.0即android N以上的需要设置权限。
if (Build.VERSION.SDK_INT >= 23) {
int REQUEST_CODE_CONTACT = 101;
String[] permissions = {
Manifest.permission.WRITE_EXTERNAL_STORAGE};
//验证是否许可权限
for (String str : permissions) {
if (MainActivity.this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
//申请权限
MainActivity.this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
return;
} else {
//这里就是权限打开之后自己要操作的逻辑
}
}
}
//还有就是不用上面的:用下面的;基本上你要的权限都差不多申请了。可以根据需求删除或者添加。
boolean isGranted = true;
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (MainActivity.this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_DENIED) {
//如果没有写sd卡权限
isGranted = false;
}
if (MainActivity.this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
isGranted = false;
}
if (MainActivity.this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) !=PackageManager.PERMISSION_GRANTED) {
isGranted = false;
}
if (MainActivity.this.checkSelfPermission(Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
isGranted = false;
}
if (!isGranted) {
MainActivity.this.requestPermissions(
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission
.ACCESS_FINE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
Manifest.permission.VIBRATE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CALL_PHONE,
Manifest.permission.CAMERA},
102);
}
}
然后在做更新的时候,我测试用的是华为手机还是遇到问题了, 文件包名冲突,后来发现华为手机需要app内部安装权限,不知道别的手机是不是。所以上代码:
//建议放在下载之前,因为有的时候都不让下载最好在判断版本里面添加这个
//新的api
@RequiresApi(api = Build.VERSION_CODES.O)
boolean haveInstallPermission = mContext.getPackageManager().canRequestPackageInstalls();
if(!haveInstallPermission){
//权限没有打开则提示用户去手动打开
Uri packageURI = Uri.parse("package:" + getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
startActivityForResult(intent, 100);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==100){
Toast.makeText(MainActivity.this, "开启权限成功", Toast.LENGTH_LONG).show();
//开启权限以后做的操作,下载更新安装。
OkHttpUtils.getInstance().download(urls, new MyNetWorkCallback<String>() {
@Override
public void onSuccess(String s) {
if(s.equals("下载完成")){
downSuccess();
}
}
@Override
public void onError(int errorCode, String errorMsg) {
Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
}
});
}
}
/**
* 下载成功
*/
public void downSuccess() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setTitle("下载完成");
builder.setMessage("是否安装");
builder.setCancelable(false);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //aandroid N的权限问题
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(MainActivity.this, "com.example.ceshijk.provider", new File(Environment.getExternalStorageDirectory(), "ceshi.apk"));//注意修改
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "ceshi.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
startActivity(intent);
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
更新就完事了,亲测好使成功,有问题留言就好,看到必回。
目前的项目还没有涉及到长传图片,等涉及到了我自己用了我在改进,
在友情提示rxjava当中的长传图片观察者模式可能有些更改,自己看下最新的吧,然后调用,应该旧可以了,用不好的话的等我更新吧。
感谢新手借鉴,大佬指点。
版权声明:本文为q992767879原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。