local book import

new setup activity
This commit is contained in:
mwang 2019-05-27 23:11:41 +08:00
parent 62113f9d9a
commit b2e85bbc9b
28 changed files with 599 additions and 186 deletions

View File

@ -31,7 +31,7 @@ android {
multiDexEnabled true //65535
manifestPlaceholders = [UMENG_CHANNEL_CALUE: "umeng"] //uMeng
flavorDimensions "default" //debug时注销
// flavorDimensions "default" //debug时注销
}
buildTypes {
debug {
@ -56,7 +56,7 @@ android {
// resource文件
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
applicationVariants.all { variant ->
/* applicationVariants.all { variant ->
variant.outputs.all { output ->
def outFile = output.outputFile
if (outFile != null && outFile.name.endsWith(".apk")) {
@ -66,12 +66,12 @@ android {
}
}
}
}*/
signingConfig signingConfigs.releaseConfig
}
}
//
productFlavors {
/*productFlavors {
// googleplay {}
qxs {
applicationId "com.novelbook.android.qxs"
@ -107,7 +107,7 @@ android {
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
}*/
android {
lintOptions {
abortOnError false
@ -124,6 +124,7 @@ android {
}
}
def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}

View File

@ -9,7 +9,8 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application
android:name=".MyApp"
android:allowBackup="true"
@ -37,20 +38,19 @@
android:name=".Activity_paihangbang"
android:label="@string/title_activity_paihangbang"
android:parentActivityName=".Main2Activity"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".Activity_ChgSource"
android:label="@string/title_Activity_ChgSource" />
<activity
android:name=".BookActivity"
android:label="@string/title_activity_book"
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".ReadActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".Main2Activity"
android:launchMode="singleTop"
@ -65,24 +65,27 @@
<activity
android:name=".FileActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".MarkActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".filechooser.FileChooserActivity"
android:label="@string/app_name"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".Activity_cache"
android:label="@string/title_download"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".AD.AdvertisementViewActivity"
android:label="@string/title_download"
android:theme="@style/ToolBarTheme.NoActionBar"></activity>
android:theme="@style/ToolBarTheme.NoActionBar" />
<activity
android:name=".ActivitySetup"
android:label="@string/title_setup"
android:theme="@style/ToolBarTheme.NoActionBar" />
<service
android:name=".service.ServiceDownload"
android:exported="false" />
@ -94,16 +97,14 @@
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
<!-- UMENG -->
<meta-data android:value="5cd6238a570df375c3000cc9" android:name="UMENG_APPKEY"/>
<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/>
<!--<meta-data android:value="debug" android:name="UMENG_CHANNEL"/>-->
<!-- <meta-data android:name="MAINHOST" android:value="${main_host}"/>
<meta-data android:name="DEFAULTHOST" android:value="${default_host}"/>-->
android:resource="@xml/provider_paths" />
</provider> <!-- UMENG -->
<meta-data
android:name="UMENG_APPKEY"
android:value="5cd6238a570df375c3000cc9" /> <!-- <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/> -->
<meta-data
android:name="UMENG_CHANNEL"
android:value="debug" />
</application>
</manifest>

View File

@ -0,0 +1,158 @@
package com.novelbook.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.novelbook.android.db.DownloadTask;
import com.novelbook.android.netutils.NetUtil;
import com.novelbook.android.service.ServiceDownload;
import com.novelbook.android.utils.CommonUtil;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.FileUtils;
import com.novelbook.android.utils.Fileutil;
import org.litepal.LitePal;
import butterknife.BindView;
import butterknife.OnClick;
import static com.novelbook.android.utils.Constants.lstNt;
public class ActivitySetup extends Activity_base {
static final String TAG = ActivitySetup.class.getSimpleName();
@BindView(R.id.tvCache)
TextView tvCache;
@BindView(R.id.tvVersion)
TextView tvVersion;
@Override
public int getLayoutRes() {
return R.layout.activity_setup;
}
@Override
protected void initViews() {
tvVersion.setText(CommonUtil.getVersion(this));
tvCache.setText(FileUtils.getCachedSize());
}
@Override
protected void setTitle() {
}
@Override
protected void initData() {
}
@Override
public void fillData() {
}
@OnClick({R.id.llAnouncement,R.id.llCache,R.id.llVersion})
void onSetupclick(View view){
switch (view.getId()) {
case R.id.llAnouncement:
break;
case R.id.llCache:
final AlertDialog.Builder normalDialog =
new AlertDialog.Builder(ActivitySetup.this);
normalDialog.setTitle("提示");
normalDialog.setMessage("是否清除所有缓存内容及下载任务?");
normalDialog.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ActivitySetup.this, ServiceDownload.class);
stopService(intent);
FileUtils.clearCache();
LitePal.deleteAll(DownloadTask.class);
tvCache.setText(FileUtils.getCachedSize());
}
});
normalDialog.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
}
});
normalDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
// 显示
normalDialog.show();
break;
case R.id.llVersion:
Constants.serverVersion =-1;
NetUtil.checkUpdate(false);
showProgressDialog(false,"正在检查版本...");
new Thread(){
@Override
public void run() {
Log.d(TAG, "prepare book to load options for search" );
int slept =0;
while( slept <100 && Constants.serverVersion ==-1){
try {
Thread.sleep(100);
slept++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if( Constants.serverVersion <= Constants.version ){
handler.sendEmptyMessage(MSG_VERSION_LATEST);
}else if(Constants.serverVersion==-1){
handler.sendEmptyMessage(MSG_VERSION_LATEST);
}
}
}.start();
break;
}
}
}

View File

@ -166,7 +166,8 @@ public abstract class Activity_base extends AppCompatActivity {
}
public abstract void fillData();
protected static final int MSG_VERSION_LATEST =4;
protected static final int MSG_VERSION_FAILE =5;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
@ -183,6 +184,12 @@ public abstract class Activity_base extends AppCompatActivity {
} else if (msg.what == 3) {
Toast.makeText(Activity_base.this, " ", Toast.LENGTH_LONG).show();
} else if (msg.what == MSG_VERSION_LATEST) {
Toast.makeText(Activity_base.this, "已是最新版本", Toast.LENGTH_LONG).show();
}else if (msg.what == MSG_VERSION_FAILE) {
Toast.makeText(Activity_base.this, "版本检查失败", Toast.LENGTH_LONG).show();
}
hideProgress();

View File

@ -251,6 +251,7 @@ void initTabs(){
//失败
Toast.makeText(getActivity(),"Novel 请求失败:"+errorMsg,Toast.LENGTH_SHORT).show();
// PageFactory.getInstance(activity ).prepareBook(novel ); //打开本地小说内容
pageFactory.prepareBook(novel );
// ReadActivity.openBook(novel ,activity);
handler.sendEmptyMessage(99);
}

View File

@ -54,16 +54,23 @@ public class BookMarkFragment extends BasicFragment implements MarkActivity.Sor
novelId = bundle.getInt(ARGUMENT);
}
bookMarksList = new ArrayList<>();
String domain =pageFactory.getSite().getDomain();
if(TextUtils.isEmpty(domain)){
Novel nv = LitePal.find(Novel.class,novelId);
if(nv!=null) {
if(pageFactory.getNovle().isLocalBook()){
bookMarksList = LitePal.where("novelId =?", novelId + "").order(String.format("id %s", isAsc ? "asc" : "desc")).find(BookMarks.class);
}else {
String domain = pageFactory.getSite().getDomain();
if (TextUtils.isEmpty(domain)) {
Novel nv = LitePal.find(Novel.class, novelId);
if (nv != null) {
domain = nv.getDomain();
}
}
if(null!=domain || !TextUtils.isEmpty(domain)){
bookMarksList = LitePal.where("novelId = ? and domain= ?", novelId+"",domain).order(String.format("id %s",isAsc ?"asc" :"desc")). find(BookMarks.class);
if (null != domain || !TextUtils.isEmpty(domain)) {
bookMarksList = LitePal.where("novelId = ? and domain= ?", novelId + "", domain).order(String.format("id %s", isAsc ? "asc" : "desc")).find(BookMarks.class);
}
}
Log.d(TAG, "initData: bookmark size " +bookMarksList.size());
markAdapter = new MarkAdapter(getActivity(), bookMarksList);

View File

@ -26,6 +26,7 @@ import android.widget.Toast;
import com.novelbook.android.Main2Activity;
import com.novelbook.android.R;
import com.novelbook.android.db.Chapter;
import com.novelbook.android.db.Novel;
import com.novelbook.android.filechooser.FileChooserActivity;
@ -37,6 +38,7 @@ import com.novelbook.android.netutils.OnSuccessAndFaultSub;
import com.novelbook.android.utils.CommonUtil;
import com.novelbook.android.utils.Constants;
import com.novelbook.android.utils.FileUtils;
import com.novelbook.android.utils.Fileutil;
import com.novelbook.android.utils.GsonUtil;
import com.novelbook.android.utils.ImageUtil;
import com.novelbook.android.utils.MyImageLoader;
@ -208,13 +210,27 @@ void test(int maxAge){
mAdapter = new BookListAdapter(activity,bookLists,R.layout.recycle_list_item,new OnItemClickListener()
{
private long lastTimeMillis;
private static final long MIN_CLICK_INTERVAL =1000;
protected boolean isTimeEnabled() {
long currentTimeMillis = System.currentTimeMillis();
if ((currentTimeMillis - lastTimeMillis) > MIN_CLICK_INTERVAL) {
lastTimeMillis = currentTimeMillis;
return true;
}
return false;
}
@Override
public void onItemClick(View view, int position)
{
if(isTimeEnabled()) {
Novel book = bookLists.get(position);
openBook(book,mAdapter);
openBook(book, mAdapter);
}else{
Log.d(TAG, "onclickInterval: bad click");
}
}
@ -333,20 +349,27 @@ void test(int maxAge){
bottomSheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet)
.setBackgroundColor(getResources().getColor(android.R.color.transparent));
TextView tvTitle =(TextView) bottomSheetDialog.findViewById(R.id.bdTitle);
TextView tvTitle = (TextView) bottomSheetDialog.findViewById(R.id.bdTitle);
TextView tvLatestChapt = (TextView) bottomSheetDialog.findViewById(R.id.txtLatestCate);
TextView tvAuthor = (TextView) bottomSheetDialog.findViewById(R.id.tvAuthor);
tvTitle.setText(bookLists.get(position).getName());
TextView tvAuthor =(TextView) bottomSheetDialog.findViewById(R.id.tvAuthor);
if (!bookLists.get(position).isLocalBook()) {
tvAuthor.setText(bookLists.get(position).getAuthor());
TextView tvLatest =(TextView) bottomSheetDialog.findViewById(R.id.txtLatestUpdate);
TextView tvLatestChapt =(TextView) bottomSheetDialog.findViewById(R.id.txtLatestCate);
TextView tvLatest = (TextView) bottomSheetDialog.findViewById(R.id.txtLatestUpdate);
tvLatestChapt.setText(bookLists.get(position).getChapterName());
tvLatest.setText(CommonUtil.getDateString( bookLists.get(position).getLastUpdateTime()) );
}else{
tvLatestChapt.setText("本地导入");
tvAuthor.setText("");
}
ImageView imageView = (ImageView) bottomSheetDialog.findViewById(R.id.imageG1);
ImageUtil.loadImage(activity,bookLists.get(position).getCover(),imageView);
LinearLayout lldetail=(LinearLayout) bottomSheetDialog.findViewById(R.id.llBookdetail);
if(!bookLists.get(position).isLocalBook())
lldetail.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showBookDetail(bookLists.get(position));
@ -355,16 +378,24 @@ void test(int maxAge){
TextView tvCache =(TextView) bottomSheetDialog.findViewById(R.id.tvCache);
tvCache.setText(FileUtils.getCacheSizeK(bookLists.get(position).getId()));
LinearLayout llClearCache =(LinearLayout) bottomSheetDialog.findViewById(R.id.llClearCache);
if(!bookLists.get(position).isLocalBook()) {
LinearLayout llClearCache = (LinearLayout) bottomSheetDialog.findViewById(R.id.llClearCache);
llClearCache.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
FileUtils.clearChapterCache(bookLists.get(position).getId());
long size = FileUtils.getCacheSize(bookLists.get(position).getId());
size = size/1024;
tvCache.setText(String.format("%sK",size));
Toast.makeText(activity,"缓存清除成功",Toast.LENGTH_SHORT);
size = size / 1024;
tvCache.setText(String.format("%sK", size));
Toast.makeText(activity, "缓存清除成功", Toast.LENGTH_SHORT);
}
});
}else{
TextView tvClearCache = (TextView) bottomSheetDialog.findViewById(R.id.tvClearCache);
tvClearCache.setText("导入文本");
}
LinearLayout lltop =(LinearLayout) bottomSheetDialog.findViewById(R.id.llTop);
TextView tvTop =(TextView) bottomSheetDialog.findViewById(R.id.tvTop);
@ -397,7 +428,7 @@ void test(int maxAge){
loadNovelsOnShelf();
mAdapter.setData(bookLists);
Toast.makeText(activity,"缓存清除成功",Toast.LENGTH_SHORT);
//Toast.makeText(activity,"缓存清除成功",Toast.LENGTH_SHORT);
}
});
@ -439,9 +470,9 @@ void test(int maxAge){
{
nv.delete();
LitePal.deleteAllAsync(Chapter.class,"novelId=?",nv.getId()+"");
//TODO: remove cache on a new thread
//Fileutil.deleteDir(file)
FileUtils.clearChapterCache(nv.getId());
}else{
Log.d(TAG, "shelfZhengliSubmit: to delete novel " + nv.getName());
nv.setToDefault("isOnShelf");

View File

@ -65,6 +65,8 @@ public class Main2Activity extends Activity_base
NavigationView navigationView;
@BindView(R.id.navigation )
BottomNavigationView botoomNavigation;
@BindView(R.id.drawer_layout)
DrawerLayout drawerLayout;
@BindView(R.id.rgSex)
RadioGroup rgSex;
// @BindView(R.id.tvUser)
@ -247,7 +249,7 @@ public class Main2Activity extends Activity_base
}
@Override
/* @Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
@ -255,7 +257,7 @@ public class Main2Activity extends Activity_base
} else {
super.onBackPressed();
}
}
}*/
@ -302,6 +304,9 @@ public class Main2Activity extends Activity_base
intent.putExtra(Intent.EXTRA_SUBJECT, "意见建议"); // 主题
intent.putExtra(Intent.EXTRA_TEXT, "请输入内容"); // 正文
startActivity(Intent.createChooser(intent, "请选择邮件应用"));
} else if (id == R.id.nav_setup) {
Intent intent = new Intent(Main2Activity.this,ActivitySetup.class);
startActivity(intent);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
@ -435,20 +440,17 @@ private int bottomSelectedIndex;
swithToolbarItems( );
}
long firstTime =0;
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if( navigationView.isShown()){
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawers();
return true;
}
int cnt=0;
long secondTime = System.currentTimeMillis();
if (secondTime - firstTime > 800) {//如果两次按键时间间隔大于800毫秒则不退出
String msg= "再按一次将退出" ;

View File

@ -52,7 +52,7 @@ public class MarkActivity extends Activity_base {
private ArrayList<Chapter> catalogueList = new ArrayList<>();*/
private DisplayMetrics dm;
private String EXTR_BOOK ="book";
// private String EXTR_BOOK ="book";
@Override
public int getLayoutRes() {
return R.layout.zactivity_mark;
@ -60,7 +60,10 @@ public class MarkActivity extends Activity_base {
@Override
protected void initViews() {
if(getFactory().getNovle().isLocalBook()) {
// btnRefresh.setEnabled(false);
btnRefresh.setVisibility(View.GONE);
}
}
@Override
@ -70,7 +73,7 @@ public class MarkActivity extends Activity_base {
@Override
protected void initData() {
pageFactory = PageFactory.getInstance(getApplicationContext());
pageFactory = getFactory();//PageFactory.getInstance(getApplicationContext());
Log.d(TAG, "prepareBook: pagefactory.mbook is ?" + (pageFactory.getNovle() .getName()) );
//config = Config.getInstance();
@ -152,6 +155,9 @@ public class MarkActivity extends Activity_base {
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.catalogemark, menu);
if(getFactory().getNovle().isLocalBook()) {
menu.findItem(R.id.action_change_source).setEnabled(false);
}
return true;
}
@ -173,4 +179,10 @@ public class MarkActivity extends Activity_base {
}
return super.onOptionsItemSelected(item);
}
PageFactory getFactory(){
if(pageFactory==null) {
pageFactory = PageFactory.getInstance(getApplicationContext());
}
return pageFactory;
}
}

View File

@ -472,6 +472,25 @@ public class ReadActivity extends Activity_base implements AdInterface {
mSpeechSynthesizer.resume();
}*/
startTime = (int) new Date().getTime();
if (book != null) {
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_BOOK)) {
Novel novel = (Novel) intent.getSerializableExtra(EXTRA_BOOK);
if (!pageFactory.isWorking() || novel.getId() != book.getId()) {
initData();
}else{
if( novel.getLastReadChapt()!=pageFactory.getCurrentChapter()){
pageFactory.changeChapter(novel.getLastReadChapt());
// hideReadSetting();
}
}
hideReadSetting();
}
}
}
@Override
@ -580,6 +599,13 @@ public class ReadActivity extends Activity_base implements AdInterface {
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.read, menu);
if(book!=null && book.isLocalBook()){
menu.findItem(R.id.action_change_source).setEnabled(false);
menu.findItem(R.id.action_refresh).setEnabled(false);
menu.findItem(R.id.action_bookdetail).setEnabled(false);
}
return true;
}
@ -614,7 +640,9 @@ public class ReadActivity extends Activity_base implements AdInterface {
bookMarks.setNovelId(pageFactory.getNovle().getId());
bookMarks.setChapt(pageFactory.getCurrentChapter());
bookMarks.setChaptName(((pageFactory.getChapters().get(bookMarks.getChapt()-1).getChapterName())));
if(!book.isLocalBook()) {
bookMarks.setDomain(pageFactory.getSite().getDomain());
}
bookMarks.save();
Toast.makeText(ReadActivity.this, "书签添加成功", Toast.LENGTH_SHORT).show();
@ -677,6 +705,13 @@ public class ReadActivity extends Activity_base implements AdInterface {
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.e("tag", "onNewINtent执行了");
setIntent(intent);
}
public static boolean openBook(final Novel book, Activity context) {
if (book == null){
@ -758,7 +793,7 @@ public class ReadActivity extends Activity_base implements AdInterface {
sb_progress.setProgress((int) (progress * 10000));
}
private void showReadSetting(){
public void showReadSetting(){
isShow = true;
// rl_progress.setVisibility(View.GONE);
@ -832,7 +867,7 @@ public class ReadActivity extends Activity_base implements AdInterface {
);
pageFactory.setBusy(true);
}
private void hideReadSetting() {
public void hideReadSetting() {
isShow = false;
Animation bottomAnim = AnimationUtils.loadAnimation(this, R.anim.dialog_exit);
Animation topAnim = AnimationUtils.loadAnimation(this, R.anim.dialog_top_exit);
@ -881,7 +916,7 @@ public class ReadActivity extends Activity_base implements AdInterface {
case R.id.tv_directory:
Intent intent = new Intent(ReadActivity.this, MarkActivity.class);
startActivity(intent);
finish();
// finish();
break;
case R.id.tv_dayornight:
changeDayOrNight();

View File

@ -28,6 +28,8 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.internal.Util;
import static com.novelbook.android.utils.ImageUtil.loader;
public class BookListAdapter extends RecyclerView.Adapter< RecyclerView.ViewHolder> {
private final int EMPTY_VIEW = 1;
private final int PROGRESS_VIEW = 2;
@ -221,8 +223,9 @@ public class BookListAdapter extends RecyclerView.Adapter< RecyclerView.ViewHol
if (holder.tvStatus != null) holder.tvStatus.setText(mDatas.get(position).getProgress());
if (holder.imageView != null && !TextUtils.isEmpty(mDatas.get(position).getCover())) {
ImageUtil.loadImage(context, mDatas.get(position).getCover(), holder.imageView);
if (holder.imageView != null/* && !TextUtils.isEmpty(mDatas.get(position).getCover())*/) {
// ImageUtil.loadImage(context, mDatas.get(position).getCover(), holder.imageView);
loader.displayImage(context, NetUtil.getCoverUrl(mDatas.get(position).getCover()) ,holder.imageView);
}
if (holder.imageTop != null) {
if( mDatas.get(position).isTop()){

View File

@ -222,7 +222,7 @@ public class HttpMethods {
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
//设置 Debug Log 模式
okHttpBuilder.addInterceptor(loggingInterceptor);
// okHttpBuilder.addInterceptor(new RetryInterceptor());

View File

@ -372,7 +372,7 @@ public class NetUtil {
// Log.e(TAG, "initHostConstants: update error ",er );
// }
}
static void checkUpdate(boolean isSilence){
public static void checkUpdate(boolean isSilence){
UpdateManager manager = new UpdateManager(Main2Activity.activityContext);
if(isSilence)

View File

@ -200,6 +200,7 @@ public class UpdateManager {
mHashMap = multiHashMap.get(packgename);
if (mHashMap != null) {
serviceCode = Integer.valueOf(mHashMap.get("version"));
Constants.serverVersion = serviceCode;
if(mHashMap.containsKey("minVersion"))
Constants.minVersion = Integer.valueOf(mHashMap.get("minVersion"));
// need update or not

View File

@ -12,5 +12,6 @@ public interface AdInterface {
public void showProgressbar(boolean dismissAble,String msg);
public void hideProgressbar();
public void showLoading(boolean isShow);
public void hideReadSetting();
public void showReadSetting();
}

View File

@ -101,6 +101,9 @@ public class BookUtil {
public void setChapters(List<Chapter> chapters) {
this.mChapters = chapters;
}
private final int MSG_FILLCONTENTDONE=1;
private final int MSG_READCHAPTER_FAIL=2;
private final int MSG_READCHAPTER_SUCCESS=3;
@ -134,8 +137,11 @@ public class BookUtil {
private Map<Integer,DownloadStatus> chaptDownStatus = new HashMap<Integer, DownloadStatus>();
DownloadStatus downloadStatus = DownloadStatus.notStart;
public Chapter getChapter(int chapId){
chapId = chapId >0 ?chapId : 1;
Log.d(TAG, String.format("prepare book getChapter: chaptId %s,mChapters.size() %s ",chapId,mChapters.size()));
if(chapId > mChapters.size() || mChapters.size() ==0){
return Chapter.getChapter(mNovel.getId(), mNovel.getDomain()==null?"":mNovel.getDomain(),chapId);
}else{
@ -358,7 +364,7 @@ public class BookUtil {
readChaptersAsync();
}else
{
handler.sendEmptyMessage(3);
handler.sendEmptyMessage(MSG_READCHAPTER_SUCCESS);
Log.d(TAG,String.format("prepare book loadChapts----end download %s 目录, 目录数量 %s, cost %s", mNovel.getName() , mChapters.size(), new Date().getTime() -startTime ));
mMuluStatus = MuluStatus.isDone;
Log.d(TAG, String.format("prepare book %s 章节信息完成.",mNovel.getName()) );
@ -848,7 +854,7 @@ int muluRetryCount =0;
//try next site
Message msg =Message.obtain();
msg.what =99;
msg.what =MSG_READCHAPTER_FAIL;
msg.arg1 =chapterNo;
Bundle bundleData = new Bundle();
@ -870,7 +876,7 @@ int muluRetryCount =0;
handler.sendMessage(msg);
// handler.sendEmptyMessage(99);
// handler.sendEmptyMessage(MSG_READCHAPTER_FAIL);
// readChaptersAsync();
@ -908,7 +914,7 @@ int muluRetryCount =0;
Log.d(TAG,String.format("prepare book loadChapts----end download %s 目录, 目录数量 %s, cost %s", mNovel.getName() , mChapters.size(), new Date().getTime() -startTime ));
mMuluStatus = MuluStatus.isDone;
Log.d(TAG, String.format("prepare book %s 章节信息完成.",mNovel.getName()) );
handler.sendEmptyMessage(3); //通知换源过程已读到目录
handler.sendEmptyMessage(MSG_READCHAPTER_SUCCESS); //通知换源过程已读到目录
} catch (IOException e) {
e.printStackTrace();
}finally {
@ -1218,6 +1224,7 @@ int muluRetryCount =0;
bookChapter.setNovelChapterStartPos(start);
bookChapter.setChapterName(str.replaceAll("###",""));
bookChapter.setNovelPath(bookPath);
bookChapter.setIndex(chaptId+1);
bookChapter.save();
int id= bookChapter.getId();
Log.d(TAG,str + " chaptId is " + id);
@ -1373,10 +1380,10 @@ int muluRetryCount =0;
void handlerMsg(Message msg){
if (msg.what == 123) {
if (msg.what == MSG_FILLCONTENTDONE) {
// isDownloadChapt =true;
Log.d(TAG,String.format("handler msg, download %s",true) );
}else if(msg.what==99){
}else if(msg.what==MSG_READCHAPTER_FAIL){
try {
Toast.makeText(mContext, "网络拥堵,已帮您切换其它源", Toast.LENGTH_LONG).show();
}catch (Exception e){
@ -1395,9 +1402,9 @@ int muluRetryCount =0;
// isDownloadChapt =true;
// Toast.makeText(mContext,"网络错误",Toast.LENGTH_LONG).show();
}else if(msg.what==3){ //change source
}else if(msg.what==MSG_READCHAPTER_SUCCESS){ //change source
isChangeSource =false;
Log.d(TAG, "changing Source:successed get chapters for " + mSite.getDomain() );
Log.d(TAG, "prepare book changing Source:successed get chapters for " + mSite.getDomain() );
/*if(isChangeSource){
Log.d(TAG, "changing Source:successed get chapters for " + mSite.getDomain() );
isChangeSource =false;
@ -1712,7 +1719,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
// return;
}*/
// handler.sendEmptyMessage(123);
// handler.sendEmptyMessage(MSG_FILLCONTENTDONE);
// handler.sendEmptyMessage(1);
@ -1765,7 +1772,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
writer.write(buf);
writer.close();
Log.d( TAG,String.format("prepare book loadChaptContent file created: %s, thread %s", file.getPath(), Thread.currentThread().getName()));
handler.sendEmptyMessage(123);
handler.sendEmptyMessage(MSG_FILLCONTENTDONE);
// setDownloadFlag(true);
} catch (IOException | JSONException e) {
e.printStackTrace();
@ -1777,7 +1784,7 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte
finally {
body.close();
handler.sendEmptyMessage(123);
handler.sendEmptyMessage(MSG_FILLCONTENTDONE);
// setDownloadFlag(true);
}
chapter.setNovelId(mNovel.getId());

View File

@ -33,5 +33,6 @@ public class Constants {
public static String email ="";
public static int minVersion =0;
public static int version =0;
public static int serverVersion =0;
public static String updateUrl="http://xiaoshuofenxiang.com/version.xml";;
}

View File

@ -122,4 +122,12 @@ public class FileUtils {
public static long getCacheSize(int noveId) {
return Fileutil.getDirSize(getNovelDir(noveId));
}
public static String getCachedSize(){
File f = new File(BookUtil.chapterPath);
return Fileutil.formatFileSize(Fileutil.getDirSize(f));
}
public static void clearCache(){
File f = new File(BookUtil.chapterPath);
Fileutil.deleteDir(f);
}
}

View File

@ -182,9 +182,10 @@ public class PageFactory implements ChangeSource{
private AdInterface mAd;
private BookTask bookTask;
private int MSG_NEXTPAGE=2;
private int MSG_HIDEPROGRESS=3;
private int MSG_NEXTPAGE_FAIL=4;
private final int MSG_CHANGECHAPTER =1;
private final int MSG_NEXTPAGE=2;
private final int MSG_HIDEPROGRESS=3;
private final int MSG_NEXTPAGE_FAIL=4;
public AdInterface getmAd() {
return mAd;
}
@ -196,7 +197,7 @@ public class PageFactory implements ChangeSource{
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "prepare book get handler msg:" +msg);
// Log.d(TAG, "prepare book get handler msg:" +msg);
handlerMsg(msg);
@ -240,6 +241,13 @@ public class PageFactory implements ChangeSource{
private List<TRPage> loadCurrentChapt(int chaptId){
Log.d(TAG, String.format("prepare book, loadCurrentChapt chaptId %s, getChapters().size() %s ,currentChapter %s",chaptId,getChapters().size() ,currentChapter) );
if ( getChapters().size()>0) { //待下载
chaptId = chaptId > getChapters().size() ? getChapters().size() : chaptId;
chaptId = chaptId > 0 ? chaptId : 1;
}
List<TRPage> chaptPages = new ArrayList<TRPage>();
chaptPages.add(new TRPage());
@ -319,7 +327,7 @@ public class PageFactory implements ChangeSource{
@Override
public void run() {
Log.d(TAG, String.format("prepare book to download chapter %s ,thread.name %s",chid,Thread.currentThread().getName() ) );
mBookUtil.chaptChars(chid); //TODO: 读取到上一章block后,file还是不存在的现在就死循环了
mBookUtil.chaptChars(chid); //TODO: 读取到上一章block后,file还是不存在的现在就死循环了 fixed
super.run();
}}.start();
@ -345,7 +353,7 @@ public class PageFactory implements ChangeSource{
}
Log.d(TAG, String.format("prepare book to download chapter %s ,handler notice changeChapter %s",chid, currentChapter ) );
//notice file done
handler.sendEmptyMessage(1);
handler.sendEmptyMessage(MSG_CHANGECHAPTER);
super.run();
@ -433,9 +441,9 @@ public class PageFactory implements ChangeSource{
page.setPageNo(pageNo);
chaptPages.add(page);
length= page.getEnd();
Log.d(TAG, String.format("prepare book build page %s ready for chapter %s,cost %s",pageNo, chaptId,new Date().getTime()-starttime1));
// Log.d(TAG, String.format("prepare book build page %s ready for chapter %s,cost %s",pageNo, chaptId,new Date().getTime()-starttime1));
}
Log.d(TAG, String.format(" prepare book build pages ready for chapter %s,cost %s", chaptId,new Date().getTime()-starttime));
// Log.d(TAG, String.format(" prepare book build pages ready for chapter %s,cost %s", chaptId,new Date().getTime()-starttime));
return chaptPages;
}
@ -709,6 +717,7 @@ private void hideSysUI(){
case FAIL:
status = "读取错误,请稍后重试";
mAd.showRefresh(View.VISIBLE);
mAd.showReadSetting();
try {
throw new Exception("error on reading");
} catch (Exception e) {
@ -853,7 +862,7 @@ private void hideSysUI(){
// Log.d(TAG, strLine);
// Log.d(TAG,"最后字符 。。。" +strLine.charAt(strLine.length()-1) + "");
lastLine =strLine;
if(( strLine.charAt(strLine.length()-1) + "" ).equals("\n")){
if(strLine.length()>0 && ( strLine.charAt(strLine.length()-1) + "" ).equals("\n")){
strLine =strLine.replace("\n","");
y += space;
space =m_fontSize + paragraphSpace;
@ -1018,6 +1027,7 @@ private void hideSysUI(){
return;
}
Log.d(TAG, "prepare book nextPage:chaptid " +mBookUtil.getChapterNo());
if (currentPage.getEnd() >= mBookUtil.getChapterLen()) {
Log.d(TAG,"已经是本章最后一页了");
File file =new File( mBookUtil.fileChapterName(currentChapter+1));
@ -1030,7 +1040,7 @@ private void hideSysUI(){
@Override
public void run() {
int slepttime = 0; mBookUtil.muluRetryCount=0;
while (slepttime<50 && mBookUtil.getChapters().size()==0 && (mBookUtil.mMuluStatus == BookUtil.MuluStatus.isDownloading || mBookUtil.muluRetryCount < Constants.retryCnt)) {
while (slepttime<80 && mBookUtil.getChapters().size()==0 && (mBookUtil.mMuluStatus == BookUtil.MuluStatus.isDownloading || mBookUtil.muluRetryCount < Constants.retryCnt)) {
try {
sleep(50);
slepttime++;
@ -1040,9 +1050,14 @@ private void hideSysUI(){
}
}
Log.d(TAG, String.format("prepare book waiting for chapters slept %s, chapt size %s " , slepttime *50,mBookUtil.getChapters().size()));
Log.d(TAG, String.format("prepare book waiting for chapters slept %s, chapt size %s, MuluStatus %s, muluRetryCount %s " ,
slepttime *50,mBookUtil.getChapters().size(),mBookUtil.mMuluStatus,mBookUtil.muluRetryCount));
if(mBookUtil.getChapters().size()>0){
if( mBookUtil.getChapterNo() == mBookUtil.getChapters().size()+1){
mBookUtil.setChapterNo(mBookUtil.getChapterNo()-1);
}
currentChapter=mBookUtil.getChapterNo();
handler.sendEmptyMessage(MSG_NEXTPAGE) ;
}else{
handler.sendEmptyMessage(MSG_NEXTPAGE_FAIL) ;
@ -1130,7 +1145,10 @@ private void hideSysUI(){
if(book==null){
return;
}
if(book.isLocalBook() || mBookUtil==null){ //离线书籍重新初始化加载mBookUtil
if(book.isLocalBook()){ //离线书籍重新初始化加载mBookUtil
mBookUtil = new BookUtil();
mBookUtil.setNovel(book);
}else if(mBookUtil==null){
mBookUtil = new BookUtil();
}
mBookUtil.setContext(context);
@ -1157,7 +1175,7 @@ private void hideSysUI(){
}
bookTask = new BookTask();
Log.d(TAG, String.format("prepare book 1 to open chapter %s ",book.getLastReadChapt() ) );
Log.d(TAG, String.format("prepare book 1 to open chapter %s ,position %s,source %s",book.getLastReadChapt() ,book.getLastReadPos(),book.getDomain()+book.getDomainName() ) );
bookTask.execute((long)book.getLastReadChapt(),book .getLastReadPos());
}
@ -1174,6 +1192,7 @@ private void hideSysUI(){
if (result) {
Log.d(TAG, String.format("prepare book ready, to open chapter %s ",chapter ) );
// m_mbBufLen = mBookUtil.getChapterLen();
currentChapter =(int)chapter;
mBookUtil.setChapterNo((int)chapter);
Log.d(TAG, String.format("prepare book ready, to open chapter, loadCurrentChapt %s ",chapter ) );
currentChaptPages = loadCurrentChapt((int)chapter);
@ -1212,6 +1231,7 @@ private void hideSysUI(){
try {
int slept=0;
while(getNovel() ==null){
// Log.d(TAG, "prepare book:waiting for bookutil book:" + getNovel());
Thread.sleep(10);
slept++;
}
@ -1290,7 +1310,7 @@ private void hideSysUI(){
trPage.setEnd(mBookUtil.getPosition());
return trPage;
*/
Log.d(TAG, String.format("prepare book getPageForBegin: chaptid %s, begin %s ",currentChapter,begin));
Log.d(TAG, String.format("prepare book getPageForBegin: currentChaptPages count %s, chaptid %s, begin %s ",currentChaptPages.size(),currentChapter,begin));
for(TRPage page : currentChaptPages)
{
if(page.getEnd() >begin){
@ -1531,7 +1551,7 @@ private void hideSysUI(){
*/
currentChapter = mBookUtil.getChapterNo();
// Log.d(TAG, String.format(" prepare book onDraw chapter after mBookUtil.getChapterNo(),currentChapter %s ",currentChapter ) );
Log.d(TAG, String.format(" prepare book onDraw chapter after mBookUtil.getChapterNo(),currentChapter %s ",currentChapter ) );
return currentChapter ;
}
@ -1581,13 +1601,21 @@ private void hideSysUI(){
if (getNovel() == null) {
return;
}
long position =0;
if(currentChapter == chapNum){
if( currentPage!=null){
position =currentPage.getBegin();
Log.d(TAG, "prepare book changeChapter: to position " + position);
}
}
preChaptPages =currentChaptPages;
currentChapter = chapNum;
mBookUtil.setChapterNo(currentChapter);
currentChaptPages = loadCurrentChapt(currentChapter ) ;
currentPage = getPageForBegin(0);
currentPage = getPageForBegin(position);
currentPage(true);
hideSysUI();
}
public void retryChapt(int chapNum){
fileRetryCnt.clear();

View File

@ -4,6 +4,7 @@
android:angle="135"
android:endColor="@color/colorPrimaryDark"
android:startColor="@color/colorPrimary"
android:type="linear" />
</shape>

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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=".Activity_paihangbang"
android:fitsSystemWindows="true"
android:clipToPadding="true"
>
<!-- 即toolbar悬浮在statusbar之后 https://blog.csdn.net/zafir6453/article/details/51344241-->
<android.support.design.widget.AppBarLayout
style="@style/barLayout">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/ToolBarTheme.PopupOverlay"
/>
</android.support.design.widget.AppBarLayout>
<LinearLayout
tools:context=".ActivitySetup"
android:orientation="vertical"
style="@style/llOutside"
android:paddingTop="10dp"
android:layout_marginTop="50dp"
>
<LinearLayout
style="@style/llSetup"
android:id="@+id/llAnouncement"
>
<TextView
style="@style/NovelBlockTitle"
android:id="@+id/tvAnnounce"
android:text="@string/title_anounce"
/>
<TextView
style="@style/tvRightMore"
android:textSize="20sp"
android:text=">"
/>
</LinearLayout>
<View style="@style/llGraySplit.2dp.gray" />
<LinearLayout
style="@style/llSetup"
android:id="@+id/llVersion"
>
<TextView
style="@style/NovelBlockTitle"
android:text="@string/title_checkVersion"
/>
<TextView
style="@style/NovelBlockTitle"
android:id="@+id/tvVersion"
android:text="1234455 "
android:gravity="right"
android:layout_marginRight="5dp"
/>
<TextView
style="@style/tvRightMore"
android:text=" "
/>
</LinearLayout>
<View style="@style/llGraySplit.2dp.gray" />
<LinearLayout
style="@style/llSetup"
android:id="@+id/llCache"
>
<TextView
style="@style/NovelBlockTitle"
android:text="@string/title_clearcache"
/>
<TextView
style="@style/NovelBlockTitle"
android:id="@+id/tvCache"
android:text="1234455 "
android:gravity="right"
android:layout_marginRight="5dp"
/>
<TextView
style="@style/tvRightMore"
android:text=" "
/>
</LinearLayout>
<View style="@style/llGraySplit.2dp.gray" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout >

View File

@ -147,6 +147,7 @@
android:textColor="#212121" />
<TextView
android:id="@+id/tvClearCache"
android:layout_width="wrap_content"
android:layout_height="20dp"

View File

@ -18,14 +18,14 @@
android:text="本地导入"
/>
<!--
<Button
<!-- <Button
style="@style/buttonCates"
android:text="切换视图"
/>
-->
<LinearLayout style="@style/llGraySplit.2dp"/>
<Button
<!-- <Button
android:id="@+id/btnUploadProgress"
style="@style/buttonCates"
android:text="上传进度"
@ -36,7 +36,7 @@
style="@style/buttonCates"
android:text="下载进度"
/>
<LinearLayout style="@style/llGraySplit.2dp"/>
<LinearLayout style="@style/llGraySplit.2dp"/>-->
<!--
<Button
style="@style/buttonCates"

View File

@ -38,7 +38,7 @@
android:src="@mipmap/star_active" />
<CheckBox
android:id="@+id/id_check_box"
android:id="@+id/id_check_box2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
@ -46,6 +46,9 @@
android:visibility="gone"
android:text=""/>
</FrameLayout>
<LinearLayout
android:layout_width="90dp"
android:layout_height="26dp">
<TextView
android:id="@+id/title"
style="@style/TextViewNovelTitle"
@ -53,7 +56,16 @@
android:layout_width="75dp"
android:gravity="top|center"
android:text="天龙八部天龙八部天龙八部"
android:layout_weight="1"
/>
<CheckBox
android:id="@+id/id_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="5dp"
android:visibility="gone"
android:layout_weight="0"
android:text=""/>
</LinearLayout>
</LinearLayout>

View File

@ -34,7 +34,6 @@
<item
android:id="@+id/nav_setup"
android:icon="@drawable/ic_settings_black_24dp"
android:visible="false"
android:title="设置" />
</group>

View File

@ -200,6 +200,10 @@
<string name="soft_updating">正在更新</string>
<string name="soft_update_cancel">取消更新</string>
<string name="action_novelDetail">详情</string>
<string name="title_anounce">免责声明</string>
<string name="title_checkVersion">检查更新</string>
<string name="title_clearcache">清除缓存</string>
<string name="title_setup">设置</string>
<string-array name="voicer_cloud_entries">
<item>小燕—女青、中英、普通话</item>

View File

@ -424,6 +424,16 @@
</style>
<style name="llSetup">
<item name="android:orientation">horizontal</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">60dp</item>
<item name="android:gravity">center_vertical</item>
<item name="android:background">@drawable/item_selector</item>
<item name="android:clickable">true</item>
</style>
</resources>

View File

@ -8,80 +8,38 @@
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="boDebug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleBoDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileBoDebugSources" />
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateBoDebugSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/src/bo/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/build/intermediates/javac/boDebug/compileBoDebugJavaWithJavac/classes" />
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/boDebugUnitTest/compileBoDebugUnitTestJavaWithJavac/classes" />
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes" />
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/bo/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/boDebug/compileBoDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/bo/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/boDebug/compileBoDebugRenderscript/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/bo/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/bo/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/boDebug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/bo/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/boDebugAndroidTest/compileBoDebugAndroidTestAidl/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/bo/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/boDebugAndroidTest/compileBoDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/bo/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/bo/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBoDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/bo/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBoDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/bo/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestBo/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testBo/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/compileDebugRenderscript/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/compileDebugAndroidTestAidl/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/compileDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@ -129,16 +87,25 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/apk_list" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/build-info" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundle_manifest" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/check_manifest_result" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/compatible_screen_manifest" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-apk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_app_manifest" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_run_app_info_output_file" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_run_main_apk_resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_run_merged_manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant_run_split_apk_resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javac" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/legacy_multidex_aapt_derived_proguard_rules" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/legacy_multidex_main_dex_list" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged-not-compiled-resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged_assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged_manifests" />
@ -147,12 +114,15 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/processed_res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-files" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res_stripped" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/resources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shader_assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/signing_config" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/split-apk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />