多渠道打包及主API过期策略
This commit is contained in:
		
							parent
							
								
									58f9f26eca
								
							
						
					
					
						commit
						65d75da6db
					
				|  | @ -2,6 +2,14 @@ apply plugin: 'com.android.application' | |||
| //apply plugin: 'com.jakewharton.butterknife' | ||||
| // apply plugin: 'com.neenbedankt.android-apt' | ||||
| android { | ||||
|     signingConfigs { | ||||
|         releaseConfig { | ||||
|             keyAlias 'key0' | ||||
|             keyPassword 'hello123' | ||||
|             storeFile file('E:/reading/android/asProjects/zhuike/mykeystore.jks') | ||||
|             storePassword 'hello123' | ||||
|         } | ||||
|     } | ||||
|     compileSdkVersion 28 | ||||
|     buildToolsVersion "28.0.3" | ||||
|     defaultConfig { | ||||
|  | @ -22,14 +30,15 @@ android { | |||
|         renderscriptSupportModeEnabled true     //blurkit | ||||
| 
 | ||||
|         multiDexEnabled true    //突破65535 | ||||
|         manifestPlaceholders = [UMENG_CHANNEL_CALUE:"umeng"]       //默认为uMeng | ||||
|         manifestPlaceholders = [UMENG_CHANNEL_CALUE: "umeng"]       //默认为uMeng | ||||
|    //  flavorDimensions "default"  //debug时注销 | ||||
|     } | ||||
| 
 | ||||
|     buildTypes { | ||||
|         debug { | ||||
|             // 显示Log | ||||
|             buildConfigField "boolean", "LOG_DEBUG", "true" | ||||
|             buildConfigField "String", "MAIN_HOST", '"http://xiaoshuofenxiang.com/api/"' | ||||
|             buildConfigField "String", "API_HOST", '"{\\"master\\":[\\"http:\\\\/\\\\/xiaoshuofenxiang.com\\"],\\"page\\":[\\"http:\\\\/\\\\/p.xiaoshuofenxiang.com\\"],\\"report\\":[\\"http:\\\\/\\\\/r.xiaoshuofenxiang.com\\"],\\"search\\":[\\"http:\\\\/\\\\/s.xiaoshuofenxiang.com\\"],\\"novel\\":[\\"http:\\\\/\\\\/n.xiaoshuofenxiang.com\\"],\\"novelsbydot\\":[\\"http:\\\\/\\\\/nbd.xiaoshuofenxiang.com\\"],\\"user\\":[\\"http:\\\\/\\\\/u.xiaoshuofenxiang.com\\"]}"' | ||||
|             versionNameSuffix "-debug" | ||||
|             minifyEnabled false | ||||
|             zipAlignEnabled false | ||||
|  | @ -43,47 +52,64 @@ android { | |||
|             minifyEnabled true | ||||
|             //Zipalign优化 | ||||
|             zipAlignEnabled true | ||||
| 
 | ||||
|             // 移除无用的resource文件 | ||||
|             shrinkResources true | ||||
| 
 | ||||
| 
 | ||||
|             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||||
|        /*      applicationVariants.all{ variant -> | ||||
|                 variant.outputs.all{ output -> | ||||
|      /*       applicationVariants.all { variant -> | ||||
|                 variant.outputs.all { output -> | ||||
|                     def outFile = output.outputFile | ||||
|                     if (outFile != null && outFile.name.endsWith(".apk")){ | ||||
|                         def fileName = "${variant.productFlavors[0].name}" + "${releaseTime()}" + ".apk" | ||||
|                     if (outFile != null && outFile.name.endsWith(".apk")) { | ||||
|                         def fileName = "${variant.productFlavors[0].name}" + "-${defaultConfig.versionName}-" + "${releaseTime()}" + ".apk" | ||||
|                         outputFileName = fileName; | ||||
|                         // output.outputFile = new File(outFile.parent, fileName); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|             }*/ | ||||
|             signingConfig signingConfigs.releaseConfig | ||||
|         } | ||||
|     } | ||||
|     //渠道 | ||||
|    /* productFlavors { | ||||
|         // googleplay {} | ||||
|             huawei { applicationId "com.novelbook.android.huawei" | ||||
|                 versionName "version-a-1.0"} | ||||
|             xiaomi { applicationId "com.novelbook.android.xiaomi" | ||||
|                 versionName "version-a-1.0"} | ||||
|         A { | ||||
|             applicationId "com.novelbook.android.a" | ||||
|             versionName "version-a-1.0" | ||||
|             buildConfigField "String", "MAIN_HOST", '"http://xiaoshuofenxiang.com/api/"' | ||||
|             buildConfigField "String", "API_HOST", '"{\\"master\\":[\\"http:\\\\/\\\\/xiaoshuofenxiang.com\\"],\\"page\\":[\\"http:\\\\/\\\\/p.xiaoshuofenxiang.com\\"],\\"report\\":[\\"http:\\\\/\\\\/r.xiaoshuofenxiang.com\\"],\\"search\\":[\\"http:\\\\/\\\\/s.xiaoshuofenxiang.com\\"],\\"novel\\":[\\"http:\\\\/\\\\/n.xiaoshuofenxiang.com\\"],\\"novelsbydot\\":[\\"http:\\\\/\\\\/nbd.xiaoshuofenxiang.com\\"],\\"user\\":[\\"http:\\\\/\\\\/u.xiaoshuofenxiang.com\\"]}"' | ||||
| 
 | ||||
|         } | ||||
|         B { | ||||
|             applicationId "com.novelbook.android.b" | ||||
|             versionName "version-b-1.0" | ||||
|             buildConfigField "String", "MAIN_HOST", '"http://xiaoshuofenxiang.com/api/"' | ||||
|             buildConfigField "String", "API_HOST", '"{\\"master\\":[\\"http:\\\\/\\\\/xiaoshuofenxiang.com\\"],\\"page\\":[\\"http:\\\\/\\\\/p.xiaoshuofenxiang.com\\"],\\"report\\":[\\"http:\\\\/\\\\/r.xiaoshuofenxiang.com\\"],\\"search\\":[\\"http:\\\\/\\\\/s.xiaoshuofenxiang.com\\"],\\"novel\\":[\\"http:\\\\/\\\\/n.xiaoshuofenxiang.com\\"],\\"novelsbydot\\":[\\"http:\\\\/\\\\/nbd.xiaoshuofenxiang.com\\"],\\"user\\":[\\"http:\\\\/\\\\/u.xiaoshuofenxiang.com\\"]}"' | ||||
| 
 | ||||
|         } | ||||
|         C { | ||||
|             applicationId "com.novelbook.android.c" | ||||
|             versionName "version-c-1.0" | ||||
|             buildConfigField "String", "MAIN_HOST", '"http://xiaoshuofenxiang.com/api/"' | ||||
|             buildConfigField "String", "API_HOST", '"{\\"master\\":[\\"http:\\\\/\\\\/xiaoshuofenxiang.com\\"],\\"page\\":[\\"http:\\\\/\\\\/p.xiaoshuofenxiang.com\\"],\\"report\\":[\\"http:\\\\/\\\\/r.xiaoshuofenxiang.com\\"],\\"search\\":[\\"http:\\\\/\\\\/s.xiaoshuofenxiang.com\\"],\\"novel\\":[\\"http:\\\\/\\\\/n.xiaoshuofenxiang.com\\"],\\"novelsbydot\\":[\\"http:\\\\/\\\\/nbd.xiaoshuofenxiang.com\\"],\\"user\\":[\\"http:\\\\/\\\\/u.xiaoshuofenxiang.com\\"]}"' | ||||
| 
 | ||||
|         } | ||||
|         D { | ||||
|             applicationId "com.novelbook.android.d" | ||||
|             versionName "version-d-1.0" | ||||
|             buildConfigField "String", "MAIN_HOST", '"http://xiaoshuofenxiang.com/api/"' | ||||
|             buildConfigField "String", "API_HOST", '"{\\"master\\":[\\"http:\\\\/\\\\/xiaoshuofenxiang.com\\"],\\"page\\":[\\"http:\\\\/\\\\/p.xiaoshuofenxiang.com\\"],\\"report\\":[\\"http:\\\\/\\\\/r.xiaoshuofenxiang.com\\"],\\"search\\":[\\"http:\\\\/\\\\/s.xiaoshuofenxiang.com\\"],\\"novel\\":[\\"http:\\\\/\\\\/n.xiaoshuofenxiang.com\\"],\\"novelsbydot\\":[\\"http:\\\\/\\\\/nbd.xiaoshuofenxiang.com\\"],\\"user\\":[\\"http:\\\\/\\\\/u.xiaoshuofenxiang.com\\"]}"' | ||||
| 
 | ||||
|         } | ||||
|         //批量配置 | ||||
|         productFlavors.all { flavor -> | ||||
|             flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] | ||||
|         } | ||||
| 
 | ||||
|         } | ||||
| */ | ||||
| 
 | ||||
|     }*/ | ||||
|     android { | ||||
|         lintOptions { | ||||
|             abortOnError false | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     sourceSets { | ||||
|         main { | ||||
|             jniLibs.srcDirs = ['libs'] | ||||
|  | @ -94,12 +120,11 @@ android { | |||
|         targetCompatibility JavaVersion.VERSION_1_8 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| def releaseTime() { | ||||
|     return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) | ||||
|     return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC")) | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation fileTree(include: ['*.jar'], dir: 'libs') | ||||
|     implementation 'com.android.support:appcompat-v7:28.0.0' | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ | |||
|             android:label="@string/title_Activity_ChgSource" /> | ||||
|         <activity | ||||
|             android:name=".BookActivity" | ||||
| 
 | ||||
|             android:label="@string/title_activity_book" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar" /> | ||||
|         <activity | ||||
|  | @ -52,6 +53,7 @@ | |||
|         <activity | ||||
|             android:name=".Main2Activity" | ||||
|             android:launchMode="singleTop" | ||||
|             android:screenOrientation="portrait" | ||||
|             android:theme="@style/ToolBarTheme.NoActionBar"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|  | @ -84,7 +86,9 @@ | |||
|         <!--  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}"/>--> | ||||
|     </application> | ||||
| 
 | ||||
| </manifest> | ||||
|  | @ -2,7 +2,7 @@ | |||
| <litepal> | ||||
|     <dbname value="book" ></dbname> | ||||
| 
 | ||||
|     <version value="15" ></version> | ||||
|     <version value="16" ></version> | ||||
| 
 | ||||
|     <list> | ||||
|         <mapping class="com.novelbook.android.db.Chapter"></mapping> | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| package com.novelbook.android; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.os.Build; | ||||
| import android.support.v4.app.Fragment; | ||||
| import android.support.v7.widget.LinearLayoutManager; | ||||
|  | @ -42,8 +43,9 @@ public class Activity_ChgSource extends Activity_base { | |||
|     public final static String EXTR_ID="id"; | ||||
|     public final static String EXTR_SITE="site"; | ||||
|     //public static final String EXTR_NAME ="" ; | ||||
|     public final static String EXTR_cate ="cate"; | ||||
|     PageFactory pageFactory; | ||||
| 
 | ||||
|     boolean isFromCate; | ||||
|     List<Site> mSites; | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -69,6 +71,9 @@ public class Activity_ChgSource extends Activity_base { | |||
|         chaptId = getIntent().getIntExtra(EXTR_ID,1); | ||||
| 
 | ||||
|         domain =   getIntent().getStringExtra(EXTR_SITE); | ||||
| 
 | ||||
|         isFromCate =getIntent().getBooleanExtra(EXTR_cate,false); | ||||
| 
 | ||||
|      //   name =   getIntent().getStringExtra(EXTR_NAME); | ||||
|         this.setTitle(chaptTitle); | ||||
|     } | ||||
|  | @ -84,8 +89,15 @@ public class Activity_ChgSource extends Activity_base { | |||
| 
 | ||||
|                  Site site = mSites.get(position); | ||||
|                 Log.d(TAG, String.format("changing Source:target site name %s, site domain %s  " ,site.getName(), site.getDomain())); | ||||
|                  pageFactory.changeSource(site.getName(),site.getDomain(),chaptId,chaptTitle); | ||||
| 
 | ||||
|                 if(isFromCate){ | ||||
|                     pageFactory.changeSourceForCate(site.getName(),site.getDomain()); | ||||
|                     Intent intent = new Intent(Activity_ChgSource.this, MarkActivity.class); | ||||
|                     //    intent.putExtra(Activity_ChgSource.EXTR_NAME, pageFactory.getSite().getName()); | ||||
|                     startActivity(intent); | ||||
|                 }else{ | ||||
|                     pageFactory.changeSource(site.getName(),site.getDomain(),chaptId,chaptTitle); | ||||
|                 } | ||||
|                   finish(); | ||||
|             } | ||||
|         }); | ||||
|  |  | |||
|  | @ -97,6 +97,12 @@ public abstract  class Activity_base extends AppCompatActivity { | |||
|         hideProgress(); | ||||
|      //   MobclickAgent.onPause(this); | ||||
|     } | ||||
|     protected void closeCurrentActitivty(){ | ||||
|         if( this instanceof BookActivity ) { | ||||
|            // return; | ||||
|         } | ||||
|         finish(); | ||||
|     } | ||||
|     protected BookListAdapter getBookListAdapter(List<Novel> mDatas,int itemResourceId){ | ||||
|         BookListAdapter mAdapter = new BookListAdapter(this ,mDatas,itemResourceId,new  OnItemClickListener() | ||||
|         { | ||||
|  | @ -107,7 +113,7 @@ public abstract  class Activity_base extends AppCompatActivity { | |||
| 
 | ||||
|              //   showBook("射雕" +position); | ||||
|                 showBookDetail(mDatas.get(position)); | ||||
|                 finish(); | ||||
|                 closeCurrentActitivty(); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|  |  | |||
|  | @ -221,9 +221,11 @@ public class BookActivity extends   Activity_base { | |||
|             return; | ||||
|         } | ||||
|         rvBooklistAuthor.setVisibility(View.VISIBLE); | ||||
| //        mAdapterAuthor = getBookListAdapter(mDataAuthor,R.layout.recycle_list_item_horizon); | ||||
| //        rvBooklistAuthor.setLayoutManager(new LinearLayoutManager(this)); | ||||
|         mAdapterAuthor = getBookListAdapter(mDataAuthor,R.layout.recycle_list_item_horizon); | ||||
| 
 | ||||
|         rvBooklistAuthor.setLayoutManager(new LinearLayoutManager(this)); | ||||
| 
 | ||||
|         rvBooklistAuthor.setAdapter(mAdapterAuthor); | ||||
| 
 | ||||
|     } | ||||
|  | @ -237,10 +239,10 @@ public class BookActivity extends   Activity_base { | |||
|             return; | ||||
|         } | ||||
|         rvBooklistRelated.setVisibility(View.VISIBLE); | ||||
|         mAdapterRelated = getBookListAdapter(mDataRelated,R.layout.recycle_list_item); | ||||
| 
 | ||||
|         rvBooklistRelated.setLayoutManager(new GridLayoutManager(this, Constants.NOVEL_SPAN_CNT)); | ||||
| 
 | ||||
|       /*  mAdapterRelated = getBookListAdapter(mDataRelated,R.layout.recycle_list_item); | ||||
|         rvBooklistRelated.setLayoutManager(new GridLayoutManager(this, Constants.NOVEL_SPAN_CNT));*/ | ||||
|         mAdapterRelated = getBookListAdapter(mDataRelated,R.layout.recycle_list_item_horizon); | ||||
|         rvBooklistRelated.setLayoutManager(new LinearLayoutManager(this)); | ||||
|         rvBooklistRelated.setAdapter(mAdapterRelated); | ||||
|     } | ||||
|     /** | ||||
|  | @ -707,6 +709,7 @@ void onResponseProcess( String content ,String url){ | |||
|             if( pageFactory.isWorking() && ( pageFactory.getNovle()==null || mNovel.getId() !=pageFactory.getNovle().getId())){ | ||||
|                 pageFactory.prepareBook(mNovel); | ||||
|             } | ||||
|             setShelfButtonText(); | ||||
|         } | ||||
| 
 | ||||
|         // View v =findViewById(R.id.head_img); | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ package com.novelbook.android.Fragments; | |||
| import android.app.AlertDialog; | ||||
| import android.content.DialogInterface; | ||||
| import android.os.Bundle; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
| import android.view.View; | ||||
| import android.widget.AdapterView; | ||||
|  | @ -27,6 +28,7 @@ import butterknife.BindView; | |||
|  * Created by Administrator on 2016/8/31 0031. | ||||
|  */ | ||||
| public class BookMarkFragment extends BasicFragment  implements MarkActivity.Sortmark{ | ||||
|     public static String TAG=BookMarkFragment.class.getSimpleName(); | ||||
|     public static final String ARGUMENT = "argument"; | ||||
| 
 | ||||
|     @BindView(R.id.lv_bookmark) | ||||
|  | @ -51,7 +53,14 @@ public class BookMarkFragment extends BasicFragment  implements MarkActivity.Sor | |||
|             novelId = bundle.getInt(ARGUMENT); | ||||
|         } | ||||
|         bookMarksList = new ArrayList<>(); | ||||
|         bookMarksList = LitePal.where("novelId = ? and domain= ?", novelId+"",pageFactory.getSite().getDomain()).order(String.format("id %s",isAsc ?"asc" :"desc")). find(BookMarks.class); | ||||
|         String domain =pageFactory.getSite().getDomain(); | ||||
|         if(TextUtils.isEmpty(domain)){ | ||||
|             Novel nv = LitePal.find(Novel.class,novelId); | ||||
|           if(nv!=null) { | ||||
|               domain = nv.getDomain(); | ||||
|           } | ||||
|         } | ||||
|         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); | ||||
|         lv_bookmark.setAdapter(markAdapter); | ||||
|  |  | |||
|  | @ -154,7 +154,16 @@ public class CatalogFragment extends BasicFragment implements MarkActivity.Sortc | |||
|             @Override | ||||
|             public void run() { | ||||
|              //   ArrayList<Chapter> list  =(ArrayList<Chapter>) LitePal.where("novelId=? and domain =? " ,pageFactory.getNovle().getId()+"",pageFactory.getSite().getDomain()).find(Chapter.class); | ||||
|                 ArrayList<Chapter> list  =(ArrayList<Chapter>) LitePal.where("novelId=? and domain =? " ,pageFactory.getNovle().getId()+"",pageFactory.getNovle().getDomain()).find(Chapter.class); | ||||
| 
 | ||||
|                 String domain =pageFactory.getNovle().getDomain(); | ||||
|                 if(TextUtils.isEmpty(domain)){ | ||||
|                   domain=""; | ||||
|                 } | ||||
| 
 | ||||
|                 ArrayList<Chapter> list  = new ArrayList<Chapter>(); | ||||
|                 if(!TextUtils.isEmpty(domain)) { | ||||
|                     list = (ArrayList<Chapter>) LitePal.where("novelId=? and domain =? ", pageFactory.getNovle().getId() + "", domain).find(Chapter.class); | ||||
|                   } | ||||
|                 File file; | ||||
|                 for(Chapter cp : list){ | ||||
|                     if(!TextUtils.isEmpty(cp.getChapterPath())) { | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ import okhttp3.ResponseBody; | |||
| 
 | ||||
| 
 | ||||
| public class Fragment_Shelf extends BasicFragment { | ||||
| 
 | ||||
|     public static String TAG=Fragment_Shelf.class.getSimpleName(); | ||||
|     public static String getFTag() { | ||||
|         return "com.novelbook.android.Fragments.Fragment_Shelf"; | ||||
|     } | ||||
|  | @ -448,6 +448,7 @@ void test(int maxAge){ | |||
|                     }else{ | ||||
|                         Log.d(TAG, "shelfZhengliSubmit: to delete novel " + nv.getName()); | ||||
|                         nv.setToDefault("isOnShelf"); | ||||
|                         nv.setToDefault("isTop"); | ||||
|                         //nv.setOnShelf(false); | ||||
|                         nv.update(nv.getId()); | ||||
|                         // nv.update(nv.getId()); //not work,,,If you set a default value to a field, the corresponding  column won't be updated. | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ import butterknife.BindView; | |||
| 
 | ||||
| public class Fragment_bookStore extends BasicFragment { | ||||
| 
 | ||||
| 
 | ||||
|     public static String TAG=Fragment_bookStore.class.getSimpleName(); | ||||
|     public static String getFTag() { | ||||
|         return "com.novelbook.android.Fragments.Fragment_bookStore"; | ||||
|     } | ||||
|  |  | |||
|  | @ -61,7 +61,7 @@ import butterknife.OnClick; | |||
| 
 | ||||
| 
 | ||||
| public class Fragment_jingxuan extends BasicFragment implements OnBannerListener { | ||||
| 
 | ||||
|     public static String TAG=Fragment_jingxuan.class.getSimpleName(); | ||||
| 
 | ||||
|     private String mParam1; | ||||
|     private String mParam2; | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ import butterknife.ButterKnife; | |||
| import butterknife.OnClick; | ||||
| 
 | ||||
| public class Fragment_jingxuan_tuijian extends BasicFragment { | ||||
| 
 | ||||
|     public static String TAG=Fragment_jingxuan.class.getSimpleName(); | ||||
|     @BindView(R.id.imageGallary1) | ||||
|     ImageView imageView1; | ||||
|     @BindView(R.id.imageGallary2) | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ import butterknife.BindView; | |||
| 
 | ||||
| 
 | ||||
| public class Fragment_shudan extends BasicFragment { | ||||
|     public static String TAG=Fragment_shudan.class.getSimpleName(); | ||||
| 
 | ||||
|     @BindView(R.id.fab) | ||||
|     FloatingActionButton fab; | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ import com.novelbook.android.Fragments.Fragment_bookStore; | |||
| import com.novelbook.android.Fragments.Fragment_booklist; | ||||
| import com.novelbook.android.Fragments.Fragment_paihang; | ||||
| import com.novelbook.android.netsubscribe.BookSubscribe; | ||||
| import com.novelbook.android.netutils.NetUtil; | ||||
| import com.novelbook.android.netutils.OnSuccessAndFaultListener; | ||||
| import com.novelbook.android.netutils.OnSuccessAndFaultSub; | ||||
| import com.novelbook.android.service.ServiceDownload; | ||||
|  | @ -40,6 +41,8 @@ import com.novelbook.android.utils.PageFactory; | |||
| 
 | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.util.Date; | ||||
| 
 | ||||
| import butterknife.BindView; | ||||
| import butterknife.OnClick; | ||||
| 
 | ||||
|  | @ -72,7 +75,7 @@ public class Main2Activity extends Activity_base | |||
| 
 | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|        getHostPolicy(); | ||||
|        NetUtil.getHostPolicy(); | ||||
|         super.onCreate(savedInstanceState); | ||||
|       //PageFactory.createPageFactory(this); | ||||
|         app =(MyApp) getApplicationContext(); | ||||
|  | @ -536,33 +539,5 @@ private  int bottomSelectedIndex; | |||
| 
 | ||||
| //----get master domain | ||||
| 
 | ||||
|     private void getHostPolicy(){  //TODO: get masterdomain info | ||||
|         BookSubscribe.getMastDomain(new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { | ||||
|             @Override | ||||
|             public void onSuccess(String result) { | ||||
| 
 | ||||
|                 // mFirstPage= gson.fromJson(result, FirstPage.class); | ||||
|                 try { | ||||
|                     JSONObject jsonObject = new JSONObject(result); | ||||
|                     String resultstr = jsonObject.getString("hosts"); | ||||
|                     Config config =Config.createConfig(Main2Activity.this); | ||||
|                     config.setBaseUrl(resultstr); | ||||
|                    // config.setRootUrl( jsonObject.getString("masterDomains")); | ||||
| 
 | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|                 handler.sendEmptyMessage(1); | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onFault(String errorMsg) { | ||||
|                 //失败 | ||||
|                 Log.d(TAG, "error on get firstpage: " + errorMsg); | ||||
|                 handler.sendEmptyMessage(2); | ||||
|             } | ||||
|         }, this)); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -1,11 +1,14 @@ | |||
| package com.novelbook.android; | ||||
| 
 | ||||
| import android.content.Intent; | ||||
| import android.graphics.Typeface; | ||||
| import android.support.design.widget.AppBarLayout; | ||||
| import android.support.v4.view.ViewPager; | ||||
| import android.support.v7.widget.Toolbar; | ||||
| import android.util.DisplayMetrics; | ||||
| import android.util.Log; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.widget.ImageButton; | ||||
| 
 | ||||
|  | @ -144,4 +147,29 @@ public class MarkActivity extends Activity_base { | |||
|         public void sortList(); | ||||
|         public void refresh(); | ||||
|     } | ||||
|     @Override | ||||
|     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); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         // Handle action bar item clicks here. The action bar will | ||||
|         // automatically handle clicks on the Home/Up button, so long | ||||
|         // as you specify a parent activity in AndroidManifest.xml. | ||||
|         int id = item.getItemId(); | ||||
| 
 | ||||
|         if (id == R.id.action_change_source) { | ||||
|             Intent intent = new Intent(MarkActivity.this, Activity_ChgSource.class); | ||||
|             intent.putExtra(Activity_ChgSource.EXTR_ID, pageFactory.getChapter().getIndex()); | ||||
|             intent.putExtra(Activity_ChgSource.EXTR_TITLE, pageFactory.getChapter().getChapterName()); | ||||
|             intent.putExtra(Activity_ChgSource.EXTR_SITE, pageFactory.getChapter().getDomain()); | ||||
|              intent.putExtra(Activity_ChgSource.EXTR_cate,true); | ||||
|             startActivity(intent); | ||||
|             finish(); | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -18,14 +18,17 @@ public class MyApp extends Application { | |||
|     @Override | ||||
|     public void onCreate() { | ||||
|         super.onCreate(); | ||||
|         HttpMethods.USERAGENT = NetUtil.getUserAgent(); | ||||
|         applicationContext = getApplicationContext(); | ||||
|         HttpMethods.USERAGENT = NetUtil.getUserAgent(); | ||||
|         HttpMethods.LOCALUSERAGENT = NetUtil.getUserAgent(applicationContext); | ||||
| 
 | ||||
|         Config.createConfig(this); | ||||
|         PageFactory.createPageFactory(this); | ||||
|         LogcatHelper.getInstance(this).start(); | ||||
| 
 | ||||
|        // BlurKit.init(this); | ||||
|         LitePal.initialize(this); | ||||
|         initApi(); | ||||
|     } | ||||
| 
 | ||||
|     public void initApi(){ | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ import com.novelbook.android.utils.Config; | |||
| import com.novelbook.android.utils.Constants; | ||||
| import com.novelbook.android.utils.PageFactory; | ||||
| import com.novelbook.android.view.PageWidget; | ||||
| import com.umeng.analytics.MobclickAgent; | ||||
| 
 | ||||
| import org.litepal.LitePal; | ||||
| 
 | ||||
|  | @ -55,7 +56,9 @@ import java.io.IOException; | |||
| import java.text.DecimalFormat; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import butterknife.BindView; | ||||
| import butterknife.OnClick; | ||||
|  | @ -121,7 +124,7 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|     private PageModeDialog mPageModeDialog; | ||||
|     private Boolean mDayOrNight; | ||||
|     // 语音合成客户端 | ||||
|     private SpeechSynthesizer mSpeechSynthesizer; | ||||
|   //  private SpeechSynthesizer mSpeechSynthesizer; | ||||
|     private boolean isSpeaking = false; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -225,7 +228,7 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|         bookpage.setPageMode(config.getPageMode()); | ||||
|         pageFactory.setPageWidget(bookpage); | ||||
|         sb_progress.setVisibility(book.isLocalBook()?View.VISIBLE:View.INVISIBLE); | ||||
|         Log.d(TAG, String .format("prepare Book: set pagewidget %s" ,  book.getName())); | ||||
|         Log.d(TAG, String .format("prepare book: set pagewidget %s, to open book" ,  book.getName())); | ||||
|         try { | ||||
| 
 | ||||
|             hideSystemUI(); | ||||
|  | @ -457,35 +460,46 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     int startTime =0; | ||||
|     @Override | ||||
|     protected void onResume(){ | ||||
|         super.onResume(); | ||||
|         if (!isShow){ | ||||
|             hideSystemUI(); | ||||
|         } | ||||
|         if (mSpeechSynthesizer != null){ | ||||
|       /*  if (mSpeechSynthesizer != null){ | ||||
|             mSpeechSynthesizer.resume(); | ||||
|         } | ||||
|         }*/ | ||||
|         startTime  = (int) new Date().getTime(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onPause() { | ||||
|         super.onPause(); | ||||
|         Map<String, String> map_value = new HashMap<String, String>(); | ||||
|         map_value.put("bookname" , book!=null ?  book.getName():"noname" ); | ||||
|         MobclickAgent.onEventValue(MyApp.applicationContext, "novel_reading_time" , map_value, (int) new Date().getTime() - startTime); | ||||
| 
 | ||||
|     } | ||||
|     @Override | ||||
|     protected void onStop(){ | ||||
|         super.onStop(); | ||||
|         if (mSpeechSynthesizer != null){ | ||||
|      /*   if (mSpeechSynthesizer != null){ | ||||
|             mSpeechSynthesizer.stop(); | ||||
|         } | ||||
|         }*/ | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onDestroy() { | ||||
|         super.onDestroy(); | ||||
|         pageFactory.clear(); | ||||
|        // pageFactory.clear(); | ||||
|         bookpage = null; | ||||
|         unregisterReceiver(myReceiver); | ||||
|         isSpeaking = false; | ||||
|         if (mSpeechSynthesizer != null){ | ||||
|        /* if (mSpeechSynthesizer != null){ | ||||
|             mSpeechSynthesizer.release(); | ||||
|         } | ||||
|         }*/ | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -509,8 +523,12 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
| 
 | ||||
| 
 | ||||
|             if(!pageFactory.canExitSilent()){ | ||||
|                 if(book.isOnShelf()){ | ||||
|                     finish(); | ||||
|                 }else { | ||||
|                     showNormalDialog(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|         return super.onKeyDown(keyCode, event); | ||||
|  | @ -524,19 +542,25 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|         final AlertDialog.Builder normalDialog = | ||||
|                 new AlertDialog.Builder(ReadActivity.this); | ||||
| 
 | ||||
|         normalDialog.setTitle("退出阅读"); | ||||
|         normalDialog.setMessage("确定退出阅读吗?"); | ||||
|         normalDialog.setPositiveButton("继续阅读", | ||||
|         normalDialog.setTitle("提示"); | ||||
|         normalDialog.setMessage("是否加入书架?"); | ||||
|         normalDialog.setPositiveButton("确定", | ||||
|                 new DialogInterface.OnClickListener() { | ||||
|                     @Override | ||||
|                     public void onClick(DialogInterface dialog, int which) { | ||||
|                         hideSystemUI(); | ||||
| 
 | ||||
|                         book.setOnShelf(true); | ||||
|                         book.update(book.getId()); | ||||
|                         finish(); | ||||
| 
 | ||||
|                     } | ||||
|                 }); | ||||
|         normalDialog.setNegativeButton("退出阅读", | ||||
|         normalDialog.setNegativeButton("取消", | ||||
|                 new DialogInterface.OnClickListener() { | ||||
|                     @Override | ||||
|                     public void onClick(DialogInterface dialog, int which) { | ||||
|                     public void onClick(DialogInterface dialog, int which) | ||||
|                     { | ||||
| 
 | ||||
|                         finish(); | ||||
|                     } | ||||
|                 }); | ||||
|  | @ -634,6 +658,11 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|            // }else{ | ||||
|           //  Toast.makeText(this,"换源不可用,请返回重试...",Toast.LENGTH_SHORT); | ||||
|           // } | ||||
|         }else if(id == R.id.action_refresh){ | ||||
|             pageFactory.refreshChapter(); | ||||
|         }else if(id == R.id.action_bookdetail){ | ||||
|             showBookDetail(this.book); | ||||
|             //finish(); | ||||
|         } | ||||
| 
 | ||||
|         return super.onOptionsItemSelected(item); | ||||
|  | @ -898,11 +927,11 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|           /*  case R.id.rl_bottom: | ||||
|                 break;*/ | ||||
|             case R.id.tv_stop_read: | ||||
|                 if (mSpeechSynthesizer!=null){ | ||||
|               /*  if (mSpeechSynthesizer!=null){ | ||||
|                     mSpeechSynthesizer.stop(); | ||||
|                     isSpeaking = false; | ||||
|                     hideReadSetting(); | ||||
|                 } | ||||
|                 }*/ | ||||
|             case R.id.llTopAd: | ||||
|                 Toast.makeText(this,"ad is clicked ",Toast.LENGTH_LONG).show(); | ||||
|                 Log.d(TAG,"Ad is clicked"); | ||||
|  | @ -992,14 +1021,14 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|      */ | ||||
|     @Override | ||||
|     public void onSpeechFinish(String utteranceId) { | ||||
|         pageFactory.nextPage(); | ||||
|      /*   pageFactory.nextPage(); | ||||
|         if (pageFactory.islastPage()) { | ||||
|             isSpeaking = false; | ||||
|             Toast.makeText(ReadActivity.this,"小说已经读完了",Toast.LENGTH_SHORT); | ||||
|         }else { | ||||
|             isSpeaking = true; | ||||
|             mSpeechSynthesizer.speak(pageFactory.getCurrentPage().getLineToString()); | ||||
|         } | ||||
|         }*/ | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -1010,9 +1039,9 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
|      */ | ||||
|     @Override | ||||
|     public void onError(String utteranceId, SpeechError error) { | ||||
|         mSpeechSynthesizer.stop(); | ||||
|        /* mSpeechSynthesizer.stop(); | ||||
|         isSpeaking = false; | ||||
|         Log.e(TAG,error.description); | ||||
|         Log.e(TAG,error.description);*/ | ||||
|     } | ||||
| 
 | ||||
|     final int contentAdHight=350; | ||||
|  | @ -1041,4 +1070,6 @@ public class ReadActivity extends  Activity_base implements SpeechSynthesizerLis | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -22,6 +22,15 @@ public class SiteRule extends LitePalSupport { | |||
|     private String chapterUrlPattern; | ||||
|     private long miniInterval4AccessChapter; | ||||
|     private String[] headers; | ||||
|     private String[] userAgents; | ||||
| 
 | ||||
|     public String[] getUserAgents() { | ||||
|         return userAgents; | ||||
|     } | ||||
| 
 | ||||
|     public void setUserAgents(String[] userAgents) { | ||||
|         this.userAgents = userAgents; | ||||
|     } | ||||
| 
 | ||||
|     public int getId() { | ||||
|         return id; | ||||
|  |  | |||
|  | @ -14,15 +14,15 @@ import org.json.JSONObject; | |||
| 
 | ||||
| public class URLConstant { | ||||
|     //存放全部的URL(可分为开发、测试、正式) | ||||
|     private static String ROOT_URL = Config.getInstance().getRootUrl()  ;//https://api.douban.com/v2/movie/"; | ||||
|     public static String[] BASE_URLS = {"http://xiaoshuofenxiang.com/api/"}; | ||||
|     private static String ROOT_URL ;//= Config.getInstance().getRootUrl()  ;//https://api.douban.com/v2/movie/"; | ||||
|    // public static String[] BASE_URLS = {"http://xiaoshuofenxiang.com/api/"}; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 取新的baseURL | ||||
|      * @return | ||||
|      */ | ||||
|     public static String newRootUrl(){ | ||||
|    /* public static String newRootUrl(){ | ||||
|        | ||||
|         for (String url:BASE_URLS) { | ||||
|             if(!url.equals(ROOT_URL)){ | ||||
|  | @ -34,7 +34,7 @@ public class URLConstant { | |||
|             Config.getInstance().setBaseUrl(ROOT_URL); | ||||
|         } | ||||
|         return ROOT_URL; | ||||
|     } | ||||
|     }*/ | ||||
| 
 | ||||
|     /** | ||||
|      * app初始化取上次保存的baseurl | ||||
|  |  | |||
|  | @ -45,8 +45,8 @@ import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; | |||
| import retrofit2.converter.gson.GsonConverterFactory; | ||||
| 
 | ||||
| import static com.novelbook.android.netapi.URLConstant.getRootUrl; | ||||
| import static com.novelbook.android.netapi.URLConstant.newRootUrl; | ||||
| import static com.novelbook.android.netutils.NetUtil.getHost; | ||||
| //import static com.novelbook.android.netapi.URLConstant.newRootUrl; | ||||
| //import static com.novelbook.android.netutils.NetUtil.getHost; | ||||
| 
 | ||||
| public class HttpMethods { | ||||
|     public String TAG = "HttpMethods"; | ||||
|  | @ -56,6 +56,7 @@ public class HttpMethods { | |||
|     private static final int DEFAULT_WRITE_TIMEOUT = 5; | ||||
|     private static final int DEFAULT_READ_TIMEOUT = 5; | ||||
|     public static String USERAGENT=""; | ||||
|     public static String LOCALUSERAGENT=""; | ||||
|     private Retrofit retrofit; | ||||
|     private HttpApi httpApi; | ||||
|     /** | ||||
|  | @ -102,6 +103,7 @@ public class HttpMethods { | |||
|        // okHttpBuilder.addInterceptor(new RetryInterceptor()); | ||||
|         okHttpBuilder.followRedirects(false); | ||||
|         okHttpBuilder.retryOnConnectionFailure(false); | ||||
| 
 | ||||
|         retrofit = new Retrofit.Builder() | ||||
|                 .client(okHttpBuilder.build()) | ||||
|                 .addConverterFactory(GsonConverterFactory.create()) | ||||
|  | @ -165,6 +167,7 @@ public class HttpMethods { | |||
|     private OkHttpClient getClient(){ | ||||
|         //手动创建一个OkHttpClient并设置超时时间 | ||||
|         okHttpBuilder = new OkHttpClient.Builder(); | ||||
| 
 | ||||
|         /** | ||||
|          * 设置缓存 | ||||
|          */ | ||||
|  | @ -173,7 +176,7 @@ public class HttpMethods { | |||
|         Log.d(TAG, "getClient: to set cach control"); | ||||
|         //  okHttpBuilder.cache(cache).addInterceptor(cacheInterceptor); | ||||
|         okHttpBuilder.cache(cache) | ||||
|                  .addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) | ||||
|                //  .addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) | ||||
|                 .addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE); | ||||
| 
 | ||||
|         /** | ||||
|  | @ -181,17 +184,17 @@ public class HttpMethods { | |||
|          */ | ||||
| 
 | ||||
| 
 | ||||
|         Interceptor headerInterceptor = new Interceptor() { | ||||
|     /*    Interceptor headerInterceptor = new Interceptor() { | ||||
|             @Override | ||||
|             public Response intercept(Chain chain) throws IOException { | ||||
|                 Request originalRequest = chain.request(); | ||||
|                /* Request.Builder requestBuilder = originalRequest.newBuilder() | ||||
|                *//* Request.Builder requestBuilder = originalRequest.newBuilder() | ||||
|                         .addHeader("Accept-Encoding", Locale.getDefault().toString()) | ||||
|                       //  .addHeader("Host", "testapi.wujike.com.cn") | ||||
|                         .addHeader("Connection", "Keep-Alive") | ||||
|                         .addHeader("Device", "Android") | ||||
|                         .method(originalRequest.method(), originalRequest.body()); | ||||
|                */ | ||||
|                *//* | ||||
|                 Request.Builder requestBuilder = originalRequest.newBuilder() | ||||
|                        //  .addHeader("Accept-Encoding", "gzip") | ||||
|                     //    .addHeader("Accept-Encoding", Locale.getDefault().toString() ) | ||||
|  | @ -206,8 +209,8 @@ public class HttpMethods { | |||
|                 Request request = requestBuilder.build(); | ||||
|                 return chain.proceed(request); | ||||
|             } | ||||
|         }; | ||||
|         okHttpBuilder.addInterceptor(headerInterceptor); | ||||
|         };*/ | ||||
|       //  okHttpBuilder.addInterceptor(headerInterceptor); | ||||
| 
 | ||||
| 
 | ||||
| //        if (BuildConfig.DEBUG) { | ||||
|  | @ -334,18 +337,7 @@ public class HttpMethods { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     private static String getUserAgent(Context context) { | ||||
|         String userAgent = ""; | ||||
| //        APP版本 | ||||
|         String versionName = CommonUtil.getVersionName(context); | ||||
| //        手机型号 | ||||
|         String systemModel = CommonUtil.getSystemModel(); | ||||
| //        系统版本 | ||||
|         String systemVersion = CommonUtil.getSystemVersion(); | ||||
|         String deviceBrand = CommonUtil.getDeviceBrand(); | ||||
|         userAgent = "Android/" + versionName + "/" + deviceBrand + "" + systemModel + "/" + systemVersion; | ||||
|         return userAgent; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { | ||||
|         @Override | ||||
|  |  | |||
|  | @ -5,16 +5,16 @@ import android.net.ConnectivityManager; | |||
| import android.net.NetworkInfo; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
| import android.widget.ImageView; | ||||
| 
 | ||||
| import com.novelbook.android.MyApp; | ||||
| import com.novelbook.android.netapi.RandomHost; | ||||
| import com.novelbook.android.netapi.URLConstant; | ||||
| import com.novelbook.android.netsubscribe.BookSubscribe; | ||||
| import com.novelbook.android.utils.CommonUtil; | ||||
| import com.novelbook.android.utils.Config; | ||||
| import com.novelbook.android.utils.Constants; | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.util.Date; | ||||
| import java.util.Random; | ||||
| 
 | ||||
| import okhttp3.Call; | ||||
|  | @ -29,8 +29,8 @@ public class NetUtil { | |||
|     private static final String TAG= NetUtil.class.getSimpleName(); | ||||
|     public static int currentRequestTag =0; | ||||
|     public static String hosts; | ||||
| 
 | ||||
|     public static String getUrl(String key){ | ||||
|     public static boolean isRequestHosts; | ||||
|  /*   public static String getUrl(String key){ | ||||
| 
 | ||||
|         try { | ||||
|             JSONObject jsonObject = getHost(); | ||||
|  | @ -48,10 +48,26 @@ public class NetUtil { | |||
|         } | ||||
| 
 | ||||
|         return ""; | ||||
|     }*/ | ||||
| 
 | ||||
|     public static boolean isHostExpires(){ | ||||
| 
 | ||||
|         if(Constants.LAST_G==0){ | ||||
|             return false; | ||||
|         } | ||||
|         long t =Constants.MAXAGE_G*1000 - (new Date().getTime() - Constants.LAST_G )  ; | ||||
|         Log.d(TAG, "isHostExpires: time left is " +CommonUtil.getTimeCnt4Read(t,true)); | ||||
| 
 | ||||
|       //  t=0; | ||||
|        return  t < 0; | ||||
|     } | ||||
| 
 | ||||
|     public static JSONObject getHost() { | ||||
|         if (TextUtils.isEmpty(hosts)) { | ||||
|     public static JSONObject getHost(boolean isMainApi) { | ||||
|         if(!isMainApi && isHostExpires()){ | ||||
|             Log.d(TAG, String.format("isHostExpires prepare book:  main API maxAge %s, is expired, loading main API again ",CommonUtil.getTimeCnt4Read(Constants.MAXAGE_G*1000,true))); | ||||
|             getHostPolicy(); | ||||
|         } | ||||
|       if (TextUtils.isEmpty(hosts)){ | ||||
|             Config config = Config.getInstance(); | ||||
|             hosts = config.getBaseUrl(); | ||||
|         } | ||||
|  | @ -267,5 +283,57 @@ public class NetUtil { | |||
|         return url; | ||||
|     } | ||||
| 
 | ||||
|     public static String getUserAgent(Context context) { | ||||
|         String userAgent = ""; | ||||
| //        APP版本 | ||||
|         String versionName = CommonUtil.getVersionName(context); | ||||
| //        手机型号 | ||||
|         String systemModel = CommonUtil.getSystemModel(); | ||||
| //        系统版本 | ||||
|         String systemVersion = CommonUtil.getSystemVersion(); | ||||
|         String deviceBrand = CommonUtil.getDeviceBrand(); | ||||
|         String packagenm = CommonUtil.getPackageName(context); | ||||
|         userAgent = "Android/" + versionName + "/"+packagenm+"/" + deviceBrand + "/" + systemModel + "/" + systemVersion; | ||||
|         return userAgent; | ||||
|     } | ||||
| 
 | ||||
|     public static void getHostPolicy(){ | ||||
|         if(isRequestHosts){ | ||||
|             return; | ||||
|         } | ||||
|         isRequestHosts =true; | ||||
|         BookSubscribe.getMastDomain(new OnSuccessAndFaultSub(new OnSuccessAndFaultListener() { | ||||
|             @Override | ||||
|             public void onSuccess(String result) { | ||||
| 
 | ||||
|                 // mFirstPage= gson.fromJson(result, FirstPage.class); | ||||
|                 try { | ||||
|                     JSONObject jsonObject = new JSONObject(result); | ||||
|                     String resultstr = jsonObject.getString("hosts"); | ||||
|                     Config config =Config.createConfig(MyApp.applicationContext); | ||||
|                     config.setBaseUrl(resultstr); | ||||
|                     //config.setBaseUrl(resultstr); | ||||
|                     hosts=""; | ||||
|                     Constants.LAST_G = new Date().getTime(); | ||||
| 
 | ||||
|                     Constants.announcement =jsonObject.getString("declare"); | ||||
|                     // config.setRootUrl( jsonObject.getString("masterDomains")); | ||||
|                     isRequestHosts =false; | ||||
|                 } catch (Exception e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void onFault(String errorMsg) { | ||||
|                 //失败 | ||||
|                 Log.d(TAG, "error on get firstpage: " + errorMsg); | ||||
|                 isRequestHosts =false; | ||||
|             } | ||||
|         }, MyApp.applicationContext)); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import android.text.TextUtils; | |||
| import android.util.Log; | ||||
| 
 | ||||
| import com.novelbook.android.netapi.RandomHost; | ||||
| import com.novelbook.android.utils.Constants; | ||||
| import com.novelbook.android.utils.REUtil; | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
|  | @ -44,7 +45,8 @@ public class RetryInterceptor implements Interceptor { | |||
|         } | ||||
|         String path = oldUrl.substring(prefix.length()); | ||||
|         RandomHost rh = null; | ||||
|         if(oldUrl.indexOf("xiaoshuofenxiang.com") == -1 || !path.startsWith("/api/") || NetUtil.getHost()==null){ | ||||
|         boolean isMainApi =path.equals("/api/g/"); | ||||
|         if(oldUrl.indexOf("xiaoshuofenxiang.com") == -1 || !path.startsWith("/api/") || NetUtil.getHost(isMainApi)==null){ | ||||
|           //  rh = null; | ||||
|             Response response = doRequest(chain, request); | ||||
|             if(response!=null) | ||||
|  | @ -57,14 +59,14 @@ public class RetryInterceptor implements Interceptor { | |||
|             } | ||||
|         } | ||||
|         try { | ||||
|                 rh = new RandomHost(NetUtil.getHost(), path); | ||||
|                 rh = new RandomHost(NetUtil.getHost(isMainApi), path); | ||||
|                 Log.d(TAG, "HttpMethods intercept: api path is "+path); | ||||
|                 Log.d(TAG, "HttpMethods intercept: create new RandomHost--------------------------"); | ||||
| 
 | ||||
|         } catch (JSONException e) { | ||||
|             Log.e(TAG, "intercept: ", e); | ||||
| 
 | ||||
|             // TODO rh == null | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -80,7 +82,20 @@ public class RetryInterceptor implements Interceptor { | |||
|             Request newRequest = null; | ||||
|             try { | ||||
| 
 | ||||
|                 newRequest = request.newBuilder().url(newUrl).build(); | ||||
|                 Request.Builder requestBuilder = request.newBuilder(); | ||||
|                 requestBuilder.removeHeader("User-Agent").addHeader("User-Agent", HttpMethods.LOCALUSERAGENT) | ||||
|                         .url(newUrl); | ||||
|                 if (path.equals("/api/g/")) { | ||||
|                     //  if(new Date().getTime() - Constants.LAST_G > Constants.MAXAGE_G){ // | ||||
|                     if (Constants.LAST_G == 0) { | ||||
|                         requestBuilder.header("Cache-Control", "public, max-age=0"); | ||||
|                         Log.d(TAG, "prepare book access main api with force maxage=0"); | ||||
|                     } | ||||
|                  } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|                 newRequest = requestBuilder.build(); | ||||
|             } catch (Exception e) { | ||||
|                 Log.e(TAG, "HttpMethods intercept: " + newUrl); | ||||
|                 Log.e(TAG, "HttpMethods intercept: ", e); | ||||
|  | @ -100,6 +115,17 @@ public class RetryInterceptor implements Interceptor { | |||
|             if (response != null && response.isSuccessful()) { | ||||
|               //  rh = null; | ||||
|                 Log.d(TAG, String.format("HttpMethods intercept: set rh null,return response")); | ||||
|                 if (path.equals("/api/g")) { | ||||
|                     String cacheControl = response.header("Cache-Control"); | ||||
|                     if(!TextUtils.isEmpty(cacheControl)) { | ||||
|                         try { | ||||
|                             Constants.MAXAGE_G = Integer.parseInt(cacheControl.substring("max-age=".length())); | ||||
|                         }catch (Exception e) | ||||
|                         { | ||||
|                             Log.e(TAG, "intercept: parse max age error", e); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 return response; | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ import java.util.Date; | |||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Random; | ||||
| 
 | ||||
| import javax.net.ssl.HostnameVerifier; | ||||
| import javax.net.ssl.SSLContext; | ||||
|  | @ -72,7 +73,7 @@ public class BookUtil { | |||
|     private static final String charachterType = "utf-8";//"UTF-16LE"; | ||||
|     private Context mContext; | ||||
|     private ProgressDialog progressDialog; | ||||
|     private MuluStatus mMuluStatus; //目录是否下载完成 | ||||
|     MuluStatus mMuluStatus; //目录是否下载完成 | ||||
|     private Gson gson = new Gson(); | ||||
|     public void setContext(Context context) { | ||||
|         this.mContext = context; | ||||
|  | @ -112,7 +113,9 @@ public class BookUtil { | |||
|     } | ||||
|     private long bookLen; | ||||
|     private long chapterLen; | ||||
|     private long position; | ||||
|    // private long position; | ||||
|     private Map<Integer,Long> charPosition = new HashMap<Integer,Long>(); | ||||
| 
 | ||||
|     private Novel mNovel; | ||||
| 
 | ||||
|     public void setNovel(Novel novel) { | ||||
|  | @ -134,7 +137,7 @@ public class BookUtil { | |||
|     public Chapter getChapter(int chapId){ | ||||
|         chapId = chapId >0 ?chapId : 1; | ||||
|         if(chapId > mChapters.size() || mChapters.size() ==0){ | ||||
|             return Chapter.getChapter(mNovel.getId(), mNovel.getDomain(),chapId); | ||||
|             return Chapter.getChapter(mNovel.getId(), mNovel.getDomain()==null?"":mNovel.getDomain(),chapId); | ||||
|         }else{ | ||||
|             return mChapters.get(chapId-1); | ||||
|         } | ||||
|  | @ -446,17 +449,8 @@ public class BookUtil { | |||
|     private boolean isChangeSource =false; | ||||
|     private int mChangeChapId; | ||||
|     private String mChangeTitle; | ||||
|     public void changeSource(String domain,int chapId,String chapTitle) { | ||||
|         Log.d(TAG, String.format("changing Source: target domain %s chaptId %s, chapt title %s ",domain,chapId,chapTitle)  ); | ||||
| 
 | ||||
| 
 | ||||
|         this.muluRetryCount=0; | ||||
|         this.downloadStatus = DownloadStatus.notStart; | ||||
|         chaptDownStatus.clear(); | ||||
|         chaptCache.clear(); | ||||
|        // isDownloadChapt =false; | ||||
|         mChangeChapId = chapId; | ||||
|         mChangeTitle =chapTitle; | ||||
|     public void changeSite(String domain){ | ||||
|         for (Site site:mNovelSites.getSites() ) { | ||||
|             if(site.getDomain().equals(domain)){ | ||||
|                 mSite = site; | ||||
|  | @ -469,6 +463,15 @@ public class BookUtil { | |||
|         isChangeSource = true; | ||||
|         mChapters.clear(); | ||||
|         getSiteRule(); | ||||
|     } | ||||
|     public void changeSource(String domain,int chapId,String chapTitle) { | ||||
|         Log.d(TAG, String.format("changing Source: target domain %s chaptId %s, chapt title %s ",domain,chapId,chapTitle)  ); | ||||
| 
 | ||||
|        clearBook(); | ||||
|        // isDownloadChapt =false; | ||||
|         mChangeChapId = chapId; | ||||
|         mChangeTitle =chapTitle; | ||||
|         changeSite(domain); | ||||
| 
 | ||||
|         BookTask btsk = new BookTask(); | ||||
|         btsk.execute( domain,  chapId+"",  chapTitle); | ||||
|  | @ -477,6 +480,17 @@ public class BookUtil { | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private void clearBook() { | ||||
|         charPosition.clear(); | ||||
|         this.muluRetryCount=0; | ||||
|         this.downloadStatus = DownloadStatus.notStart; | ||||
|         chaptDownStatus.clear(); | ||||
|         chaptCache.clear(); | ||||
|         fileRetryCnt.clear(); | ||||
|         siteRuleRetryCnt=0; | ||||
|         caprint.clear(); | ||||
|     } | ||||
| 
 | ||||
|     public Site getSite() { | ||||
|  | @ -527,6 +541,21 @@ public class BookUtil { | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * delete cache chapter file | ||||
|      * and reload the chapter | ||||
|      */ | ||||
|     public void refreshChapter() { | ||||
|         File file = new File(fileChapterName(chapterNo)); | ||||
|         if(file.exists()){ | ||||
|             file.delete(); | ||||
|         } | ||||
|         if(chaptCache.containsKey(chapterNo)){ | ||||
|             chaptCache.remove(chapterNo); | ||||
|         } | ||||
|         pagefactory.changeChapter(chapterNo); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private class BookTask extends AsyncTask<String,Void,Boolean> { | ||||
|        private String domain; | ||||
|  | @ -954,14 +983,16 @@ int muluRetryCount =0; | |||
|     } | ||||
| 
 | ||||
|     public int next(boolean back,int chaptId){ | ||||
|         position += 1; | ||||
|         if (position > tmpChaptLen){ | ||||
|             position = tmpChaptLen; | ||||
|       //  Log.d(TAG, String.format(" loadchapt  next(), back %s, chaptId %s, position %s, tmpChaptLen %s",back,chaptId,charPosition.get(chaptId),tmpChaptLen )); | ||||
|         charPosition.put(chaptId,charPosition.get(chaptId)+1) ; | ||||
|         if (charPosition.get(chaptId) > tmpChaptLen){ | ||||
|             charPosition.put(chaptId,tmpChaptLen) ; | ||||
|             return -1; | ||||
|         } | ||||
| 
 | ||||
|         char result = chaptCurrent(chaptId); //current(); | ||||
|         if (back) { | ||||
|             position -= 1; | ||||
|             charPosition.put(chaptId,charPosition.get(chaptId)-1) ; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | @ -984,7 +1015,7 @@ int muluRetryCount =0; | |||
|             line += wordChar; | ||||
|         } | ||||
|         return line.toCharArray(); | ||||
|     }*/ | ||||
|     } | ||||
| 
 | ||||
|     public char[] preLine(){ | ||||
|         if (position <= 0){ | ||||
|  | @ -1006,18 +1037,19 @@ int muluRetryCount =0; | |||
|         } | ||||
| 
 | ||||
|         return line.toCharArray(); | ||||
|     } | ||||
|     }*/ | ||||
| 
 | ||||
|     public char chaptCurrent(int chaptId){ | ||||
|       //  chapterNo = mChapters.size() < chapterNo ? 1 : chapterNo; | ||||
|        // Log.d(TAG, String.format(" prepare book  chaptCurrent() ,chapterNo %s,  getChapters().size() %s " ,chapterNo , mChapters.size()) ); | ||||
|     //    Log.d(TAG, String.format(" loadchapt   chaptCurrent() ,chapterNo %s,  getChapters().size() %s " ,chaptId , mChapters.size()) ); | ||||
|         char[] charArray = chaptChars(chaptId); | ||||
| 
 | ||||
| 
 | ||||
|         int i = (int)position-1; | ||||
|         int i = (int) (charPosition.get(chaptId) -1);//(int)position-1; | ||||
|         i =i>0?i:0; | ||||
|         i = i< charArray.length? i:charArray.length-1; | ||||
| 
 | ||||
|         // Log.d(TAG, String.format(" loadchapt  chaptCurrent(), char position %s - %s, char  '%s'  " ,i,charPosition.get(chaptId) -1,charArray[i]) ); | ||||
|         return charArray[i]; | ||||
|     } | ||||
|     public char current(){ | ||||
|  | @ -1028,9 +1060,9 @@ int muluRetryCount =0; | |||
|         int len = 0; | ||||
|         for (int i = 0;i < myArray.size();i++){ | ||||
|             long size = myArray.get(i).getSize(); | ||||
|             if (size + len - 1 >= position){ | ||||
|             if (size + len - 1 >= charPosition.get(chaptId) ){ | ||||
|                 cachePos = i; | ||||
|                 pos = (int) (position - len); | ||||
|                 pos = (int) (charPosition.get(chaptId) - len); | ||||
|                 break; | ||||
|             } | ||||
|             len += size; | ||||
|  | @ -1040,7 +1072,7 @@ int muluRetryCount =0; | |||
|         return charArray[pos]; | ||||
|     } | ||||
| 
 | ||||
|     public int pre(boolean back){ | ||||
|   /*  public int pre(boolean back){ | ||||
|         position -= 1; | ||||
|         if (position < 0){ | ||||
|             position = 0; | ||||
|  | @ -1052,13 +1084,13 @@ int muluRetryCount =0; | |||
|         } | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     public long getPosition(){ | ||||
|         return position; | ||||
| */ | ||||
|     public long getPosition(int chaptId){ | ||||
|         return charPosition.get(chaptId); | ||||
|     } | ||||
| 
 | ||||
|     public void setPostition(long position){ | ||||
|         this.position = position; | ||||
|     public void setPostition(int chaptId,long position){ | ||||
|         charPosition.put(chaptId,position) ; | ||||
|     } | ||||
| 
 | ||||
|     //缓存书本 | ||||
|  | @ -1433,7 +1465,7 @@ int muluRetryCount =0; | |||
|      return  true; | ||||
|  } | ||||
| 
 | ||||
| 
 | ||||
|     List<Integer> caprint = new ArrayList<Integer>(); | ||||
| 
 | ||||
|     //获取chapter 缓存 | ||||
|     public char[] chaptChars(final int index) { | ||||
|  | @ -1441,7 +1473,12 @@ int muluRetryCount =0; | |||
|         char[] block=null; | ||||
|         if(chaptCache.containsKey(Integer.valueOf(index))) { | ||||
|             block = chaptCache .get(index).getData().get(); | ||||
|             Log.d(TAG, String.format("read content  get block in cache, chapter: %s", index)); | ||||
|          //   Log.d(TAG, String.format("chaptChars  get block in cache, chapter: %s", index)); | ||||
| 
 | ||||
|             if(!caprint.contains(index)) { | ||||
|                 caprint.add(index); | ||||
|              //   Log.d(TAG, String.format("chaptChars: load from cache chaptId %s,--->%s", index, new String(block))); | ||||
|             } | ||||
|         } | ||||
|       //  Log.d(TAG, String.format("prepare book  begin to load content for chapter %s", index)); | ||||
|         if (block == null) { | ||||
|  | @ -1592,6 +1629,11 @@ int muluRetryCount =0; | |||
| 
 | ||||
|                     long l = reader.read(block); | ||||
| 
 | ||||
|                   //  Log.d(TAG, String.format("loadchapt: load from file chaptId %s,--->%s",index,  new String(block ))); | ||||
|                    /* for (char c :block | ||||
|                          ) { | ||||
|                         Log.d(TAG, String.valueOf(c)); | ||||
|                     }*/ | ||||
|                     if (reader.read(block) != block.length) { | ||||
|                         //   throw new RuntimeException("Error during reading " + fileChapterName(index)); | ||||
|                     } | ||||
|  | @ -1613,6 +1655,7 @@ int muluRetryCount =0; | |||
|             cache.setData(new WeakReference<char[]>(block)); | ||||
|             chaptCache.put(index, cache); | ||||
| //            myArray.set(index, new WeakReference<char[]>(block)); | ||||
|             Log.d(TAG, String.format("prepare book content reading finish, chapter %s", index)); | ||||
|         } | ||||
|         return block; | ||||
|     } | ||||
|  | @ -1771,6 +1814,15 @@ private void loadChaptContent(final int chapterIndex) throws JSONException, Inte | |||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         if(mSiteRule.getUserAgents()!=null && mSiteRule.getUserAgents().length>0){ | ||||
|             String siteAgent =mSiteRule.getUserAgents()[new Random().nextInt( mSiteRule.getUserAgents().length-1)]; | ||||
| 
 | ||||
|             Log.d(TAG, "prepare book on getTagRequest:add site user agent " + siteAgent); | ||||
|             builder.removeHeader("User-Agent").addHeader("User-Agent",siteAgent ); //加 随机agent | ||||
| 
 | ||||
|         }else{ | ||||
|             builder.removeHeader("User-Agent").addHeader("User-Agent",  HttpMethods.USERAGENT); | ||||
|         } | ||||
| 
 | ||||
| //                .header( "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8") | ||||
| //                .header( "Upgrade-Insecure-Requests", "1") | ||||
|  |  | |||
|  | @ -2,11 +2,13 @@ package com.novelbook.android.utils; | |||
| 
 | ||||
| import android.app.Activity; | ||||
| import android.content.Context; | ||||
| import android.content.pm.ApplicationInfo; | ||||
| import android.content.pm.PackageInfo; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.content.res.Resources; | ||||
| import android.graphics.Point; | ||||
| import android.os.Build; | ||||
| import android.support.v4.widget.ContentLoadingProgressBar; | ||||
| import android.text.TextUtils; | ||||
| import android.util.DisplayMetrics; | ||||
| import android.util.Log; | ||||
|  | @ -343,6 +345,19 @@ public class CommonUtil { | |||
|             return 0; | ||||
|         } | ||||
|     } | ||||
|     public static String  getPackageName(Context context) { | ||||
|         try { | ||||
| 
 | ||||
|             return context.getPackageName(); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             return ""; | ||||
|         }catch (NoSuchMethodError e){ | ||||
|             e.printStackTrace(); | ||||
|             return ""; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取当前手机系统语言。 | ||||
|      * | ||||
|  | @ -480,7 +495,24 @@ public class CommonUtil { | |||
|         String date1 = format1.format(new Date(System.currentTimeMillis())); | ||||
|         return date1;// 2012-10-03 23:41:31 | ||||
|     } | ||||
| 
 | ||||
|     private String getChannel(Context context) { | ||||
|         try { | ||||
|             PackageManager pm = context.getPackageManager(); | ||||
|             ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(context), PackageManager.GET_META_DATA); | ||||
|             return appInfo.metaData.getString("UMENG_CHANNEL"); | ||||
|         } catch (PackageManager.NameNotFoundException ignored) { | ||||
|         } | ||||
|         return ""; | ||||
|     } | ||||
|     public static  String getMeta(Context context,String key) { | ||||
|         try { | ||||
|             PackageManager pm = context.getPackageManager(); | ||||
|             ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(context), PackageManager.GET_META_DATA); | ||||
|             return appInfo.metaData.getString(key); | ||||
|         } catch (PackageManager.NameNotFoundException ignored) { | ||||
|         } | ||||
|         return ""; | ||||
|     } | ||||
| 
 | ||||
| /*    public static boolean isNavigationBarShow(){ | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | ||||
|  |  | |||
|  | @ -3,7 +3,10 @@ package com.novelbook.android.utils; | |||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.graphics.Typeface; | ||||
| import android.text.style.BulletSpan; | ||||
| 
 | ||||
| import com.novelbook.android.BuildConfig; | ||||
| import com.novelbook.android.MyApp; | ||||
| import com.novelbook.android.R; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -187,14 +190,20 @@ public class Config { | |||
|         sp.edit().putString(KEY_BASE_URY,baseUrl).commit(); | ||||
|     } | ||||
|     public String getBaseUrl(){ | ||||
|     String defaultHost ="{\"master\":[\"http:\\/\\/xiaoshuofenxiang.com\"],\"page\":[\"http:\\/\\/p.xiaoshuofenxiang.com\"],\"report\":[\"http:\\/\\/r.xiaoshuofenxiang.com\"],\"search\":[\"http:\\/\\/s.xiaoshuofenxiang.com\"],\"novel\":[\"http:\\/\\/n.xiaoshuofenxiang.com\"],\"novelsbydot\":[\"http:\\/\\/nbd.xiaoshuofenxiang.com\"],\"user\":[\"http:\\/\\/u.xiaoshuofenxiang.com\"]}"; | ||||
|      // String defaultHost ="{\"master\":[\"http:\\/\\/xiaoshuofenxiang.com\"],\"page\":[\"http:\\/\\/p.xiaoshuofenxiang.com\"],\"report\":[\"http:\\/\\/r.xiaoshuofenxiang.com\"],\"search\":[\"http:\\/\\/s.xiaoshuofenxiang.com\"],\"novel\":[\"http:\\/\\/n.xiaoshuofenxiang.com\"],\"novelsbydot\":[\"http:\\/\\/nbd.xiaoshuofenxiang.com\"],\"user\":[\"http:\\/\\/u.xiaoshuofenxiang.com\"]}"; | ||||
|       //  String defaultHost =CommonUtil.getMeta(MyApp.applicationContext,"DEFAULTHOST"); | ||||
| 
 | ||||
|         String defaultHost =BuildConfig.API_HOST; | ||||
|         return sp.getString(KEY_BASE_URY,defaultHost); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public String getRootUrl(){ | ||||
|         return sp.getString(KEY_ROOT_URL,"http://xiaoshuofenxiang.com/api/"); | ||||
|         //String defaultHost =CommonUtil.getMeta(MyApp.applicationContext,"MAINHOST"); | ||||
| 
 | ||||
|         String defaultHost = BuildConfig.MAIN_HOST; | ||||
|         String rt =sp.getString(KEY_ROOT_URL,defaultHost); | ||||
|         return sp.getString(KEY_ROOT_URL,defaultHost); | ||||
|     } | ||||
| 
 | ||||
|     public void setRootUrl(String baseUrl){ | ||||
|  |  | |||
|  | @ -12,6 +12,8 @@ public class Constants { | |||
|     public static final int MAXAGE_MAX =60*60*24*28; //28 天 ; | ||||
|     public static final int MAXAGE_MULU = 60*60*24*7*2; //2周;; | ||||
|     public static final String VERSION_ADDRESS ="version.xml"; | ||||
|     public static long LAST_G = 0;//主目录API上次访问时间 | ||||
|     public static long MAXAGE_G = 3600;//主目录API上次访问时间 | ||||
|     public static   String[] HOT_KEYS_VALUE = {}; | ||||
|     public static int SEX=1; //1 男,2女 | ||||
|     public static String A_Regex = "<a[^>]+href[\\s]*=[\\s]*['\"]?([^'\"]+)['\"\\s]?[^>]*>([^<]+)<"; //TODO: 从服务器更新 | ||||
|  | @ -25,5 +27,5 @@ public class Constants { | |||
|     // public static  List<String> lstProgress=null; | ||||
|     public static boolean showDialogOnUi =true; | ||||
|     public static boolean showDialogOnUiPage =false; | ||||
| 
 | ||||
|     public static String announcement ="免责声明:阅读内容均来自互联网,本软件仅提供转码服务"; | ||||
| } | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ import android.util.Log; | |||
| import com.novelbook.android.db.Chapter; | ||||
| import com.novelbook.android.db.SiteRule; | ||||
| import com.novelbook.android.netutils.HttpMethods; | ||||
| import com.novelbook.android.netutils.NetUtil; | ||||
| 
 | ||||
| import org.json.JSONArray; | ||||
| import org.json.JSONException; | ||||
|  | @ -22,6 +23,7 @@ import java.util.HashMap; | |||
| import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Random; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import okhttp3.Request; | ||||
|  | @ -292,6 +294,13 @@ public class NovelParseUtil { | |||
|             builder.header(siteRule.getHeaders()[i],siteRule.getHeaders()[i+1]); | ||||
| 
 | ||||
|         } | ||||
|         if(siteRule.getUserAgents()!=null && siteRule.getUserAgents().length>0){ | ||||
| 
 | ||||
|             builder.removeHeader("User-Agent").addHeader("User-Agent", siteRule.getUserAgents()[new Random().nextInt( siteRule.getUserAgents().length-1)]); //加 随机agent | ||||
| 
 | ||||
|         }else{ | ||||
|             builder.removeHeader("User-Agent").addHeader("User-Agent",  HttpMethods.USERAGENT); | ||||
|         } | ||||
|         Request request =builder.build() ; | ||||
|         Response response = null; | ||||
|         try { | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import android.graphics.Rect; | |||
| import android.graphics.RectF; | ||||
| import android.graphics.Region; | ||||
| import android.graphics.Typeface; | ||||
| import android.opengl.Visibility; | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Handler; | ||||
| import android.os.Message; | ||||
|  | @ -26,6 +27,7 @@ import android.view.View; | |||
| import android.view.WindowManager; | ||||
| import android.widget.Toast; | ||||
| 
 | ||||
| import com.novelbook.android.MyApp; | ||||
| import com.novelbook.android.R; | ||||
| import com.novelbook.android.bean.NovelSites; | ||||
| import com.novelbook.android.bean.Site; | ||||
|  | @ -33,6 +35,7 @@ import com.novelbook.android.db.Chapter; | |||
| import com.novelbook.android.db.Novel; | ||||
| import com.novelbook.android.netutils.NetUtil; | ||||
| import com.novelbook.android.view.PageWidget; | ||||
| import com.umeng.analytics.MobclickAgent; | ||||
| 
 | ||||
| import org.litepal.LitePal; | ||||
| 
 | ||||
|  | @ -89,7 +92,7 @@ public class PageFactory implements ChangeSource{ | |||
|     //段间距 | ||||
|     private float paragraphSpace; | ||||
|     //段间距相对行间距的倍数 | ||||
|     private final float prate = 1.3f; | ||||
|     private final float prate = 1.8f; | ||||
|     //字高度 | ||||
|     private float fontHeight; | ||||
|     //字体 | ||||
|  | @ -179,6 +182,7 @@ public class PageFactory implements ChangeSource{ | |||
| 
 | ||||
|     private AdInterface mAd; | ||||
|     private BookTask bookTask; | ||||
|     private int MSG_NEXTPAGE=2; | ||||
| 
 | ||||
|     public AdInterface getmAd() { | ||||
|         return mAd; | ||||
|  | @ -191,11 +195,11 @@ public class PageFactory implements ChangeSource{ | |||
|         @Override | ||||
|         public void handleMessage(Message msg) { | ||||
| 
 | ||||
|             int wt = msg.what; | ||||
|             Log.d(TAG, "prepare book get handler msg:" +msg); | ||||
| 
 | ||||
|             handlerMsg(msg); | ||||
| 
 | ||||
|             dismissProgressDialog(); | ||||
|            // dismissProgressDialog(); | ||||
| 
 | ||||
|         } | ||||
|     }; | ||||
|  | @ -203,14 +207,20 @@ public class PageFactory implements ChangeSource{ | |||
| 
 | ||||
|     void handlerMsg(Message msg) { | ||||
|         if (msg.what == 1) { | ||||
|             Log.d(TAG, String.format("prepare book handler get notic to download chapter %s , getNovel() is null? %s",currentChapter, getNovel()==null  ) ); | ||||
|             Log.d(TAG, String.format("prepare book handler get notic to download chapter %s , getNovel() is null? %s", currentChapter, getNovel() == null)); | ||||
|             if (getNovel() != null) { | ||||
|                 changeChapter(currentChapter); | ||||
|             }else{ | ||||
|             } else { | ||||
|                /* mStatus = Status.FAIL;      // unknow error null Attempt to invoke virtual method 'android.graphics.Bitmap com.novelbook.android.view.PageWidget.getCurPage()' on a null object reference | ||||
|                 drawStatus(); | ||||
|                 */ | ||||
|             } | ||||
|         } else if (msg.what == MSG_NEXTPAGE) { | ||||
| 
 | ||||
|             mStatus =Status.FINISH; | ||||
|           //  drawStatus(); | ||||
|             Log.d(TAG, "prepare book to load next page"); | ||||
|             nextPage(); | ||||
|         } | ||||
|     } | ||||
|     Map<Integer,Integer> fileRetryCnt = new HashMap<Integer,Integer>(); | ||||
|  | @ -234,12 +244,13 @@ public class PageFactory implements ChangeSource{ | |||
|         } | ||||
| 
 | ||||
|         chaptId = chaptId > 0 ? chaptId : 1; | ||||
|         final File file = new File(getChapterFileName(chaptId)); | ||||
|           File file = new File(getChapterFileName(chaptId)); | ||||
| 
 | ||||
|         if (!file.exists() && getChapters().size()>0) { //待下载 | ||||
|             chaptId = chaptId > getChapters().size() ? getChapters().size() : chaptId; | ||||
| 
 | ||||
|             chaptId = chaptId > 0 ? chaptId : 1; | ||||
|             file = new File(getChapterFileName(chaptId)); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -303,6 +314,7 @@ public class PageFactory implements ChangeSource{ | |||
|                     @Override | ||||
|                     public void run() { | ||||
|                         int slepttime =0; | ||||
|                        File file = new File(getChapterFileName(chid)); | ||||
|                       while( !file.exists() && slepttime <60 && mBookUtil.muluRetryCount<Constants.retryCnt){ | ||||
|                           try { | ||||
|                               sleep(50); | ||||
|  | @ -341,8 +353,7 @@ public class PageFactory implements ChangeSource{ | |||
|         Log.d(TAG, String.format("prepare book to load chapt %s,  cost %s ",chaptId ,new Date().getTime() -starttime) ); | ||||
|         mStatus = Status.FINISH; | ||||
|         Log.d(TAG, String.format("changing Source prepare book to draw chapter %s,  currentChapter %s ",chaptId ,currentChapter ) ); | ||||
|        /* drawStatus(); | ||||
|         */ | ||||
|       //  drawStatus(); | ||||
|         return  chaptPages; | ||||
|     } | ||||
| 
 | ||||
|  | @ -382,14 +393,17 @@ public class PageFactory implements ChangeSource{ | |||
|      */ | ||||
|     List<TRPage> readChaptCache(int chaptId){ | ||||
|         List<TRPage> chaptPages = new ArrayList<TRPage>(); | ||||
|         Log.d(TAG, String.format("changing Source prepare book to open chapter %s,  currentChapter %s ",chaptId ,currentChapter ) ); | ||||
| 
 | ||||
|         Log.d(TAG, String.format("prepare book to open chapter %s,  currentChapter %s ",chaptId ,currentChapter ) ); | ||||
|         char[] chars = mBookUtil.chaptChars(chaptId); | ||||
|          mBookUtil.setTmpChaptLen(chars.length); | ||||
| //        mBookUtil.setChapterNo(chaptId); | ||||
|         // TRPage page = new TRPage(); | ||||
|         long length =0; | ||||
|         int pageNo =0; | ||||
|         long starttime = new Date().getTime(); | ||||
|         while(length <chars.length ) { | ||||
|             long starttime1 = new Date().getTime(); | ||||
|             pageNo++; | ||||
|             TRPage page  = getNextChapterPage(chaptId,length); | ||||
|             // Log.d(TAG,"prepare book  page.getBegin :" + page.getBegin()+ ",chapter length "+ mBookUtil.getChapterLen()); | ||||
|  | @ -405,7 +419,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 pages ready for chapter %s,cost %s", chaptId,new Date().getTime()-starttime)); | ||||
|         return chaptPages; | ||||
|     } | ||||
| 
 | ||||
|  | @ -413,14 +429,14 @@ public class PageFactory implements ChangeSource{ | |||
| 
 | ||||
| 
 | ||||
|     public TRPage getNextChapterPage(int chaptId,long position){ | ||||
|         mBookUtil.setPostition(position); | ||||
|         mBookUtil.setPostition(chaptId,position); | ||||
| 
 | ||||
|         TRPage trPage = new TRPage(); | ||||
|         trPage.setBegin(position +1); | ||||
|       // Log.d(TAG,"page postion next begin:" +  (position + 1) + ""); | ||||
|         trPage.setLines(getNextLines(chaptId)); | ||||
|      //  Log.d(TAG,"page postion next end:" +mBookUtil.getPosition() + ""); | ||||
|         trPage.setEnd(mBookUtil.getPosition()); | ||||
|         trPage.setEnd(mBookUtil.getPosition(chaptId)); | ||||
|         return trPage; | ||||
|     } | ||||
| 
 | ||||
|  | @ -452,13 +468,16 @@ public class PageFactory implements ChangeSource{ | |||
|         } | ||||
|     } | ||||
|     public void changeSource(String domainName,String domain,int chapId,String chapTitle) { | ||||
|         mAd.hideSystemUI(); | ||||
|         hideSysUI(); | ||||
|         fileRetryCnt.clear(); | ||||
|         chaptMap.clear(); | ||||
| 
 | ||||
|         if(getSite().getDomain().equals(domain)){ //当前源 | ||||
|             Log.d(TAG, "prepare book changing Source: same site with original " + domain); | ||||
|             return; | ||||
|         } | ||||
|         if(chaptMap!=null){ | ||||
|             chaptMap.clear(); | ||||
|         } | ||||
|         Log.d(TAG, String.format("prepare book changing Source:target site received: name %s, site domain %s ,chapterId %s " ,domainName, domain,chapId)); | ||||
|         mStatus= Status.CHANGESOURCE; | ||||
|         statusChangeSource="正在换源..."; | ||||
|  | @ -485,6 +504,19 @@ public static boolean busy(){ | |||
|         return isBusy; | ||||
|     } | ||||
| 
 | ||||
|     public void refreshChapter() { | ||||
|         mBookUtil.refreshChapter(); | ||||
|     } | ||||
| 
 | ||||
|     public void changeSourceForCate(String name, String domain) { | ||||
|         if(getSite().getDomain().equals(domain)){ //当前源 | ||||
|             Log.d(TAG, "prepare book changing Source: same site with original " + domain); | ||||
|             return; | ||||
|         } | ||||
|         mBookUtil.changeSite(domain); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public enum Status { | ||||
|         OPENING, | ||||
|         FINISH, | ||||
|  | @ -493,7 +525,12 @@ public static boolean busy(){ | |||
|         SERVERERROR, | ||||
|          CHANGESOURCE   ; | ||||
|     } | ||||
| 
 | ||||
| private void hideSysUI(){ | ||||
|         if(mAd!=null){ | ||||
|             mAd.hideSystemUI(); | ||||
|            // mAd.showRefresh(View.GONE); | ||||
|         } | ||||
| } | ||||
|     public static synchronized PageFactory getInstance(Context context){ | ||||
|         if(pageFactory==null){ | ||||
|             createPageFactory(context); | ||||
|  | @ -535,7 +572,7 @@ public static boolean busy(){ | |||
|         lineSpace = context.getResources().getDimension(R.dimen.reading_line_spacing); | ||||
|         paragraphSpace = context.getResources().getDimension(R.dimen.reading_paragraph_spacing); | ||||
|         mVisibleWidth = mWidth - marginWidth * 2; | ||||
|         mVisibleHeight = mHeight - marginHeight * 2; | ||||
|         mVisibleHeight = mHeight - marginHeight * 2   - CommonUtil.convertDpToPixel(mContext,10);; | ||||
|         mHeight +=screenHeihtDiff; | ||||
|         typeface = config.getTypeface(); | ||||
|         m_fontSize = config.getFontSize(); | ||||
|  | @ -620,7 +657,7 @@ public static boolean busy(){ | |||
|     private String loadingTxt =""; | ||||
|     private String statusChangeSource ="正在换源..."; | ||||
|     private void drawStatus(Bitmap bitmap){ | ||||
|         mAd.hideSystemUI(); | ||||
|         hideSysUI(); | ||||
|        mAd.showRefresh(View.VISIBLE); | ||||
|         String status = ""; | ||||
|         switch (mStatus){ | ||||
|  | @ -630,7 +667,7 @@ public static boolean busy(){ | |||
|                 break; | ||||
|             case FAIL: | ||||
|                 status = "读取错误,请稍后重试"; | ||||
| 
 | ||||
|                 mAd.showRefresh(View.VISIBLE); | ||||
|                 break; | ||||
|             case NETWORKFAILE: | ||||
|                 status = "请开启网络"; | ||||
|  | @ -650,6 +687,7 @@ public static boolean busy(){ | |||
| 
 | ||||
|         Canvas c = new Canvas(bitmap); | ||||
|         c.drawBitmap(getBgBitmap(), 0, 0, null); | ||||
|         waitPaint.setTextSize(mContext.getResources().getDimension(R.dimen.reading_max_text_size));// 字体大小 | ||||
|         waitPaint.setColor(getTextColor()); | ||||
|         waitPaint.setTextAlign(Paint.Align.CENTER); | ||||
| 
 | ||||
|  | @ -670,16 +708,18 @@ public static boolean busy(){ | |||
|         myStaticLayout.draw(c);*/ | ||||
| 
 | ||||
|         mBookPageWidget.postInvalidate(); | ||||
|         mAd.hideSystemUI(); | ||||
|        // hideSysUI(); | ||||
|     } | ||||
| 
 | ||||
|     //上次翻书时间 | ||||
|     private long lastPageTime; | ||||
|     public void onDraw(Bitmap bitmap,List<String> m_lines,Boolean updateChapter) { | ||||
|         mAd.hideSystemUI(); | ||||
|         hideSysUI(); | ||||
|        // mAd.showRefresh(View.GONE); | ||||
|         if(m_lines.size()==0){ | ||||
|             return; | ||||
|         } | ||||
|         mStatus =Status.FINISH; | ||||
|         //    Log.d(TAG, String.format(" prepare book  onDraw chapter %s,  getChapters().size() %s ",currentChapter ,getChapters().size() ) ); | ||||
|         if (getChapters().size() > 0 && updateChapter) { | ||||
|        //     Log.d(TAG, String.format(" prepare book  onDraw chapter to getCurrentChapter(),currentChapter %s  ",currentChapter  ) ); | ||||
|  | @ -689,6 +729,9 @@ public static boolean busy(){ | |||
|    //     Log.d(TAG, String.format(" prepare book  onDraw chapter _____________ %s  ",currentChapter  ) ); | ||||
|         //更新数据库进度 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         if ( mStatus ==Status.FINISH && currentPage != null && getNovel() != null) { | ||||
|             new Thread() { | ||||
|                 @Override | ||||
|  | @ -747,6 +790,10 @@ public static boolean busy(){ | |||
|         float space =m_fontSize + lineSpace; | ||||
|         paragraphSpace = prate * lineSpace; | ||||
| 
 | ||||
|         if(mAd!=null){ | ||||
|             mAd.showRefresh(View.GONE); | ||||
|         } | ||||
| 
 | ||||
|         if (m_lines.size() > 0) { | ||||
|             float y = marginHeight; | ||||
|             String lastLine =""; | ||||
|  | @ -842,6 +889,21 @@ public static boolean busy(){ | |||
|         } | ||||
|         if(mBookPageWidget!=null) | ||||
|         mBookPageWidget.postInvalidate(); | ||||
|         if(currentPage!=null && currentPage.getPageNo()==1){ | ||||
| 
 | ||||
|             String source =String.format("本章节内容来自网络"); | ||||
|             if(getSite()!=null){ | ||||
|                 source =String.format("本章节内容来自第三方网站:%s",getSite().getName()); | ||||
|             } | ||||
|             int anny= (int) CommonUtil.convertDpToPixel(mContext,40); | ||||
|             c.drawText(source,   marginWidth, statusMarginBottom  + mBatterryFontSize+anny, mBatterryPaint); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|              anny= (int) CommonUtil.convertDpToPixel(mContext,60); | ||||
|             c.drawText( Constants.announcement,   marginWidth, statusMarginBottom  + mBatterryFontSize+anny, mBatterryPaint); | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void showAd(int adHeight,int adY) { | ||||
|  | @ -904,10 +966,38 @@ public static boolean busy(){ | |||
| 
 | ||||
|         if (currentPage.getEnd() >= mBookUtil.getChapterLen()) { | ||||
|            Log.d(TAG,"已经是本章最后一页了"); | ||||
|             if(mBookUtil.getChapters().size()==0){ | ||||
| 
 | ||||
|             m_islastPage =currentChapter == mBookUtil.getChapters().size() ||mBookUtil.getChapters().size()==0; | ||||
|                 mStatus = Status.OPENING; | ||||
|                 drawStatus(); | ||||
|                 new Thread() { | ||||
|                     @Override | ||||
|                     public void run() { | ||||
|                         int slepttime = 0; | ||||
|                          while (mBookUtil.getChapters().size()==0 && (mBookUtil.mMuluStatus == BookUtil.MuluStatus.isDownloading || mBookUtil.muluRetryCount < Constants.retryCnt)) { | ||||
|                             try { | ||||
|                                 sleep(50); | ||||
|                                 slepttime++; | ||||
| 
 | ||||
|                             } catch (InterruptedException e) { | ||||
|                                 e.printStackTrace(); | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         Log.d(TAG, String.format("prepare book waiting for chapters slept %s, chapt size %s " , slepttime *50,mBookUtil.getChapters().size())); | ||||
| 
 | ||||
|                          if(mBookUtil.getChapters().size()>0){ | ||||
|                            handler.sendEmptyMessage(MSG_NEXTPAGE) ; | ||||
|                          } | ||||
| 
 | ||||
|                     }}.start(); | ||||
| 
 | ||||
|                 return; | ||||
|             } | ||||
|             m_islastPage =currentChapter == mBookUtil.getChapters().size();// ||mBookUtil.getChapters().size()==0; | ||||
|             if ( m_islastPage){ | ||||
|                 Toast.makeText(mContext, "已经是最后一页了", Toast.LENGTH_SHORT).show(); | ||||
|                 currentPage(false); | ||||
|                 return; | ||||
|             } else { | ||||
| 
 | ||||
|  | @ -927,6 +1017,12 @@ public static boolean busy(){ | |||
|         } | ||||
|         onDraw(mBookPageWidget.getNextPage(),currentPage.getLines(),true); | ||||
|        Log.d("nextPage","nextPagenext"); | ||||
| 
 | ||||
|         HashMap<String,String> map = new HashMap<String,String>(); | ||||
|         map.put("novel",bookName); | ||||
|         map.put("chapt",getChapter().getChapterName()); | ||||
|         map.put("page",currentPage.getPageNo()+""); | ||||
|         MobclickAgent.onEvent(MyApp.applicationContext, "page_reading", map); | ||||
|     } | ||||
| 
 | ||||
|     //取消翻页 | ||||
|  | @ -947,6 +1043,7 @@ public static boolean busy(){ | |||
| 
 | ||||
|         Log.d(TAG, "prepare book:  start prepare book " + book.getName()); | ||||
| 
 | ||||
|         clear(); | ||||
|         if(getNovel()!=null &&getNovel().getNovelId() !=book.getNovelId()){ //取消未上本书完成的web请求,待验证效果 | ||||
|             try { | ||||
|                 NetUtil.cancelRequest(getNovel().getNovelId()  ); | ||||
|  | @ -986,8 +1083,8 @@ if(book==null){ | |||
|            NetUtil.cancelRequest(getNovel().getNovelId() ); | ||||
|         } | ||||
| 
 | ||||
|         bookPath = getNovel().getNovelPath(); | ||||
|         bookName =getNovel().getName();// FileUtils.getFileName(bookPath); | ||||
|         bookPath = book.getNovelPath(); | ||||
|         bookName =book.getName();// FileUtils.getFileName(bookPath); | ||||
|       //  this.mCurrentChapter = chapter; | ||||
|         mStatus = Status.OPENING; | ||||
|         drawStatus(); | ||||
|  | @ -1076,7 +1173,11 @@ if(book==null){ | |||
|                preReadChaptCache(currentChapter + 1); | ||||
|            } | ||||
|        } | ||||
|        if(currentChaptPages.size()>nextPageNo) | ||||
|             return currentChaptPages.get(nextPageNo); | ||||
|        else{ | ||||
|            return new TRPage("没有了"); | ||||
|        } | ||||
|     } | ||||
| 
 | ||||
|     public TRPage getPrePage(){ | ||||
|  | @ -1133,20 +1234,22 @@ if(book==null){ | |||
|         float width = 0; | ||||
|         float height = 0; | ||||
|         String line = ""; | ||||
|         if(mBookUtil.getPosition()==0) { | ||||
|         if(mBookUtil.getPosition(chaptId)==0) { | ||||
|         lines.add("\n");lines.add("\n"); | ||||
|         } | ||||
|         calculateLineCount(); | ||||
|         while (mBookUtil.next(true,chaptId) != -1){ | ||||
|             char word = (char) mBookUtil.next(false,chaptId); | ||||
|         //    Log.d(TAG, String.format(" loadchapt  getNextLines(), chaptId %s, word '%s'", chaptId,word  )); | ||||
|             //判断是否换行 | ||||
|             if ((word + "" ).equals("\n")  ){//   if ((word + "" ).equals("\r") && (((char) mBookUtil.next(true)) + "").equals("\n")){ | ||||
|               //  mBookUtil.next(false); | ||||
|                 if ( !line.isEmpty()){ | ||||
|                     if (showChapTitleOnTopWhenNextPage && lines.size() >0 && mBookUtil.isChapterTitle(line)) { | ||||
|                        Log.d(TAG,String.format("title is %s\n,size is %s ,position is %s" ,line,line.length(),mBookUtil.getPosition()  )); | ||||
|                        Log.d(TAG,String.format("title is %s\n,size is %s ,position is %s" ,line,line.length(),mBookUtil.getPosition(chaptId)  )); | ||||
|                          break; | ||||
|                     } | ||||
|                 //    Log.d(TAG, String.format(" loadchapt  getNextLines(),chaptId %s, new line with enter '%s' ", chaptId, line+word  )); | ||||
|                     lines.add(line+word); | ||||
|                   //  lines.add("\n"); | ||||
|                     line = ""; | ||||
|  | @ -1162,9 +1265,12 @@ if(book==null){ | |||
|             }else { | ||||
|                 float widthChar = mPaint.measureText(word + ""); | ||||
|                 width += widthChar; | ||||
|            //     Log.d(TAG, String.format(" loadchapt  getNextLines(),widthChar %s ,width %s,mVisibleWidth %s",widthChar, width ,mVisibleWidth )); | ||||
| 
 | ||||
|                 if (width > mVisibleWidth) { | ||||
|                     width = widthChar; | ||||
|                     lines.add(line); | ||||
|               //      Log.d(TAG, String.format(" loadchapt  getNextLines(),chaptId %s,new line '%s' ",chaptId , line   )); | ||||
|                    /* if (lines.size() == mLineCount){ | ||||
|                        Log.d(TAG,String.format("lines count limit b %s,lines size %s",mLineCount,lines.size())); | ||||
|                         line =""; | ||||
|  | @ -1173,15 +1279,17 @@ if(book==null){ | |||
|                     */ | ||||
|                     line = word + ""; | ||||
|                 } else { | ||||
| 
 | ||||
|                     line += word; | ||||
|                 //    Log.d(TAG, String.format(" loadchapt  getNextLines(),chaptId %s,growing line '%s' ",chaptId , line   )); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (lines.size() == mLineCount){ | ||||
|              //  Log.d(TAG,String.format("lines count limit c %s,lines size %s",mLineCount,lines.size())); | ||||
|             // Log.d(TAG,String.format("loadchapt lines count ,chaptId %s limit c %s,lines size %s",chaptId ,mLineCount,lines.size())); | ||||
|                 if (!line.isEmpty()){ | ||||
|                   //  mBookUtil.setPostition(mBookUtil.getPosition() - line.length()-2);// mBookUtil.setPostition(mBookUtil.getPosition() - 1); | ||||
|                     mBookUtil.setPostition(mBookUtil.getPosition() - 1); | ||||
|                     mBookUtil.setPostition(chaptId,mBookUtil.getPosition(chaptId) - 1); | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|  | @ -1211,7 +1319,7 @@ if(book==null){ | |||
|         return lines; | ||||
|     } | ||||
| 
 | ||||
|     public List<String> getPreLines(){ | ||||
|     /*public List<String> getPreLines(){ | ||||
|         List<String> lines = new ArrayList<>(); | ||||
|         float width = 0; | ||||
|         String line = ""; | ||||
|  | @ -1233,11 +1341,11 @@ if(book==null){ | |||
| //               Log.d(TAG,"preLine is \n" + line); | ||||
|             } | ||||
| 
 | ||||
|           /*  if ( mBookUtil.isChapterTitle(line)) { | ||||
|           *//*  if ( mBookUtil.isChapterTitle(line)) { | ||||
| 
 | ||||
|                 mBookUtil.setPostition(mBookUtil.getPosition() - line.length()-2); | ||||
|                 break; | ||||
|             }*/ | ||||
|             }*//* | ||||
|             //   lines.add(line); | ||||
| 
 | ||||
|             // Log.d(TAG,"preLine is \n" + line); | ||||
|  | @ -1275,7 +1383,7 @@ if(book==null){ | |||
|         } | ||||
| 
 | ||||
|         return reLines; | ||||
|     } | ||||
|     }*/ | ||||
| 
 | ||||
| 
 | ||||
|     //上一章 | ||||
|  | @ -1359,7 +1467,7 @@ if(book==null){ | |||
| 
 | ||||
|     //更新电量 | ||||
|     public void updateBattery(int mLevel){ | ||||
|        if(mAd!=null) mAd.hideSystemUI(); | ||||
|        hideSysUI(); | ||||
|         if (currentPage != null && mBookPageWidget != null && !mBookPageWidget.isRunning()) { | ||||
| 
 | ||||
|             Log.d(TAG, String.format("updateBattery: level old %s, new %s",level,mLevel)); | ||||
|  | @ -1371,7 +1479,7 @@ if(book==null){ | |||
|     } | ||||
| 
 | ||||
|     public void updateTime(){ | ||||
|         if(mAd!=null)  mAd.hideSystemUI(); | ||||
|          hideSysUI(); | ||||
|         if (currentPage != null && mBookPageWidget != null && !mBookPageWidget.isRunning()) { | ||||
|             String mDate = sdf.format(new java.util.Date()); | ||||
|             if (date != mDate) { | ||||
|  | @ -1518,7 +1626,7 @@ if(book==null){ | |||
|     } | ||||
| 
 | ||||
|     public void clear(){ | ||||
|         Log.d(TAG, String .format("prepare Book: clearing book info %s" ,  getNovle().getName())); | ||||
| //        Log.d(TAG, String .format("prepare Book: clearing book info %s" ,  getNovle().getName())); | ||||
|         fileRetryCnt.clear(); | ||||
|         lastPageTime=0; | ||||
|        if(chaptMap!=null){ | ||||
|  | @ -1641,8 +1749,13 @@ if(book==null){ | |||
|         return new Novel(); | ||||
|     } | ||||
|     public Site getSite(){ | ||||
|         if(mBookUtil!=null){ | ||||
|             return mBookUtil.getSite(); | ||||
|         } | ||||
|       else{ | ||||
|           return  new Site(); | ||||
|         } | ||||
|     } | ||||
|     public boolean isWorking(){ | ||||
|         return mBookUtil !=null; | ||||
|     } | ||||
|  |  | |||
|  | @ -0,0 +1,23 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <shape xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <!-- 实心 --> | ||||
|     <solid android:color="@color/colorPrimaryDark"/> | ||||
|     <!-- 渐变 --> | ||||
|      <gradient | ||||
|         android:startColor="@color/colorPrimary" | ||||
|         android:endColor="@color/colorPrimaryDark" | ||||
|         android:angle="270" /> | ||||
| 
 | ||||
|     <!-- 描边 --> | ||||
|     <stroke | ||||
|         android:width="2dp" | ||||
|         android:color="@color/white" /> | ||||
|     <!-- 圆角 --> | ||||
|     <corners | ||||
|         android:radius="8dp" /> | ||||
|     <padding | ||||
|         android:left="11dp" | ||||
|         android:top="2dp" | ||||
|         android:right="11dp" | ||||
|         android:bottom="3dp" /> | ||||
| </shape> | ||||
|  | @ -0,0 +1,23 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <shape xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <!-- 实心 --> | ||||
|     <solid android:color="@color/read_dialog_bg"/> | ||||
|     <!-- 渐变 --> | ||||
|     <!--<gradient--> | ||||
|         <!--android:startColor="#ff8c00"--> | ||||
|         <!--android:endColor="#FFFFFF"--> | ||||
|         <!--android:angle="270" />--> | ||||
| 
 | ||||
|     <!-- 描边 --> | ||||
|     <stroke | ||||
|         android:width="1dp" | ||||
|         android:color="@color/white" /> | ||||
|     <!-- 圆角 --> | ||||
|     <corners | ||||
|         android:radius="6dp" /> | ||||
|     <padding | ||||
|         android:left="5dp" | ||||
|         android:top="5dp" | ||||
|         android:right="5dp" | ||||
|         android:bottom="5dp" /> | ||||
| </shape> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M18,2H6c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zM6,4h5v8l-2.5,-1.5L6,12V4z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M17,3L7,3c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3L19,5c0,-1.1 -0.9,-2 -2,-2zM17,18l-5,-2.18L7,18L7,5h10v13z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M14,4l2.29,2.29 -2.88,2.88 1.42,1.42 2.88,-2.88L20,10L20,4zM10,4L4,4v6l2.29,-2.29 4.71,4.7L11,20h2v-8.41l-5.29,-5.3z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M14,2L6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6zM16,18L8,18v-2h8v2zM16,14L8,14v-2h8v2zM13,9L13,3.5L18.5,9L13,9z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M10,20h4L14,4h-4v16zM4,20h4v-8L4,12v8zM16,9v11h4L20,9h-4z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM9,17L7,17v-7h2v7zM13,17h-2L11,7h2v10zM17,17h-2v-4h2v4z"/> | ||||
| </vector> | ||||
|  | @ -0,0 +1,5 @@ | |||
| <vector android:height="24dp" android:tint="#FFFFFF" | ||||
|     android:viewportHeight="24.0" android:viewportWidth="24.0" | ||||
|     android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <path android:fillColor="#FF000000" android:pathData="M2,20h20v-4L2,16v4zM4,17h2v2L4,19v-2zM2,4v4h20L22,4L2,4zM6,7L4,7L4,5h2v2zM2,14h20v-4L2,10v4zM4,11h2v2L4,13v-2z"/> | ||||
| </vector> | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 129 KiB | 
|  | @ -0,0 +1,18 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <selector | ||||
|   xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:state_selected="true"> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <solid android:color="#00000000" /> | ||||
|             <stroke android:width="0.5dip" android:color="@color/colorPrimary" /> | ||||
|             <corners android:radius="2.0dip" /> | ||||
|         </shape> | ||||
|     </item> | ||||
|     <item> | ||||
|         <shape android:shape="rectangle"> | ||||
|             <solid android:color="#00000000" /> | ||||
|             <stroke android:width="0.30000007dip" android:color="#fff8f8f8" /> | ||||
|             <corners android:radius="2.0dip" /> | ||||
|         </shape> | ||||
|     </item> | ||||
| </selector> | ||||
|  | @ -168,6 +168,7 @@ | |||
|         android:layout_height="@dimen/botoomNavi" | ||||
|         android:layout_gravity="bottom" | ||||
|         android:layout_weight="0" | ||||
|         android:background="@color/white" | ||||
|         android:orientation="horizontal"> | ||||
| 
 | ||||
|         <Button | ||||
|  | @ -176,18 +177,14 @@ | |||
|             android:layout_height="match_parent" | ||||
|             android:layout_weight="1" | ||||
|             android:background="@drawable/item_selector" | ||||
|             android:drawableTop="@drawable/ic_mood_black_24dp" | ||||
|             android:text="加入书架" /> | ||||
| 
 | ||||
|         <Button | ||||
|             android:id="@+id/btnRead" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_weight="0.8" | ||||
|             android:background="@drawable/item_selector_red" | ||||
|             android:text="立即阅读" | ||||
|             android:textColor="@color/white" | ||||
|             android:textSize="15sp" /> | ||||
|             android:text="加入书架" /> | ||||
|         <View | ||||
|             android:layout_margin="2dp" | ||||
|             android:layout_width="2dp" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:background="@color/whitesmoke"/> | ||||
| 
 | ||||
| 
 | ||||
|         <Button | ||||
|             android:id="@+id/btnCacheBook" | ||||
|  | @ -195,9 +192,21 @@ | |||
|             android:layout_height="match_parent" | ||||
|             android:layout_weight="1" | ||||
|             android:background="@drawable/item_selector" | ||||
|             android:drawableTop="@drawable/ic_mood_black_24dp" | ||||
| 
 | ||||
| 
 | ||||
|             android:text="全本缓存" /> | ||||
| 
 | ||||
|         <Button | ||||
|             android:id="@+id/btnRead" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_weight="0.7" | ||||
|             android:background="@drawable/item_selector_red" | ||||
|             android:text="转码阅读" | ||||
|             android:textColor="@color/white" | ||||
|             android:textSize="15sp" /> | ||||
| 
 | ||||
| 
 | ||||
|     </LinearLayout> | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,7 +19,8 @@ | |||
|             android:layout_height="50dp" | ||||
|             android:layout_gravity="bottom" | ||||
|             android:layout_weight="0" | ||||
|             android:orientation="horizontal"> | ||||
|             android:orientation="horizontal" | ||||
|             android:visibility="gone"> | ||||
| 
 | ||||
|             <TextView | ||||
|                 android:layout_width="match_parent" | ||||
|  | @ -66,7 +67,7 @@ | |||
|         </LinearLayout> | ||||
| 
 | ||||
| 
 | ||||
|         <LinearLayout style="@style/llGraySplit.2dp" /> | ||||
|         <LinearLayout style="@style/llGraySplit" /> | ||||
| 
 | ||||
| 
 | ||||
|         <LinearLayout | ||||
|  | @ -123,40 +124,41 @@ | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         <LinearLayout style="@style/llGraySplit.2dp" /> | ||||
|         <LinearLayout style="@style/llGraySplit" /> | ||||
| 
 | ||||
|         <LinearLayout | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:orientation="vertical"> | ||||
| 
 | ||||
|           <!--  <LinearLayout | ||||
|              <LinearLayout | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:orientation="horizontal" | ||||
|                 android:visibility="gone" | ||||
|                 android:visibility="visible" | ||||
|                 > | ||||
| 
 | ||||
|                 <TextView | ||||
|                     android:layout_width="5dp" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:background="@color/colorAccent" | ||||
| 
 | ||||
|                     android:visibility="gone" | ||||
|                     /> | ||||
| 
 | ||||
|                 <TextView | ||||
|                     style="@style/TextViewTitle" | ||||
|                     android:layout_marginTop="5dp" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:text="目录" /> | ||||
| 
 | ||||
|             </LinearLayout>--> | ||||
|             </LinearLayout> | ||||
| 
 | ||||
|             <LinearLayout | ||||
|                 android:id="@+id/llCate" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_marginTop="10dp" | ||||
|                 android:layout_marginTop="5dp" | ||||
|                 android:layout_marginBottom="10dp" | ||||
|                 android:gravity="center_vertical" | ||||
|                 android:orientation="horizontal"> | ||||
|  | @ -206,7 +208,7 @@ | |||
|             </LinearLayout> | ||||
|         </LinearLayout> | ||||
| 
 | ||||
|         <LinearLayout style="@style/llGraySplit.2dp" /> | ||||
|         <LinearLayout style="@style/llGraySplit" /> | ||||
| 
 | ||||
|        <!-- | ||||
|         <LinearLayout | ||||
|  | @ -270,6 +272,7 @@ | |||
|             android:id="@+id/tvAuthorMore" | ||||
|             style="@style/NovelBlockTitle" | ||||
|             android:layout_marginBottom="5dp" | ||||
|             android:layout_marginTop="5dp" | ||||
|             android:layout_weight="1" | ||||
|             android:text=" 其他作品" /> | ||||
| 
 | ||||
|  | @ -280,11 +283,11 @@ | |||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:nestedScrollingEnabled="false" | ||||
|             android:paddingBottom="50dp" | ||||
|             android:paddingBottom="2dp" | ||||
|             /> | ||||
| 
 | ||||
|         </LinearLayout> | ||||
| 
 | ||||
|         <LinearLayout style="@style/llGraySplit" /> | ||||
|         <LinearLayout | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content" | ||||
|  | @ -294,6 +297,7 @@ | |||
|                 android:id="@+id/tvTonglei" | ||||
|                 style="@style/NovelBlockTitle" | ||||
|                 android:layout_marginBottom="5dp" | ||||
|                 android:layout_marginTop="5dp" | ||||
|                 android:layout_weight="1" | ||||
|                 android:text="同类推荐" /> | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
| xmlns:tools="http://schemas.android.com/tools" | ||||
|     style="@style/llOutside" | ||||
|    android:layout_marginBottom ="0dp" | ||||
| 
 | ||||
| app:layout_behavior="@string/appbar_scrolling_view_behavior" | ||||
| > | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ | |||
|                 android:layout_marginLeft="5dp" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:src="@drawable/ic_refresh_black_24dp" | ||||
|                 app:srcCompat="@drawable/ic_refresh_black_24dp" | ||||
|                 style="@style/buttonCates"/> | ||||
| 
 | ||||
|             <ImageButton | ||||
|  | @ -35,7 +35,7 @@ | |||
|                 android:layout_marginRight="10dp" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:src="@drawable/ic_format_line_spacing_black_24dp" | ||||
|                 app:srcCompat="@drawable/ic_format_line_spacing_black_24dp" | ||||
|                 style="@style/buttonCates"/> | ||||
|         </android.support.v7.widget.Toolbar> | ||||
|     </android.support.design.widget.AppBarLayout> | ||||
|  |  | |||
|  | @ -0,0 +1,10 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <menu xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||
|     <item | ||||
|         android:id="@+id/action_change_source" | ||||
|         android:title="@string/action_change_source" | ||||
|         android:orderInCategory="90" | ||||
|         app:showAsAction="always" /> | ||||
| 
 | ||||
| </menu> | ||||
|  | @ -3,17 +3,17 @@ | |||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/navigation_home" | ||||
|         android:icon="@drawable/ic_favorite_border_black_24dp" | ||||
|         android:icon="@drawable/ic_collections_bookmark_black_24dp" | ||||
|         android:title="@string/title_home" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/navigation_dashboard" | ||||
|         android:icon="@drawable/ic_library_books_black_24dp" | ||||
|         android:icon="@drawable/ic_storage_black_24dp" | ||||
|         android:title="@string/title_dashboard" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/navigation_notifications" | ||||
|         android:icon="@drawable/ic_star_border_black_24dp" | ||||
|         android:icon="@drawable/ic_rank_24dp" | ||||
|         android:title="@string/title_notifications" /> | ||||
| 
 | ||||
| </menu> | ||||
|  |  | |||
|  | @ -1,16 +1,29 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <menu xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/action_add_bookmark" | ||||
|         android:title="" | ||||
|         android:icon= "@drawable/ic_bookmark_border_black_24dp" | ||||
|         android:orderInCategory="10" | ||||
|         app:showAsAction="always" /> | ||||
|     <item | ||||
|         android:id="@+id/action_refresh" | ||||
|         android:orderInCategory="20" | ||||
|         android:title="" | ||||
|         android:icon= "@drawable/ic_refresh_black_24dp" | ||||
|     app:showAsAction="always" /> | ||||
|     <item | ||||
|         android:id="@+id/action_bookdetail" | ||||
|         android:orderInCategory="30" | ||||
|         android:title="" | ||||
|         android:icon= "@drawable/ic_description_black_24dp" | ||||
|         app:showAsAction="always" /> | ||||
|     <item | ||||
|     android:id="@+id/action_change_source" | ||||
|     android:title="@string/action_change_source" | ||||
|         android:orderInCategory="90" | ||||
|         app:showAsAction="ifRoom" /> | ||||
|     <item | ||||
|         android:id="@+id/action_add_bookmark" | ||||
|         android:title="@string/action_add_bookmark" | ||||
|         android:orderInCategory="90" | ||||
|         app:showAsAction="ifRoom" /> | ||||
| 
 | ||||
| 
 | ||||
|         android:icon= "@drawable/ic_call_split_black_24dp" | ||||
|     android:orderInCategory="40" | ||||
|     app:showAsAction="always" /> | ||||
| </menu> | ||||
|  | @ -140,7 +140,7 @@ | |||
| 
 | ||||
|     <string name="action_select_file">导入书本</string> | ||||
|     <string name="action_change_source">换源</string> | ||||
|     <string name="action_add_bookmark">添加书签</string> | ||||
|     <string name="action_add_bookmark">书签</string> | ||||
|     <string name="action_read_book">读书</string> | ||||
| 
 | ||||
|     <string name="press_twice_to_exit">连续点击才能退出</string> | ||||
|  | @ -198,6 +198,7 @@ | |||
|     <string name="soft_update_later">以后再说</string> | ||||
|     <string name="soft_updating">正在更新</string> | ||||
|     <string name="soft_update_cancel">取消更新</string> | ||||
|     <string name="action_novelDetail">详情</string> | ||||
| 
 | ||||
|     <string-array name="voicer_cloud_entries"> | ||||
|         <item>小燕—女青、中英、普通话</item> | ||||
|  |  | |||
|  | @ -131,9 +131,11 @@ | |||
|     </style> | ||||
|     <style name="TextViewTitle"> | ||||
|         <item name="android:paddingLeft">5dp</item> | ||||
|         <item name="android:textColor">@color/darkcyan</item> | ||||
|         <item name="android:textSize">18sp</item> | ||||
|         <item name="android:textColor">@color/read_font_1</item> | ||||
|         <item name="android:textSize">15sp</item> | ||||
|         <item name="android:textStyle">bold</item> | ||||
|         <item name="android:layout_width">wrap_content</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
| 
 | ||||
|     </style> | ||||
| 
 | ||||
|  |  | |||
|  | @ -88,7 +88,6 @@ | |||
|       <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" /> | ||||
|  | @ -96,7 +95,6 @@ | |||
|       <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-run-resources" /> | ||||
|       <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" /> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue