import {
AsyncStorage, FlatList, Image, StatusBar, TouchableOpacity, View, Dimensions,ToastAndroid,
ActivityIndicator, Platform, ProgressBarAndroid, Text, PixelRatio,ImageBackground,BackHandler,
NativeModules,Modal,PermissionsAndroid,
} from "react-native";
import React from "react";
class HomeScreen extends React.PureComponent {
componentDidMount() {
if (Platform.OS === 'android') {
this._version();
}
}
constructor(props) {
super(props);
this.state = {
sourceData : []
isLoading: false,
animating: false,
//网络请求状态
error: false,
errorInfo: "",
isUpdateModalVisable:false,
}
}
render() {
return (
this._flatList = flatList}
style={{backgroundColor:'#fff'}}
renderItem={this._renderItem}
keyExtractor={ this._keyExtractor }
refreshing={false}
numColumns ={3}
data={this.state.sourceData}>
{
this.setState({
isUpdateModalVisable: false
});
}}
>
{this._renderUpdateModal()}
);
}
_version(){
// let version = 2;
// if(version){
// NativeModules.VersionModule.getVersionInfo((result) => {
// if(result){
// let o = JSON.parse(result);
// if(o){
// let versionCode = o.versionCode;
// if(versionCode){
// if(version>versionCode){
// this.setState({
// isNeedUpdate:true,
// })
// }
// }
// }
// }
// })
// }
let url = 'http';
fetch(url)
.then((response) => response.json())
.then((responseData) => {
let resultMsg = responseData.resultMsg;
let resultCode = responseData.resultCode;
if(resultCode===200){
let object = responseData.object;
if(object){
let version = object.version;
if(version){
NativeModules.VersionModule.getVersionInfo((result) => {
if(result){
let o = JSON.parse(result);
if(o){
let versionCode = o.versionCode;
if(versionCode){
if(version>versionCode){
this.setState({
isUpdateModalVisable:true,
})
}
}
}
}
})
}
}
}else{
// this.setState({
// error: true,
// });
}
}).catch((error) => {
});
}
_renderUpdateModal(){
return(
{this.setState({isUpdateModalVisable:false})}}
style={{
position: 'absolute', left: 10,
height: 40, flexDirection: 'row',
justifyContent: 'center', alignItems: 'center', marginLeft: 5
}}>
close
Tip
this.textInput = ref}
style={{
marginLeft: 15,marginRight:15,
height: 120, color: '#333333', fontSize: 15,
borderWidth: 1, borderColor: '#E8EEF0', backgroundColor: '#ffffff', borderRadius: 4,
paddingLeft: 15, paddingRight: 15, paddingTop: 10
}}
>New version detected, update now?
{
this.checkPermission();
}}
style={{
paddingTop:8,paddingBottom:8,paddingLeft:12,paddingRight:12,
justifyContent: 'center', alignItems: 'center',
backgroundColor: "#1097D5", borderRadius: 4
}}>
update
);
}
checkPermission() {
this.setState({isUpdateModalVisable:false});
try {
//返回Promise类型
const granted = PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
)
granted.then((data)=>{
//alert(data)
if(data){
NativeModules.VersionModule.update();
}else{
this.requestReadPermission();
}
}).catch((err)=>{
//this.show(err.toString())
})
} catch (err) {
//this.show(err.toString())
}
}
async requestReadPermission() {
try {
//返回string类型
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
// {
// //第一次请求拒绝后提示用户你为什么要这个权限
// 'title': 'Need to storage permissions ',
// 'message': 'Please agree with storage permissions '
// }
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
//this.show("你已获取了读写权限")
NativeModules.VersionModule.update();
} else {
//this.show("获取读写权限失败")
alert('Failed to get storage permission')
}
} catch (err) {
//this.show(err.toString())
alert(err.toString())
}
}
}
VersionModule.java
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import org.json.JSONException;
import org.json.JSONObject;
public class VersionModule extends ReactContextBaseJavaModule {
private Context context;
public VersionModule(ReactApplicationContext reactContext) {
super(reactContext);
this.context = reactContext;
}
@Override
public String getName() {
return "VersionModule";
}
@ReactMethod
public void update() {
if (context != null) {
Intent intent = new Intent(context, UpdateService.class);
context.startService(intent);
}
}
public static int getVersionCode(Context mContext) {
if (mContext != null) {
try {
return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException ignored) {
}
}
return 0;
}
public static String getVersionName(Context mContext) {
if (mContext != null) {
try {
return mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException ignored) {
}
}
return "";
}
@ReactMethod
public void getVersionInfo(final Callback callback) {
JSONObject versionInfo = new JSONObject();
try {
versionInfo.put("versionCode", getVersionCode(context));
versionInfo.put("versionName", getVersionName(context));
} catch (JSONException e) {
e.printStackTrace();
}
callback.invoke(versionInfo.toString());
}
}
VersionPackage.java
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class VersionPackage implements ReactPackage {
public VersionPackage() {}
@Override
public List createNativeModules(
ReactApplicationContext reactContext) {
List modules = new ArrayList<>();
modules.add(new VersionModule(reactContext));
return modules;
}
public List> createJSModules() {
return Collections.emptyList();
}
@Override
public List createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
在MainApplication.java中注册
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new VersionPackage()
);
}
UpdateService.java
import android.Manifest;
import android.app.DownloadManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ServiceCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.webkit.MimeTypeMap;
import android.widget.Toast;
import java.io.File;
public class UpdateService extends Service {
/**
* 安卓系统下载类
**/
private DownloadManager manager;
/**
* 接收下载完的广播
**/
private DownloadCompleteReceiver receiver;
private String downloadurl;
private String DOWNLOADPATH = Environment.DIRECTORY_DOWNLOADS;
private String apkName = "download.apk";
/**
* 初始化下载器
**/
private void initDownManager() {
manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
receiver = new DownloadCompleteReceiver();
//设置下载地址
DownloadManager.Request down = new DownloadManager.Request(Uri.parse(downloadurl));
// 设置允许使用的网络类型,这里是移动网络和wifi都可以
down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
| DownloadManager.Request.NETWORK_WIFI);
down.setAllowedOverRoaming(false);
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(downloadurl));
down.setMimeType(mimeString);
// 下载时,通知栏显示途中
down.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
// 显示下载界面
down.setVisibleInDownloadsUi(true);
// 设置下载后文件存放的位置
down.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
down.setTitle(this.getResources().getString(R.string.app_name));
// 将下载请求放入队列
manager.enqueue(down);
//注册下载广播
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//downloadurl = intent.getStringExtra("url");
downloadurl = "http://127.0.0.1/download.apk";
File file = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
, apkName);
if (file.exists()) {
file.delete();
}
try {
// 调用下载
initDownManager();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "download fail initDownManager", Toast.LENGTH_SHORT).show();
}
return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
if (receiver != null)
// 注销下载广播
unregisterReceiver(receiver);
super.onDestroy();
}
// 接受下载完成后的intent
class DownloadCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//判断是否下载完成的广播
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
//获取下载的文件id
long downId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if ( manager.getUriForDownloadedFile(downId) != null ) {
//自动安装apk
//installAPK(manager.getUriForDownloadedFile(downId), context);
//File file = new File(DOWNLOADPATH+ apkName);
install(context);
//installAPK(context);
} else {
Toast.makeText(context, "download fail", Toast.LENGTH_SHORT).show();
}
//停止服务并关闭广播
UpdateService.this.stopSelf();
}
}
/**
* 通过隐式意图调用系统安装程序安装APK
*/
public void install(Context context) {
File file = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
, apkName);
if(file.exists()){
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由于没有在Activity环境下启动Activity,设置下面的标签
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) { //判读版本是否在7.0以上
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致 参数3 共享的文件
Uri apkUri =
MyFileProvider.getUriForFile(context, context.getPackageName()+".fileprovider", file);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
}else{
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
}
context.startActivity(intent);
}else {
Toast.makeText(context, "update error", Toast.LENGTH_SHORT).show();
}
}
}
}
MyFileProvider.java
import android.support.v4.content.FileProvider;
public class MyFileProvider extends FileProvider {
}
file_provider_paths.xml
AndroidManifest.xml