Bläddra i källkod

Merge commit 'refs/tags/jenkins-front-end-screenad-296-v43^{}' into product

tags/jenkins-product-front-end-screenad-6-^0
hupeng 5 år sedan
förälder
incheckning
01356aede4
18 ändrade filer med 12822 tillägg och 94 borttagningar
  1. +9
    -0
      .gitignore
  2. +533
    -90
      App.js
  3. +1
    -0
      android/app/build.gradle
  4. Binär
      android/app/libs/cron4j-2.2.5.jar
  5. +5
    -1
      android/app/src/main/AndroidManifest.xml
  6. +153
    -0
      android/app/src/main/java/com/screenad/DaemonService.java
  7. +16
    -2
      android/app/src/main/java/com/screenad/MainApplication.java
  8. Binär
      android/app/src/main/res/drawable-mdpi/image_background.png
  9. Binär
      android/app/src/main/res/drawable-mdpi/image_discount.png
  10. Binär
      android/app/src/main/res/drawable-mdpi/image_groupbuy.png
  11. Binär
      android/app/src/main/res/drawable-mdpi/image_itembackground.png
  12. Binär
      android/app/src/main/res/drawable-mdpi/image_timed.png
  13. Binär
      android/app/src/main/res/drawable-mdpi/image_title.png
  14. Binär
      android/app/src/main/res/drawable-mdpi/image_titleqrcode.png
  15. +2
    -0
      android/settings.gradle
  16. +28
    -0
      ios/screenAd.xcodeproj/project.pbxproj
  17. +12070
    -0
      package-lock.json
  18. +5
    -1
      package.json

+ 9
- 0
.gitignore Visa fil

@@ -55,3 +55,12 @@ buck-out/
# Bundle artifact
*.jsbundle
/yarn.lock

android/app/.classpath
android/app/.project
android/.project
android/.settings/*
android/app/.settings/*
android/app/src/main/gen/*
android/bin/*


+ 533
- 90
App.js Visa fil

@@ -8,18 +8,22 @@ import {
Image,
ImageBackground,
PixelRatio,
NativeModules
NativeModules,
} from 'react-native';



//引用插件
import Package from './package.json'
import HttpUtils from './HttpUtils.js';
import CodePush from "react-native-code-push";
import DeviceInfo from "react-native-device-info";
import * as Animatable from 'react-native-animatable';
var testMac = 'FF:FF:FF:FF:FF:FF'
import Swiper from 'react-native-swiper';
import Carousel from 'react-native-snap-carousel';
// import {BoxShadow} from 'react-native-shadow';

var testMac = 'FF:FF:FF:FF:FF:FF'
var curAdIndex = 0;
var errorMsg = {
ERR_MAC_GET:'设备编号获取错误',
@@ -54,17 +58,29 @@ var animationThemes = [
third:"bounceInRight"
}
]
const shadowOpt = {
width: 800/PixelRatio.get(),
height: 240/PixelRatio.get(),
color:"#000",
border:2,
radius:3,
opacity:0.5,
x:2,
y:3,
style:{marginVertical:5}
}

var timer = null;
var curTimer = null;

var hbRequestCount
var getAdDataCount
var pageChangeCount

var adDataList = []
var adDataList = [];
var adDataBgList = [];

var heartConfig = {
heartbeatInterval:10,
heartbeatInterval:300,
dataRefreshInterval:3600,
pageChangeInterval:10,
}
@@ -90,7 +106,7 @@ export default class MyPage extends Component {
contentItem0:null,
contentItem1:null,
contentItem2:null,
animationTheme:{},
animationTheme:animationThemes[0],
contentDisplayStatus:false,
syncMessage: "初始化..." ,
errorMessage: '加载中...',
@@ -100,8 +116,46 @@ export default class MyPage extends Component {
},
updating:true,
macAddress: '',
versionInfo:'未知'
versionInfo:'未知',
adType: 0,
curAdType02Index: 0, //广告图index
coverImgUrl: '',
previewImg: '',
curImgState: false,
};

/* this.codePushUpdate = this.codePushUpdate.bind(this);
this.startAd = this.startAd.bind(this);
this.showErrMsg = this.showErrMsg.bind(this); */
}

componentDidMount() {
this.codePushUpdate();
DeviceInfo.getMACAddress().then((mac)=>{
if (mac=='' || mac==null ) {
if (NativeModules.BuildConfig.buildType == 'debug') {
this.setState({macAddress : this.testMac})
this.startAd()
} else {
this.showErrMsg(errorMsg.ERR_MAC_GET);
}
} else {
this.setState({macAddress : mac})
this.startAd()
}
}).catch(e => {
this.showErrMsg(errorMsg.ERR_START_AD);
})
}

componentDidUpdate() {
/* console.log(this.refs.scrollView)
if (this.refs.scrollView != undefined) {
var ScrollView = this.refs.scrollView;
ScrollView.scrollBy(0, true);
} */
}

//更新函数
@@ -123,7 +177,8 @@ async codePushUpdate() {
).then((status: SyncStatus) => {

}, (error: any) => {
CodePush.restartApp();
console.log(error)
// CodePush.restartApp();
});
}

@@ -167,7 +222,8 @@ codePushStatusDidChange(syncStatus) {
return false;
if (curAdIndex >= adDataList.length) {
curAdIndex = 0
curAdIndex = 0;
}

this.setState({contentItem0:adDataList[curAdIndex]});
@@ -235,6 +291,27 @@ codePushStatusDidChange(syncStatus) {
this.setState({errorMessage : errMsg});
}

//判断播放类型adType
dealLoopType(dataList) {
adDataList = dataList.filter((item) => {
return item.type == 0;
})
adDataBgList = dataList.filter((item) => {
return item.type == 2;
})
//aaa
let num = 0;
if (adDataList.length > 0 && adDataBgList.length > 0) {
num = 2;
this.setState({previewImg: adDataBgList[0].coverImg});
} else if (adDataList.length > 0 && !adDataBgList.length) {
num = 0;
} else if (!adDataList.length && adDataBgList.length > 0) {
num = 1;
}
this.setState({adType: num })
}

getAdDataList(first) {
HttpUtils.get(NativeModules.BuildConfig.apiHost
+ 'api/wxDeviceScreenAd/list?deviceId='
@@ -244,7 +321,12 @@ codePushStatusDidChange(syncStatus) {
if (result.code != 200) {
this.showErrMsg(result.message+'\n'+this.state.macAddress);
} else if (result.data.list) {
adDataList = result.data.list;
//aaa
//type==0的是券 1是? 2是广告大图
let curData = result.data.list;
this.dealLoopType(curData);

if (this.updateContent()) {
this.setState({contentDisplayStatus: true})
} else {
@@ -283,36 +365,23 @@ codePushStatusDidChange(syncStatus) {
}

componentDidMount() {
this.codePushUpdate();

DeviceInfo.getMACAddress().then((mac)=>{
if (mac=='' || mac==null ) {
if (NativeModules.BuildConfig.buildType == 'debug') {
this.setState({macAddress : this.testMac})
this.startAd()
} else {
this.showErrMsg(errorMsg.ERR_MAC_GET);
}
} else {
this.setState({macAddress : mac})
this.startAd()
}
}).catch(e => {
this.showErrMsg(errorMsg.ERR_START_AD);
})
}

componentWillUnmount(){
if (timer)
clearTimeout(timer)
if (curTimer)
clearTimeout(curTimer)
}



async routine() {
hbRequestCount -=1;
getAdDataCount -=1;
pageChangeCount -=1;
if (this.state.adType == 2 && this.state.curImgState) {
pageChangeCount -=1;
}
if (this.state.adType != 2) {
pageChangeCount -=1;
}

try {
if (getAdDataCount<=0) {
@@ -322,26 +391,45 @@ async routine() {
this.hbRequest()
hbRequestCount = heartConfig.heartbeatInterval
}

if (pageChangeCount <= 0) { //页面切换间隔
if (this.state.contentDisplayStatus && this.state.baseInfo) {
this.setState({ contentDisplayStatus: false})
if (this.updateContent()) {
this.setState({ contentDisplayStatus: true})
//如果是adType == 2时间间隔到了,要检验轮播是否走完在决定切换
if (this.state.adType == 2) {
if (pageChangeCount<=0) {
let curNum = this.state.curAdType02Index + 1;
if (curNum >= adDataBgList.length) {
curNum = 0;
}
} else {
await this.getBaseInfo()
await this.getAdDataList(true)
getAdDataCount = heartConfig.dataRefreshInterval
hbRequestCount = heartConfig.heartbeatInterval
this.setState({
curAdType02Index: curNum,
previewImg:adDataBgList[curNum].coverImg
})
pageChangeCount = heartConfig.pageChangeInterval
}
} else if (this.state.adType == 0) {
if (pageChangeCount <= 0) { //页面切换间隔
if (this.state.contentDisplayStatus && this.state.baseInfo) {
this.setState({ contentDisplayStatus: false})
if (this.updateContent()) {
this.setState({ contentDisplayStatus: true})
}
} else {
await this.getBaseInfo()
await this.getAdDataList(true)
getAdDataCount = heartConfig.dataRefreshInterval
hbRequestCount = heartConfig.heartbeatInterval
}
pageChangeCount = heartConfig.pageChangeInterval
}
pageChangeCount = heartConfig.pageChangeInterval
}

} catch(e){
this.setState({ versionInfo: versionInfo+'[E]'});
}

timer = setTimeout(()=>{
curTimer = setTimeout(()=>{
this.routine();
},1000);
}
@@ -397,8 +485,18 @@ getContentViewItem(contentItem, annomation) {

actionText = this.getContentViewItemActionStr(contentItem);
merchantName = this.getContentViewItemMerchantName(contentItem);
//aaa
// contentItem.target.salePriceStr = 234005.8;
// console.warn(annomation)
let curNumStr = contentItem.target.salePriceStr+'';
let curStyleObj = {};
if (curNumStr.length > 5 || Number(curNumStr) > 10000) {
curStyleObj = styles.contentItemTopDetailCurPriceStr02;
} else {
curStyleObj = styles.contentItemTopDetailCurPriceStr01;
}
return (
<Animatable.View animation={annomation} style={styles.contentItem}>

<ImageBackground source={require('./image/item-background.png')} resizeMode='center' style={styles.contentItemDownLayer} >
@@ -412,7 +510,8 @@ getContentViewItem(contentItem, annomation) {
{/* 售价 */}
<View style={styles.contentItemTopDetailCurPrice}>
<Text style={styles.contentItemTopDetailCurPriceStrUnit}>¥</Text>
<Text style={styles.contentItemTopDetailCurPriceStr}>{contentItem.target.salePriceStr}</Text>
<Text style={curStyleObj}>{contentItem.target.salePriceStr}</Text>
{/* <Text style={styles.contentItemTopDetailCurPriceStr}>{contentItem.target.salePriceStr}</Text> */}
</View>
{/* 面额 */}
<View style={styles.contentItemTopDetailSalePrice}>
@@ -449,6 +548,71 @@ getContentView() {
</View>)
}
}
setAdSwiperItemDom(item) {
let contentItem = item.item;
return (
<View style={styles.onlyAdSwiperItem}>
<Image source={{uri: contentItem.coverImg}} resizeMode='stretch' style={styles.onlyAdTypeItemImg} />
</View>
)
}
setSwiperItemDom(item) {
let contentItem = item.item;
let index = item.index;
let curLogo = null;
if (contentItem.type == 0) {
if (contentItem.subType == 2)
curLogo = require('./image/timed.png');
if (contentItem.subType == 6)
curLogo = require('./image/discount.png');
if (contentItem.subType == 7)
curLogo = require('./image/groupbuy.png');
}
//aaa
// contentItem.target.salePriceStr = 24502228;
let curNumStr = contentItem.target.salePriceStr+'';
let curStyleObj = {};
if (curNumStr.length > 6 || Number(curNumStr) > 100000) {
curStyleObj = styles.contentItemTopDetailCurPriceStr04;
} else {
curStyleObj = styles.contentItemTopDetailCurPriceStr03;
}
return (
<View style={styles.carouselItemWrap}>
{/* <BoxShadow setting={shadowOpt}> */}
<View setting={shadowOpt}>
<View style={styles.contentItemTopForAd} key={index}>
<Image source={curLogo} resizeMode='center' style={styles.contentItemUpLayerLogo} />
{/* <ImageBackground style={styles.adTypeSwiper02} resizeMode="stretch" source={require('./image/item-background.png')}></ImageBackground> */}
<Image source={{uri: contentItem.coverImg}} resizeMode='cover' style={styles.adTypeItemImg} />
<View style={styles.contentItemTopDetail}>
{/* 券的title */}
<Text style={styles.contentItemTopDetailTitle02} numberOfLines={2} ellipsizeMode="tail">{contentItem.target.title}</Text>
<View style={styles.contentItemTopDetailPrice}>
{/* 售价 */}
<View style={styles.contentItemTopDetailCurPrice}>
<Text style={styles.contentItemTopDetailCurPriceStrUnit02}>¥</Text>
<Text style={curStyleObj}>{contentItem.target.salePriceStr}</Text>
</View>
{/* 面额 */}
<View style={styles.contentItemTopDetailSalePrice02}>
<Text style={styles.contentItemTopDetailSalePriceStr02} >¥{contentItem.target.priceStr}</Text>
</View>
</View>
</View>
{/* <Image source={{uri:'data:image/png;base64,'+contentItem.qrcode}} resizeMode='contain' style={styles.contentItemTopQrcode} /> */}
<View style={styles.contentItemTopQrcodeBox}>
<Image source={{uri:contentItem.target.qrCode}} resizeMode='contain' style={styles.contentItemTopQrcode02} />
</View>
</View>
</View>
{/* </BoxShadow> */}
</View>
)
}

getUpdateView() {
if (this.state.progress.totalBytes > 0)
@@ -462,41 +626,113 @@ getUpdateView() {
</Text>
);
}
rendDefaultImg() {
if (this.state.coverImgUrl) {
return (
<ImageBackground style={styles.adTypeBg} resizeMode="stretch" source={{uri: this.state.coverImgUrl}}></ImageBackground>
)
} else {
return (
<ImageBackground style={styles.adTypeBg} resizeMode="stretch" source={require('./image/background.png')}></ImageBackground>
)
}
}

getAdView(){
if (this.state.baseInfo) {
return (
<ImageBackground style={styles.background} resizeMode='center' source={require('./image/background.png')}>
{/* 头部title二维码开始 */}
<View style={styles.title}>
<View style={styles.titleImagePlace}>
<Image source={require('./image/title.png')} resizeMode='center' style={styles.titleImage} />
</View>
<ImageBackground source={require('./image/title-qrcode.png') } resizeMode='center' style={styles.titleQrcodeBonder} >
<View style={styles.titleQrcodePlacehold}></View>
<Image source={{uri: this.state.baseInfo.imgQrcodeWeapp}} resizeMode='center' style={styles.titleQrcode} />
<View style={styles.titleQrcodePlacehold}></View>
</ImageBackground>
</View>
{/* 券列表展示列表开始 */}
{this.getContentView()}
{/* 底部商场信息展示开始 */}
<View style={styles.bottom}>
<View style={styles.bottomLogoBackground}>
<Image source={{ uri: this.state.baseInfo.imgUrlH}} resizeMode='contain' style={styles.bottomLogo} />
</View>
<View style={styles.bottomQrcode1Background}>
<Image source={{ uri: this.state.baseInfo.imgQrcodeWeapp}} resizeMode='center' style={styles.bottomQrcode1} />
<Text style={styles.bottomQrcode1Str}>小程序</Text>
</View>
<View style={styles.bottomQrcode2Background}>
<Image source={{ uri: this.state.baseInfo.imgQrcodeWemp}} resizeMode='center' style={styles.bottomQrcode2} />
<Text style={styles.bottomQrcode1Str}>公众号</Text>
if (this.state.adType == 0) {
return (
<ImageBackground style={styles.background} resizeMode='center' source={require('./image/background.png')}>
{/* 头部title二维码开始 */}
<View style={styles.title}>
<View style={styles.titleImagePlace}>
<Image source={require('./image/title.png')} resizeMode='center' style={styles.titleImage} />
</View>
<ImageBackground source={require('./image/title-qrcode.png') } resizeMode='center' style={styles.titleQrcodeBonder} >
<View style={styles.titleQrcodePlacehold}></View>
<Image source={{uri: this.state.baseInfo.imgQrcodeWeapp}} resizeMode='center' style={styles.titleQrcode} />
<View style={styles.titleQrcodePlacehold}></View>
</ImageBackground>
</View>
{/* 券列表展示列表开始 */}
{this.getContentView()}
{/* 底部商场信息展示开始 */}
<View style={styles.bottom}>
<View style={styles.bottomLogoBackground}>
<Image source={{ uri: this.state.baseInfo.imgUrlH}} resizeMode='contain' style={styles.bottomLogo} />
</View>
<View style={styles.bottomQrcode1Background}>
<Image source={{ uri: this.state.baseInfo.imgQrcodeWeapp}} resizeMode='center' style={styles.bottomQrcode1} />
<Text style={styles.bottomQrcode1Str}>小程序</Text>
</View>
<View style={styles.bottomQrcode2Background}>
<Image source={{ uri: this.state.baseInfo.imgQrcodeWemp}} resizeMode='center' style={styles.bottomQrcode2} />
<Text style={styles.bottomQrcode1Str}>公众号</Text>
</View>
<Text style={styles.bottomPlacehold}>{this.state.versionInfo}</Text>
</View>
</ImageBackground>
);
} else if (this.state.adType == 2) {
let curWidthNum = 1080/(PixelRatio.get());
return (
// <ImageBackground style={styles.adTypeBg} source={require('./image/ad1.jpg')}> slideInDown zoomInDown
<View style={styles.adWrapBox}>
<Image style={styles.adWrapHideImg}
onLoadStart={() => {
this.setState({
curImgState: false
})
}}
onLoad={() => {
this.setState({
coverImgUrl: this.state.previewImg,
curImgState: true
})
}}
resizeMode="stretch" source={{uri: this.state.previewImg}}>
</Image>

<Animatable.View animation="fadeIn" style={styles.adWrap} key={this.state.coverImgUrl}>
{this.rendDefaultImg()}
</Animatable.View>
<View style={styles.adTypeSwiper02}>
<Carousel
style={styles.adTypeSwiper02Content}
ref={'carousel02'}
data={adDataList}
renderItem={this.setSwiperItemDom}
sliderWidth={curWidthNum}
itemWidth={curWidthNum}
layout={'stack'}
activeSlideOffset={0}
autoplay={true}
loop={true}
autoplayInterval={5000}
/>
</View>
<Text style={styles.bottomPlacehold}>{this.state.versionInfo}</Text>
</View>
</ImageBackground>
);}
);
} else if (this.state.adType == 1) {
let curWidthNum = 1080/(PixelRatio.get())
return(
<Carousel
ref={'carousel01'}
data={adDataBgList}
renderItem={this.setAdSwiperItemDom}
sliderWidth={curWidthNum}
itemWidth={curWidthNum}
activeSlideOffset={0}
autoplay={true}
loop={true}
autoplayInterval={5000}
/>
)
}
}
else {
return (
<ImageBackground style={styles.background} resizeMode='center' source={require('./image/background.png')}>
@@ -713,6 +949,15 @@ MyPage = CodePush(codePushOptions)(MyPage);
position:'absolute',
backgroundColor:'transparent'
},
contentItemUpLayerLogo: {
width:160/PixelRatio.get(),
height:83/PixelRatio.get(),
position: 'absolute',
left: -20/PixelRatio.get(),
top: 20/PixelRatio.get(),
zIndex:100,
backgroundColor: 'transparent',
},

contentItemTop:{
flex: 3,
@@ -761,11 +1006,24 @@ MyPage = CodePush(codePushOptions)(MyPage);
flex: 5,
width:'100%',
height:'100%',
// borderStyle:"solid",
// borderWidth:1,
// borderColor:"red",
marginLeft:18/PixelRatio.get(),
backgroundColor:'transparent'
// backgroundColor:'transparent'
},

contentItemTopQrcodeBox:{
flex: 5,
width:'100%',
height:'100%',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
marginLeft: -28/PixelRatio.get(),
// backgroundColor:'transparent'
},

contentItemTopQrcode02:{
width:'90%',
height:'90%',
},

//layer content item bottom
@@ -779,7 +1037,8 @@ MyPage = CodePush(codePushOptions)(MyPage);
textAlign :'center',
textAlignVertical:'center',
fontSize: 27/PixelRatio.get(),
fontWeight : 'bold'
fontWeight : 'bold',

},

contentItemBottomPlacehold:{
@@ -803,9 +1062,16 @@ MyPage = CodePush(codePushOptions)(MyPage);
textAlignVertical:'center',
fontSize: 36/PixelRatio.get(),
color: 'black',
// borderStyle:"solid",
// borderWidth:1,
// borderColor:"red"
},

contentItemBottomAction02:{
width:'100%',
height: 60/PixelRatio.get(),
backgroundColor:'transparent',
textAlign :'center',
textAlignVertical:'center',
fontSize: 36/PixelRatio.get(),
color: 'black',
},

// 券的title
@@ -814,15 +1080,25 @@ MyPage = CodePush(codePushOptions)(MyPage);
// height:'100%',
width:'100%',
marginTop:"2%",
// borderStyle:"solid",
// borderWidth:1,
// borderColor:"red",
backgroundColor:'transparent',
textAlign :'left',
color:"black",
textAlignVertical:'center',
fontSize: 53/PixelRatio.get(),
},
// 券的title
contentItemTopDetailTitle02:{
flex: 2,
// height:'100%',
width:'100%',
marginTop:"2%",
paddingRight: 14/PixelRatio.get(),
backgroundColor:'transparent',
textAlign :'left',
color:"black",
textAlignVertical:'center',
fontSize: 42/PixelRatio.get(),
},
/*
contentItemTopDetailRemark:{
flex: 1,
@@ -854,7 +1130,7 @@ MyPage = CodePush(codePushOptions)(MyPage);
backgroundColor:'transparent',
},

contentItemTopDetailCurPriceStr:{
contentItemTopDetailCurPriceStr01:{
backgroundColor:'transparent',
fontSize:96/PixelRatio.get(),
fontFamily:"PingFangSC-Bold",
@@ -863,6 +1139,36 @@ MyPage = CodePush(codePushOptions)(MyPage);
textAlignVertical:'bottom',
color : 'red'
},
//金额超10000,字号修改
contentItemTopDetailCurPriceStr02:{
backgroundColor:'transparent',
fontSize:64/PixelRatio.get(),
fontFamily:"PingFangSC-Bold",
fontWeight: "bold",
textAlign :'left',
textAlignVertical:'bottom',
paddingBottom: 8/PixelRatio.get(),
color : 'red'
},

contentItemTopDetailCurPriceStr03:{
backgroundColor:'transparent',
fontSize:72/PixelRatio.get(),
fontFamily:"PingFangSC-Bold",
fontWeight: "bold",
textAlign :'left',
color : 'red'
},
//金额超10000,字号修改
contentItemTopDetailCurPriceStr04:{
backgroundColor:'transparent',
fontSize:52/PixelRatio.get(),
fontFamily:"PingFangSC-Bold",
fontWeight: "bold",
textAlign :'left',
paddingTop: 16/PixelRatio.get(),
color : 'red'
},

contentItemTopDetailCurPriceStrUnit:{
backgroundColor:'transparent',
@@ -870,6 +1176,15 @@ MyPage = CodePush(codePushOptions)(MyPage);
textAlignVertical:'bottom',
paddingBottom: 16/PixelRatio.get(),
fontSize: 48/PixelRatio.get(),
color : 'red',
},

contentItemTopDetailCurPriceStrUnit02:{
backgroundColor:'transparent',
textAlign :'left',
textAlignVertical:'center',
paddingBottom: 16/PixelRatio.get(),
fontSize: 48/PixelRatio.get(),
color : 'red'
},
// 面额的样式
@@ -878,7 +1193,18 @@ MyPage = CodePush(codePushOptions)(MyPage);
bottom:2,
left:0,
// flex: 1,
paddingTop:50,
paddingTop:138/PixelRatio.get(),
width:'100%',
// height:'100%',
backgroundColor:'transparent',
},

contentItemTopDetailSalePrice02:{
position:"absolute",
bottom:14/PixelRatio.get(),
left:0,
// flex: 1,
paddingTop:138/PixelRatio.get(),
width:'100%',
// height:'100%',
backgroundColor:'transparent',
@@ -894,4 +1220,121 @@ MyPage = CodePush(codePushOptions)(MyPage);
textDecorationLine: 'line-through',
color : 'gray'
},

contentItemTopDetailSalePriceStr02:{
width:'100%',
height:'100%',
backgroundColor:'transparent',
textAlignVertical:'center',
textAlign :'left',
fontSize: 27/PixelRatio.get(),
textDecorationLine: 'line-through',
color : 'gray'
},


adTypeBg:{
flex: 1,
width: '100%',
height: '100%',
},
adWrapBox: {
width: '100%',
height: '100%',
position: 'relative',
},
adWrap: {
width: '100%',
height: '100%',
position: 'absolute',
left: 0,
top: 0,
zIndex: 10,
},
adWrapHideImg: {
width: '100%',
height: '100%',
position: 'absolute',
left: 0,
top: 0,
zIndex: -1,
opacity:0,
},

adTypeSwiper02:{
flex: 1,
alignItems: 'center',
position: 'absolute',
left: 0,
bottom: 60/PixelRatio.get(),
width: '100%',
height: 270/PixelRatio.get(),
paddingTop: 10/PixelRatio.get(),
paddingBottom: 10/PixelRatio.get(),
backgroundColor: 'rgba(0,0,0,.1)',
},

adTypeItemImgWrap:{
flex: 1,
width: '100%',
height: 369/PixelRatio.get(),
flexDirection: 'row',
alignItems: 'center',
},

adTypeItemImg:{
width: 200/PixelRatio.get(),
height: 200/PixelRatio.get(),
marginLeft: 8/PixelRatio.get(),
marginTop: 20/PixelRatio.get(),
borderRadius:27/PixelRatio.get(),
backgroundColor:'transparent'
},

bottomBox:{
position: 'absolute',
bottom: 20/PixelRatio.get(),
left: 0,
width: '100%',
height: 130/PixelRatio.get(),
flexDirection: 'row',
alignItems: 'center',
backgroundColor:'transparent',
},

contentItemTopForAd:{
position: 'relative',
flex: 1,
width: 800/PixelRatio.get(),
// width: '100%',
height:'100%',
paddingLeft: 12/PixelRatio.get(),
paddingRight: 26/PixelRatio.get(),
flexDirection: 'row',
alignItems: 'flex-start',
borderRadius: 6,
backgroundColor:'rgba(255,255,255,.8)',
},

onlyAdSwiperItem:{
width: '100%',
height: '100%',
},

onlyAdTypeItemImg:{
width: '100%',
height: '100%',
},

carouselItemWrap: {
flex: 1,
width: '100%',
backgroundColor: 'transparent',
alignItems: 'center',
}

});

+ 1
- 0
android/app/build.gradle Visa fil

@@ -181,6 +181,7 @@ android {
}

dependencies {
implementation project(':react-native-svg')
implementation project(':react-native-camera')
implementation project(':react-native-device-info')
implementation project(':react-native-code-push')


Binär
android/app/libs/cron4j-2.2.5.jar Visa fil


+ 5
- 1
android/app/src/main/AndroidManifest.xml Visa fil

@@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".MainApplication"
android:label="@string/app_name"
@@ -27,6 +27,10 @@
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<service
android:name=".DaemonService"
android:exported="true"
android:launchMode="singleInstance" />
<receiver android:name=".AutoStartBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />


+ 153
- 0
android/app/src/main/java/com/screenad/DaemonService.java Visa fil

@@ -0,0 +1,153 @@
package com.screenad;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.ArrayList;
import java.util.List;
import com.screenad.MainApplication;
import it.sauronsoftware.cron4j.Scheduler;
/**
* 守护进程,同时用来升级程序
*/
public class DaemonService extends Service {
// 核心进程 Service ID
private final static int CORE_SERVICE_ID = -5122;
private ExecutorService executorService = Executors.newSingleThreadExecutor();
Scheduler scheduler;
public DaemonService() {
}
private static void log(String text) {
Log.i("DaemonService",text);
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
log("started");
//利用 Android 漏洞提高进程优先级, 前台进程
String CHANNEL_ONE_ID = "DaemonService";
String CHANNEL_ONE_NAME= "DaemonService";
NotificationChannel notificationChannel= null;
//进行8.0的判断
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
notificationChannel= new NotificationChannel(CHANNEL_ONE_ID,
CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setShowBadge(true);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.createNotificationChannel(notificationChannel);
}
Notification notification= new Notification.Builder(this).setChannelId(CHANNEL_ONE_ID)
.setContentTitle("DaemonService")
.build();
notification.flags|= Notification.FLAG_NO_CLEAR;
startForeground(CORE_SERVICE_ID, notification);
executorService.submit(new Runnable() {
@Override
public void run() {
startCronTabTask();
}
});
return START_STICKY;
}
private boolean isProcessWork(Context context, String processName) {
ActivityManager myAM = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> processInfos = myAM.getRunningAppProcesses();
if (processInfos == null) {
return false;
}
for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.processName.equals(processName)) {
return true;
}
}
return false;
}
private boolean isBackground(Context context, String packageName) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(packageName)) {
/* BACKGROUND=400 EMPTY=500 FOREGROUND=100 GONE=1000 PERCEPTIBLE=130 SERVICE=300 ISIBLE=200 */
log(appProcess.processName + " appimportace =" + appProcess.importance);
if (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
log("处于后台" + appProcess.processName);
return true;
} else {
log("处于前台" + appProcess.processName);
return false;
}
}
}
return false;
}
/**
* 开启cron4jtab定时任务
*/
private void startCronTabTask() {
if (scheduler != null) {
scheduler.stop();
}
scheduler = new Scheduler();
scheduler.isDaemon();
scheduler.schedule("* * * * *", new Runnable() {
public void run() {
try {
if (!isProcessWork(MainApplication.getContext(), "com.screenad") ||
isBackground(MainApplication.getContext(), "com.screenad")) {
log("正在重启 com.screenad...");
Intent newIntent = MainApplication.getContext().getPackageManager().getLaunchIntentForPackage("com.screenad");
MainApplication.getContext().startActivity(newIntent);
}else{
log("运行良好 com.screenad...");
}
} catch (Exception e) {
log(e.getMessage());
}
}
});
scheduler.start();
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
super.onDestroy();
}
}

+ 16
- 2
android/app/src/main/java/com/screenad/MainApplication.java Visa fil

@@ -1,8 +1,11 @@
package com.screenad;

import com.screenad.DaemonService;
import android.app.Application;

import android.content.Context;
import android.content.Intent;
import com.facebook.react.ReactApplication;
import com.horcrux.svg.SvgPackage;
import org.reactnative.camera.RNCameraPackage;

import com.facebook.react.bridge.ReactApplicationContext;
@@ -17,7 +20,7 @@ import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;

import android.util.Log;

public class MainApplication extends Application implements ReactApplication {

@@ -37,6 +40,7 @@ public class MainApplication extends Application implements ReactApplication {
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new SvgPackage(),
new RNCameraPackage(),
new RNBuildConfigPackage(),
new RNDeviceInfo(),
@@ -55,6 +59,13 @@ public class MainApplication extends Application implements ReactApplication {
}
};

private static void log(String text) {
Log.i("MainApplication",text);
}
private static Context context;
public static Context getContext() {
return context;
}
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
@@ -63,6 +74,9 @@ public class MainApplication extends Application implements ReactApplication {
@Override
public void onCreate() {
super.onCreate();
context = this;
SoLoader.init(this, /* native exopackage */ false);
context.startForegroundService(new Intent(getContext(), DaemonService.class));
log("started");
}
}

Binär
android/app/src/main/res/drawable-mdpi/image_background.png Visa fil

Före Efter
Bredd: 1080  |  Höjd: 1920  |  Storlek: 995 KiB

Binär
android/app/src/main/res/drawable-mdpi/image_discount.png Visa fil

Före Efter
Bredd: 142  |  Höjd: 142  |  Storlek: 11 KiB

Binär
android/app/src/main/res/drawable-mdpi/image_groupbuy.png Visa fil

Före Efter
Bredd: 141  |  Höjd: 141  |  Storlek: 33 KiB

Binär
android/app/src/main/res/drawable-mdpi/image_itembackground.png Visa fil

Före Efter
Bredd: 1080  |  Höjd: 428  |  Storlek: 28 KiB

Binär
android/app/src/main/res/drawable-mdpi/image_timed.png Visa fil

Före Efter
Bredd: 141  |  Höjd: 141  |  Storlek: 33 KiB

Binär
android/app/src/main/res/drawable-mdpi/image_title.png Visa fil

Före Efter
Bredd: 546  |  Höjd: 198  |  Storlek: 67 KiB

Binär
android/app/src/main/res/drawable-mdpi/image_titleqrcode.png Visa fil

Före Efter
Bredd: 268  |  Höjd: 268  |  Storlek: 28 KiB

+ 2
- 0
android/settings.gradle Visa fil

@@ -1,4 +1,6 @@
rootProject.name = 'screenAd'
include ':react-native-svg'
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
include ':react-native-camera'
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
include ':react-native-device-info'


+ 28
- 0
ios/screenAd.xcodeproj/project.pbxproj Visa fil

@@ -45,6 +45,8 @@
59D20E8E9CD64A01B87A3AC0 /* libRNDeviceInfo-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22D705AD40EF415A95C31652 /* libRNDeviceInfo-tvOS.a */; };
D240C4819F1E4B80BB6D7BEE /* libRNCamera.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F8C0E0ED2BA401B9075C9F3 /* libRNCamera.a */; };
BA9EAC9D8E144D058AC73DD2 /* libRNFetchBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 99C586CF88164E08936AF0C0 /* libRNFetchBlob.a */; };
B4144D9AB571435787D52BFB /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C56D91B66FA473E89F6B165 /* libRNSVG.a */; };
C109232BD2434156AC1DB82B /* libRNSVG-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA6B0CF8B7494E2E82C54C57 /* libRNSVG-tvOS.a */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
@@ -362,6 +364,9 @@
4F8C0E0ED2BA401B9075C9F3 /* libRNCamera.a */ = {isa = PBXFileReference; name = "libRNCamera.a"; path = "libRNCamera.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
BE5C3F5DA65B4EFC83BEC512 /* RNFetchBlob.xcodeproj */ = {isa = PBXFileReference; name = "RNFetchBlob.xcodeproj"; path = "../node_modules/react-native-fetch-blob/ios/RNFetchBlob.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
99C586CF88164E08936AF0C0 /* libRNFetchBlob.a */ = {isa = PBXFileReference; name = "libRNFetchBlob.a"; path = "libRNFetchBlob.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
D6E9CCF6747C429FACC9C9EE /* RNSVG.xcodeproj */ = {isa = PBXFileReference; name = "RNSVG.xcodeproj"; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
9C56D91B66FA473E89F6B165 /* libRNSVG.a */ = {isa = PBXFileReference; name = "libRNSVG.a"; path = "libRNSVG.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
DA6B0CF8B7494E2E82C54C57 /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; name = "libRNSVG-tvOS.a"; path = "libRNSVG-tvOS.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
@@ -395,6 +400,7 @@
FEBB7F68D5534228A6A832AD /* libRNDeviceInfo.a in Frameworks */,
D240C4819F1E4B80BB6D7BEE /* libRNCamera.a in Frameworks */,
BA9EAC9D8E144D058AC73DD2 /* libRNFetchBlob.a in Frameworks */,
B4144D9AB571435787D52BFB /* libRNSVG.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -412,6 +418,7 @@
2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */,
2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */,
59D20E8E9CD64A01B87A3AC0 /* libRNDeviceInfo-tvOS.a in Frameworks */,
C109232BD2434156AC1DB82B /* libRNSVG-tvOS.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -590,6 +597,7 @@
C6058A0BC9054E0394045AC4 /* RNDeviceInfo.xcodeproj */,
0F57B32024664223A7D6E682 /* RNCamera.xcodeproj */,
BE5C3F5DA65B4EFC83BEC512 /* RNFetchBlob.xcodeproj */,
D6E9CCF6747C429FACC9C9EE /* RNSVG.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@@ -1219,6 +1227,8 @@
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1226,6 +1236,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Debug;
@@ -1249,6 +1260,8 @@
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1256,6 +1269,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Release;
@@ -1282,6 +1296,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Debug;
@@ -1307,6 +1322,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Release;
@@ -1338,6 +1354,8 @@
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1345,6 +1363,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Debug;
@@ -1376,6 +1395,8 @@
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1383,6 +1404,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Release;
@@ -1413,6 +1435,8 @@
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1420,6 +1444,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Debug;
@@ -1450,6 +1475,8 @@
"$(inherited)",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1457,6 +1484,7 @@
"$(SRCROOT)\..\node_modules\react-native-device-info\ios\RNDeviceInfo",
"$(SRCROOT)\..\node_modules\react-native-camera\ios/**",
"$(SRCROOT)\..\node_modules\react-native-fetch-blob\ios/**",
"$(SRCROOT)\..\node_modules\react-native-svg\ios/**",
);
};
name = Release;


+ 12070
- 0
package-lock.json
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 5
- 1
package.json Visa fil

@@ -11,8 +11,12 @@
"react-native": "0.59.9",
"react-native-animatable": "^1.3.2",
"react-native-camera": "^1.12.0",
"react-native-code-push": "^5.6.0",
"code-push": "2.0.7",
"react-native-code-push": "5.6.1",
"react-native-device-info": "^2.1.2",
"react-native-shadow": "^1.2.2",
"react-native-snap-carousel": "^3.8.0",
"react-native-svg": "^9.6.2",
"react-native-swiper": "^1.5.14",
"rn-fetch-blob": "^0.10.15"
},


Laddar…
Avbryt
Spara