diff --git a/zhuike/src/main/AndroidManifest.xml b/zhuike/src/main/AndroidManifest.xml index 520db16..77f87af 100644 --- a/zhuike/src/main/AndroidManifest.xml +++ b/zhuike/src/main/AndroidManifest.xml @@ -12,51 +12,42 @@ android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:launchMode="singleInstance" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/ToolBarTheme" - android:launchMode="singleInstance" android:usesCleartextTraffic="true"> - + - - - - - + android:theme="@style/ToolBarTheme.NoActionBar"> - + android:theme="@style/ToolBarTheme.NoActionBar"> @@ -64,28 +55,26 @@ - - - - + android:theme="@style/ToolBarTheme.NoActionBar"> - + android:theme="@style/ToolBarTheme.NoActionBar"> - - - - + android:theme="@style/ToolBarTheme.NoActionBar"> + + \ No newline at end of file diff --git a/zhuike/src/main/assets/litepal.xml b/zhuike/src/main/assets/litepal.xml index f9ad3e5..eec8672 100644 --- a/zhuike/src/main/assets/litepal.xml +++ b/zhuike/src/main/assets/litepal.xml @@ -2,7 +2,7 @@ - + diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_cache.java b/zhuike/src/main/java/com/novelbook/android/Activity_cache.java new file mode 100644 index 0000000..7438b59 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/Activity_cache.java @@ -0,0 +1,359 @@ +package com.novelbook.android; + +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.novelbook.android.Activity_base; +import com.novelbook.android.R; +import com.novelbook.android.bean.Cataloge; +import com.novelbook.android.db.Chapter; +import com.novelbook.android.db.DownloadTask; +import com.novelbook.android.db.Novel; +import com.novelbook.android.service.ServiceDownload; +import com.novelbook.android.utils.ImageUtil; + +import org.litepal.LitePal; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class Activity_cache extends Activity_base { + public static final String TAG=Activity_cache.class.getSimpleName(); + @BindView(R.id.recycleView) + RecyclerView mRecyclerView; + private List mData; + private CacheAdapter mAdapter; + @Override + public int getLayoutRes() { + return R.layout.activitycache; + } + + @Override + protected void initViews() { + + } + + @Override + protected void setTitle() { + + } + + @Override + protected void initData() { + initiDownloadReceiver(); + mData = LitePal.findAll(DownloadTask.class); + + mAdapter = new CacheAdapter(this,mData,R.layout.recycle_list_item_cache,new OnItemClickLitener() { + @Override + public void onItemClick(View view, int position) { + Novel novel = LitePal.find(Novel.class,mData.get(position).getNovelId()); + showBookDetail(novel); + } + + @Override + public void onItemLongClick(View view, int position) + { + final AlertDialog.Builder normalDialog = + new AlertDialog.Builder(Activity_cache.this); + + normalDialog.setTitle("删除此下载任务并清除缓存吗"); + normalDialog.setMessage("确定删除吗?"); + normalDialog.setPositiveButton("取消", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + } + }); + normalDialog.setNegativeButton("删除", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + DownloadTask cl = mData.get(position); + cl.delete(); + // Chapter.deleteByTask(); + //TODO:clear cache ? + + + mAdapter.removeData(position); + + } + }); + + normalDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + + } + }); + // 显示 + normalDialog.show(); + // mAdapter.removeData(position); + } + + }); + + mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + mRecyclerView.setAdapter(mAdapter ); + + + + } + + @Override + public void fillData() { + + } + + private IntentFilter filter; + DownloadProcessReceiver receiver; + void initiDownloadReceiver(){ + filter = new IntentFilter("ServiceDownload.ChapterContent.finished"); + filter.addCategory(Intent.CATEGORY_DEFAULT); + receiver = new DownloadProcessReceiver(); + } + class DownloadProcessReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent){ + int taskId =0; + int progress=0; + + if( intent.hasExtra("progress")){ + progress = intent.getIntExtra("progress",0); + } + if( intent.hasExtra("taskId")){ + taskId = intent.getIntExtra("taskId",0); + } + + Log.d(TAG, String.format("onReceive: taskId %s progress %s ",taskId,progress)); + for(DownloadTask dt : mData){ + if(taskId == dt.getId()){ + dt.setFinishedChpats(progress); + if(dt.getDownSatus()!=DownloadTask.DownStatus.等待下载) { + dt.setDownSatus(DownloadTask.DownStatus.正在下载); + } + }else{ + if(dt.getDownSatus()!=DownloadTask.DownStatus.正在下载) { + dt.setDownSatus(DownloadTask.DownStatus.排队中); + } + } + } + + mAdapter.setData(mData); + + + } + } + private void startDownloadService(int taskId,boolean start) { + Intent serviceIntent = new Intent(this, ServiceDownload.class); + serviceIntent.putExtra("taskId",taskId); + serviceIntent.putExtra("start",start); + startService(serviceIntent); + } + + @Override + protected void onResume() { + super.onResume(); + registerReceiver(receiver, filter); + } + + @Override + public void onPause() { + super.onPause(); + unregisterReceiver(receiver); + } + + class CacheAdapter extends RecyclerView.Adapter { + private final int EMPTY_VIEW = 1; + private final int PROGRESS_VIEW = 2; + private final int IMAGE_VIEW = 3; + + private Context context; + private List mDatas = new ArrayList(); + private OnItemClickLitener mOnItemClickLitener; + private int listItemID; + + public CacheAdapter(Context context, List mDatas, int listItemID, OnItemClickLitener clickLitener) { + this.context = context; + this.mDatas = mDatas; + this.mOnItemClickLitener = clickLitener; + this.listItemID = listItemID; + } + + public CacheAdapter(Context context, OnItemClickLitener clickLitener) { + this.context = context; + this.mOnItemClickLitener = clickLitener; + + } + + @Override + public int getItemViewType(int position) { + if (mDatas.size() == 0) { + return EMPTY_VIEW; + } else if (mDatas.get(position) == null) { + return PROGRESS_VIEW; + } else { + return super.getItemViewType(position); + } + } + + @Override + public CacheAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + CacheAdapter.MyViewHolder holder = new CacheAdapter.MyViewHolder(LayoutInflater.from( + context).inflate(listItemID, parent, + false)); + return holder; + } + + + public void setParameters(List mDatas, int listItemID) { + this.mDatas = mDatas; + this.listItemID = listItemID; + } + + public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) { + this.mOnItemClickLitener = mOnItemClickLitener; + } + + @Override + public void onBindViewHolder(CacheAdapter.MyViewHolder holder, int position) { + holder.tvTitle.setText(mDatas.get(position).getNovelTitle()); + holder.tvSource.setText(mDatas.get(position).getDomainName()); + boolean finished = mData.get(position).getFinishedChpats() == mData.get(position).getTotalChapts(); + + if( mData.get(position).getTotalChapts() >0) { + float progress = mData.get(position).getFinishedChpats() *100/ mData.get(position).getTotalChapts() ; + holder.tvProgress.setText(String.format("%s/%s",mData.get(position).getFinishedChpats() , mData.get(position).getTotalChapts())); + + holder.tvStatus.setText( mData.get(position).getDownSatus() == DownloadTask.DownStatus.正在下载 ?"正在下载" + : mData.get(position).getDownSatus() == DownloadTask.DownStatus.等待下载? "暂停下载" :"休眠中"); + + holder.tvStatus.setText( mData.get(position).getStatus()==0 || mData.get(position).getFinishedChpats() >=mData.get(position).getTotalChapts() + ? holder.tvStatus.getText():"下载完成" ); + + holder.tvStatus.setText( mData.get(position).getStatus()==0? holder.tvStatus.getText():"下载完成" ); + + holder.tvStatus.setText( mData.get(position).getDownSatus() == DownloadTask.DownStatus.排队中?"排队中": holder.tvStatus.getText() ); + + holder.barProgress.setProgress((int)progress); + } + // holder.imgStart.setVisibility(View.GONE); + int img = R.mipmap.play; + img = mData.get(position).getDownSatus() == DownloadTask.DownStatus.正在下载 ? R.mipmap.pause : R.mipmap.play; + + holder.imgStart.setImageResource( img); + holder.imgStart.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getLayoutPosition(); + + if(mData.get(position).getDownSatus() != DownloadTask.DownStatus.正在下载) { + startDownloadService(mData.get(pos).getId(),true); + holder.imgStart.setImageResource( R.mipmap.pause); + mData.get(pos).setDownSatus(DownloadTask.DownStatus.排队中); + + }else{ + startDownloadService(mData.get(pos).getId(),false); + holder.imgStart.setImageResource( R.mipmap.play); + mData.get(pos).setDownSatus(DownloadTask.DownStatus.等待下载); + } + mData.get(pos).update( mData.get(pos).getId()); + + + } + }); + + // 如果设置了回调,则设置点击事件 + if (mOnItemClickLitener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getLayoutPosition(); + mOnItemClickLitener.onItemClick(holder.itemView, pos); + } + }); + } + + holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + int pos = holder.getLayoutPosition(); + mOnItemClickLitener.onItemLongClick(holder.itemView, pos); + return false; + } + }); + + } + + @Override + public int getItemCount() { + return mDatas.size(); + } + + public void addData(int position) { + // mDatas.add(position, "Insert One"); + // notifyItemInserted(position); + } + + public void removeData(int position) { + mDatas.remove(position); + notifyItemRemoved(position); + notifyDataSetChanged(); + } + + public void setData(List data) { + mData = data; + notifyDataSetChanged(); + } + + class MyViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.tvTitle) + TextView tvTitle; + @BindView(R.id.tvProgress) + TextView tvProgress; + @BindView(R.id.tvStatus) + TextView tvStatus; + @BindView(R.id.barProgress) + ProgressBar barProgress; + @BindView(R.id.imgStart) + ImageView imgStart; + @BindView(R.id.tvSource) + TextView tvSource; + public MyViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + //tvTitle = (TextView) view.findViewById(R.id.title); + // tvAuthor = (TextView) view.findViewById(R.id.author); + + } + } + } + interface OnItemClickLitener + { + void onItemClick(View view, int position); + + void onItemLongClick(View itemView, int pos); + } + + +} diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java b/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java index ce8032b..4ba1212 100644 --- a/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java +++ b/zhuike/src/main/java/com/novelbook/android/Activity_paihangbang.java @@ -29,9 +29,9 @@ public static String TAG ="com.novelbook.android.paihangbang"; ViewPager mViewpager; @BindView(R.id.tab_layout) SlidingTabLayout tabLayout; - public static String EXTR_FN="fn"; - public static String EXTR_TITLE="title"; - public static String EXTR_BANGDAN ="bangdan"; + public static final String EXTR_FN="fn"; + public static final String EXTR_TITLE="title"; + public static final String EXTR_BANGDAN ="bangdan"; public static final String EXTR_SEARCH ="search"; public static final String EXTR_HISTORY ="history" ; private ArrayList mFragments; diff --git a/zhuike/src/main/java/com/novelbook/android/BookActivity.java b/zhuike/src/main/java/com/novelbook/android/BookActivity.java index 84a45e1..5ed9400 100644 --- a/zhuike/src/main/java/com/novelbook/android/BookActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/BookActivity.java @@ -353,6 +353,10 @@ public class BookActivity extends Activity_base { Toast.makeText(BookActivity.this, "已加入下载队列1", Toast.LENGTH_LONG).show(); } else if (msg.what == 3) { Toast.makeText(BookActivity.this, "获取目录信息失败,下载失败", Toast.LENGTH_LONG).show(); + }else if (msg.what == 4) { + Toast.makeText(BookActivity.this, String.format("亲,小说《%s》已经缓存完成了", mNovel.getName()), Toast.LENGTH_LONG).show(); + }else if (msg.what == 5) { + Toast.makeText(BookActivity.this, String.format("亲,小说《%s》已经在缓存队列了,请耐心等待", mNovel.getName()), Toast.LENGTH_LONG).show(); } hideProgress(); } @@ -420,20 +424,7 @@ public class BookActivity extends Activity_base { // if (LitePal.where("novelId = ?", mNovel.getId() + "").count("DownloadTask") > 0) { - List dts = LitePal.where("novelId = ?", mNovel.getId() + "").limit(1).find(DownloadTask.class); - if (dts.size() > 0) { - if (dts.get(0).getStatus() == 1) { - Toast.makeText(this, String.format("亲,小说《%s》已经缓存完成了", mNovel.getName()), Toast.LENGTH_LONG).show(); - } else { - Toast.makeText(this, String.format("亲,小说《%s》已经在缓存队列了,请耐心等待", mNovel.getName()), Toast.LENGTH_LONG).show(); - startDownloadService(dts.get(0).getId()); - // startService( getSvrIntent()); - } - - return; - - } // } @@ -454,16 +445,40 @@ public class BookActivity extends Activity_base { handler.sendEmptyMessage(3); } else { + + + List dts = LitePal.where("novelId = ? and domain =?", mNovel.getId() + "",mNovel.getDomain()).limit(1).find(DownloadTask.class); + if (dts.size() > 0) { + if (dts.get(0).getStatus() == 1) { + + handler.sendEmptyMessage(4); + + } else { + handler.sendEmptyMessage(5); + + startDownloadService(dts.get(0).getId()); + // startService( getSvrIntent()); + } + + return; + + } + DownloadTask dt = new DownloadTask(); dt.setDomain(mNovel.getDomain()); + dt.setDomainName(mNovel.getDomainName()); dt.setFinishedChpats(0); dt.setNovelId(mNovel.getId()); dt.setStatus(0); - dt.setTotalChapts(mNovel.getTotalChapts()); + // dt.setTotalChapts(mNovel.getChaptCnt()); + dt.setTotalChapts(pageFactory.getChapters().size()); + dt.setNovelTitle(mNovel.getName()); + dt.save(); // LitePal.deleteAll("chapter","novelId=?",mNovel.getId()+""); for (Chapter chapter : pageFactory.getChapters()) { chapter.setNovelId(mNovel.getId()); + chapter.setTaskId(dt.getId()); chapter.save(); } startDownloadService(dt.getId()); diff --git a/zhuike/src/main/java/com/novelbook/android/Main2Activity.java b/zhuike/src/main/java/com/novelbook/android/Main2Activity.java index c0c2eee..62cf466 100644 --- a/zhuike/src/main/java/com/novelbook/android/Main2Activity.java +++ b/zhuike/src/main/java/com/novelbook/android/Main2Activity.java @@ -31,6 +31,7 @@ import com.novelbook.android.Fragments.Fragment_paihang; import com.novelbook.android.netsubscribe.BookSubscribe; import com.novelbook.android.netutils.OnSuccessAndFaultListener; import com.novelbook.android.netutils.OnSuccessAndFaultSub; +import com.novelbook.android.service.ServiceDownload; import com.novelbook.android.utils.Config; import com.novelbook.android.utils.Constants; import com.novelbook.android.utils.GsonUtil; @@ -268,8 +269,10 @@ public class Main2Activity extends Activity_base intent.putExtra(Activity_paihangbang.EXTR_HISTORY,"yes"); intent.putExtra(Activity_paihangbang.EXTR_TITLE,"我曾经看过的书"); startActivity(intent); - } else if (id == R.id.nav_slideshow) { - + } else if (id == R.id.nav_huancun) { + startDownloadService(); + Intent intent = new Intent(Main2Activity.this,Activity_cache.class); + startActivity(intent); } else if (id == R.id.nav_manage) { } else if (id == R.id.nav_share) { @@ -282,7 +285,11 @@ public class Main2Activity extends Activity_base drawer.closeDrawer(GravityCompat.START); return true; } + private void startDownloadService() { + Intent serviceIntent = new Intent(this, ServiceDownload.class); + startService(serviceIntent); + } private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { diff --git a/zhuike/src/main/java/com/novelbook/android/db/Chapter.java b/zhuike/src/main/java/com/novelbook/android/db/Chapter.java index 5b64309..f8dce80 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/Chapter.java +++ b/zhuike/src/main/java/com/novelbook/android/db/Chapter.java @@ -1,12 +1,17 @@ package com.novelbook.android.db; +import android.text.TextUtils; + import org.litepal.LitePal; import org.litepal.crud.LitePalSupport; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; +import javax.security.auth.callback.CallbackHandler; + public class Chapter extends LitePalSupport implements Serializable { private int id; @@ -19,6 +24,9 @@ public class Chapter extends LitePalSupport implements Serializable { private String chapterPath; //缓存地址 private String domain; //目标 site private int index;//第几章 + private int taskId; + + public static Chapter getChapter(int id, String domain, int chapId) { // Chapter chapter =(Chapter) @@ -37,7 +45,13 @@ public class Chapter extends LitePalSupport implements Serializable { chapter.setChapterPath(""); return chapter; } + public int getTaskId() { + return taskId; + } + public void setTaskId(int taskId) { + this.taskId = taskId; + } public int getIndex() { return index; } @@ -118,10 +132,18 @@ public class Chapter extends LitePalSupport implements Serializable { this.chapterPath = chapterPath; } - public static List getUnCachedChapters(int noveId,String domain ){ + public static List getUnCachedChapters(int taskId){ // return LitePal.where("novelId = ? and domain = ? and chapterPath = null" ,noveId+"",domain ) .find(Chapter.class); - - return LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class); + //ist lst = LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class); + List lst = LitePal.where("taskId= ? " ,taskId+"").find(Chapter.class); + List lstrt = new ArrayList(); + for(Chapter chapter : lst){ + if(TextUtils.isEmpty(chapter.getChapterPath())){ + lstrt.add(chapter); + } + } + return lstrt; + // return LitePal.where("novelId = ? and domain = ? " ,noveId+"",domain).find(Chapter.class); } diff --git a/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java b/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java index 336e18e..9f56a5d 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java +++ b/zhuike/src/main/java/com/novelbook/android/db/DownloadTask.java @@ -9,11 +9,38 @@ public class DownloadTask extends LitePalSupport implements Serializable { private int id; private int novelId; + private String novelTitle; private String domain; + private String domainName; @Column( defaultValue = "0") private int status; //0 未完成 1 完成 private int totalChapts; private int finishedChpats; + private DownStatus downSatus =DownStatus.初始状态;//0 队列外 1 队列内 + + public DownStatus getDownSatus() { + return downSatus; + } + + public void setDownSatus(DownStatus downSatus) { + this.downSatus = downSatus; + } + + public String getNovelTitle() { + return novelTitle; + } + + public void setNovelTitle(String novelTitle) { + this.novelTitle = novelTitle; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } public int getTotalChapts() { return totalChapts; @@ -63,6 +90,9 @@ public class DownloadTask extends LitePalSupport implements Serializable { this.status = status; } + public static enum DownStatus{ + 初始状态,等待下载, 正在下载,排队中,下载完成 + } } diff --git a/zhuike/src/main/java/com/novelbook/android/db/Novel.java b/zhuike/src/main/java/com/novelbook/android/db/Novel.java index 2f16d40..af88998 100644 --- a/zhuike/src/main/java/com/novelbook/android/db/Novel.java +++ b/zhuike/src/main/java/com/novelbook/android/db/Novel.java @@ -24,6 +24,7 @@ public class Novel extends LitePalSupport implements Serializable{ private String name; private String infoUrl; private String domain; + private String domainName; private String muluUrl; private String novelPath; private long lastReadPos; @@ -61,7 +62,13 @@ public class Novel extends LitePalSupport implements Serializable{ this.readtime = readtime; } + public String getDomainName() { + return domainName; + } + public void setDomainName(String domainName) { + this.domainName = domainName; + } public long getLastVisit() { return lastVisit; @@ -127,17 +134,7 @@ public class Novel extends LitePalSupport implements Serializable{ this.progress = progress; } - public int getTotalChapts() { - return totalChapts; - } - - public void setTotalChapts(int totalChapts) { - this.totalChapts = totalChapts; - } - - private int totalChapts; - - public int getId() { + public int getId() { return id; } diff --git a/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java index 807edbf..85ecc67 100644 --- a/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java +++ b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownload.java @@ -1,8 +1,11 @@ package com.novelbook.android.service; import android.app.IntentService; +import android.app.Service; import android.content.Intent; +import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.Message; import android.text.TextUtils; import android.util.Log; @@ -15,6 +18,7 @@ import com.novelbook.android.netutils.HttpMethods; import com.novelbook.android.utils.BookUtil; import com.novelbook.android.utils.NovelParseUtil; +import com.novelbook.android.utils.PageFactory; import org.json.JSONException; import org.json.JSONObject; @@ -41,7 +45,7 @@ import okhttp3.Response; import okhttp3.ResponseBody; -public class ServiceDownload extends IntentService { +public class ServiceDownload extends Service { private static final String TAG ="ServiceDownload" ; private final String storagePath = BookUtil.storagePath; @@ -57,9 +61,9 @@ public class ServiceDownload extends IntentService { // public ServiceDownload(String name) { // super(name); // } - public ServiceDownload() { + /* public ServiceDownload() { super("ServiceDownload"); - } + }*/ private Map siteRuleMap = new HashMap() ; // key = novelId private DownloadTask processingTask ; @@ -67,6 +71,7 @@ public class ServiceDownload extends IntentService { private int chaptIndex=0; private Map> tasksMap = new ConcurrentHashMap>();// key = taskId + private Map> tasksMapDone = new ConcurrentHashMap>();// key = taskId @Override public void onCreate() { @@ -91,18 +96,23 @@ public class ServiceDownload extends IntentService { } + @Override + public int onStartCommand(Intent intent, int flags, int startId){ + // // QLog.getLogger().d( TAG,TAG+"... service NaviSvc onStartCommand.....," ); + onHandleIntent(intent); + // We want this service to continue running until it is explicitly + // stopped, so return sticky. +// return START_NOT_STICKY; //TODO: checking why can not stop the service. + return START_STICKY; + } + + @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.d(TAG,"test service onStart"); } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG,"test service onStartCommand"); - return super.onStartCommand(intent, flags, startId); - - } @Override public void onDestroy() { @@ -110,65 +120,197 @@ public class ServiceDownload extends IntentService { super.onDestroy(); } + @Override + public IBinder onBind(Intent intent) { + // TODO Auto-generated method stub + return null; + } private List downloadTasks = new ArrayList(); - - @Override + + List cancelId =new ArrayList(); + protected void onHandleIntent( Intent intent) { - Log.d(TAG,"test service onHandleIntent...begin"); + Log.d(TAG,"ServiceDownload onHandleIntent...begin"); String key ="taskId"; int taskId =0; + if(intent.hasExtra(key)){ taskId= intent.getExtras().getInt(key); - startNewTask(taskId); + DownloadTask dt = LitePal.find(DownloadTask.class,taskId); + + if(intent.hasExtra("start")){ + if(!intent.getBooleanExtra("start",true)){ + cancelId.add(taskId); + for(DownloadTask t : downloadTasks){ + if( t.getId() == taskId){ + t.setDownSatus(DownloadTask.DownStatus.等待下载); + break; + } + } + stopTask(taskId); + + }else{ + boolean newTask = true; + + if(cancelId.contains(taskId)){ + cancelId.remove(cancelId.indexOf(taskId)); + } + for(DownloadTask t : downloadTasks){ + if(t.getId() == taskId){ + newTask =false; + break; + } + } + + if(newTask) { + startNewTask(dt); + } else { + + for (DownloadTask t : downloadTasks) { + if (t.getId() == taskId) { + t.setDownSatus(DownloadTask.DownStatus.正在下载); + break; + } + } + } + + startTask(taskId); + + if(taskIndex==0) { + + // handler.sendEmptyMessage(1); + } + } + } + + } else{ - /* if(processingTask==null) { + Log.d(TAG,"ServiceDownload downloadTask size: " +downloadTasks.size()); + + + new Thread() { + + @Override + public void run() { + List tmp = LitePal.findAll(DownloadTask.class); + + if (downloadTasks.size() == 0) { + taskIndex = 0; + for (DownloadTask dt : tmp) { + startNewTask(dt); + } + + }else{ + + for (DownloadTask dt : tmp) { + boolean exist = false; + for(DownloadTask t: downloadTasks){ + if(t.getId() == dt.getId()){ + exist =true; + break; + } + } + if(!exist){ + startNewTask(dt); + } + + } + + } + if (taskIndex == 0) { + startTask(); + // handler.sendEmptyMessage(1); + } + } + }.start(); + + + + + /* + if(processingTask==null) { startTask(); }*/ } - Log.d(TAG,"test service onHandleIntent...over"); + Log.d(TAG,"ServiceDownload test service onHandleIntent...over"); } + + Handler handler = new Handler() { @Override public void handleMessage(Message msg) { - if(msg.what ==1){ + /* if(msg.what ==1){ startTask(); - }else if(msg.what==2){ + }else*/ + if(msg.what==2){ + int tIndex = msg.getData().getInt("tIndex"); + + if(tIndex>=downloadTasks.size()) { + return; + } + int taskId = downloadTasks.get(tIndex).getId(); + /* if( downloadTasks.get(taskId).getDownSatus() == DownloadTask.DownStatus.等待下载){ + return; + } if(tasksMap.get(processingTask.getId())==null){ return; } + */ + + if(tasksMap.get(taskId)==null){ + return; + } + Log.d(TAG,String.format("%s start new chapt download---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(), tasksMap.get(processingTask.getId()).size(),chaptIndex )); - - Intent broadcastIntent = new Intent(); - broadcastIntent.setAction("ServiceDownload.ChapterContent.finished"); - broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); - broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()); - broadcastIntent.putExtra("novelId", processingTask.getNovelId()); - sendBroadcast(broadcastIntent); + // if(taskIndex==tIndex+1){ - if( tasksMap.get(processingTask.getId()).size()-1 > chaptIndex){ - chaptIndex++; + Intent broadcastIntent = new Intent(); + broadcastIntent.setAction("ServiceDownload.ChapterContent.finished"); + broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); + broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()>processingTask.getTotalChapts() ?processingTask.getTotalChapts():processingTask.getFinishedChpats()); + broadcastIntent.putExtra("novelId", processingTask.getNovelId()); + broadcastIntent.putExtra("taskId", processingTask.getId()); + sendBroadcast(broadcastIntent); + + // } + + if( tasksMap.get(taskId).size()-1 > chaptIndex){ + if( downloadTasks.get(tIndex).getDownSatus() == DownloadTask.DownStatus.正在下载) { + chaptIndex++; + }else{ + return; + } + }else{ Log.d(TAG,String.format("%s task done ---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(), tasksMap.get(processingTask.getId()).size(),chaptIndex )); //章节全部处理完毕了 - processingTask.setStatus(1); - processingTask.update(processingTask.getId()); - tasksMap.remove(processingTask.getId()); //会不会线程冲突? + if(taskId == processingTask.getId()) { + int abc = 1; + abc++; + if(tasksMap.get(taskId).size() == tasksMapDone.get(taskId).size()) { + processingTask.setStatus(1); + processingTask.update(processingTask.getId()); + // tasksMap.remove(processingTask.getId()); //会不会线程冲突? + } - startTask(); + + } + //startTask(); //auto start next task + return; } - doDownloadContent(); + doDownloadContent(tIndex,chaptIndex); } } @@ -176,22 +318,67 @@ public class ServiceDownload extends IntentService { }; + private void stopTask(int taskId) { + if(processingTask==null || processingTask.getId()==taskId) { + //startTask();//to start next + } + } + + /** + * 启动指定task + * @param taskId + */ + private void startTask(int taskId) { + if ( downloadTasks.size()==0){ + return; + } + if(processingTask!=null) { + processingTask.update(processingTask.getId()); + } + taskIndex=0; + for(DownloadTask task : downloadTasks) { + if(task.getId()==taskId) { + processingTask = task; + break; + } + taskIndex++; + } + + processingTask.setDownSatus(DownloadTask.DownStatus.正在下载); + chaptIndex=0; + doDownloadContent(taskIndex,chaptIndex); + } + + /** + * auto next task + */ private void startTask() { - + if ( downloadTasks.size()==0){ + return; + } if(processingTask!=null) { processingTask.update(processingTask.getId()); } + Log.d(TAG,"ServiceDownload start task to download,index " +taskIndex); + if(downloadTasks.size() <=taskIndex){ + taskIndex=0; processingTask =null; - Log.d(TAG,"No task to download."); - return; + // Log.d(TAG,"No task to download."); + // return; } processingTask = downloadTasks.get(taskIndex); + if(processingTask.getDownSatus()== DownloadTask.DownStatus.等待下载){ + taskIndex++; + startTask(); + return; + } + processingTask.setDownSatus(DownloadTask.DownStatus.正在下载); chaptIndex=0; - doDownloadContent(); + doDownloadContent(taskIndex,chaptIndex); if(taskIndex < downloadTasks.size()-1){ taskIndex++; } @@ -199,16 +386,20 @@ public class ServiceDownload extends IntentService { } - void doDownloadContent(){ - - Log.d(TAG, String.format("ServiceDowload--- taskId: %s ",processingTask.getId())); + void doDownloadContent(int taskIndex,int chaptIndex){ + Message mg = Message.obtain(); + mg.what =2; + Bundle bundleData = new Bundle(); + bundleData.putInt("tIndex", taskIndex); + mg.setData(bundleData); + Log.d(TAG, String.format("ServiceDownload--- taskId: %s ",processingTask.getId())); List chps = tasksMap.get(processingTask.getId()); - if(chps!=null && chps.size()>0) { + if(chps!=null && chps.size()>0 && chps.size() >chaptIndex) { Chapter chapter = chps.get(chaptIndex); if (TextUtils.isEmpty(chapter.getChapterPath())) { try { - ServiceDownload(chapter); + ServiceDownload(taskIndex,chapter); } catch (JSONException e) { e.printStackTrace(); } catch (InterruptedException e) { @@ -218,19 +409,19 @@ public class ServiceDownload extends IntentService { } } else { - handler.sendEmptyMessage(2); + handler.sendMessage(mg); } }else{ - handler.sendEmptyMessage(2); + handler.sendMessage(mg); } } - void startNewTask(int taskId){ + void startNewTask(DownloadTask dt){ + - DownloadTask dt = LitePal.find(DownloadTask.class,taskId); if(dt!=null){ - List chps = Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain() ); + List chps = Chapter.getUnCachedChapters(dt.getId()); if(chps==null || chps.size()==0){ return; } @@ -243,16 +434,16 @@ public class ServiceDownload extends IntentService { downloadTasks.add(dt); - for(DownloadTask tmp: downloadTasks){ + /* for(DownloadTask tmp: downloadTasks){ Log.d(TAG, String.format("test service task list : %s",tmp.getId())); - } + }*/ tasksMap.put(dt.getId(), chps); - if(taskIndex==0) { + /* if(taskIndex==0) { startTask(); // handler.sendEmptyMessage(1); - } + }*/ } } /* @@ -268,21 +459,27 @@ public class ServiceDownload extends IntentService { */ } - private void ServiceDownload( Chapter chapter ) throws JSONException, InterruptedException { + private void ServiceDownload(int taskIndex, Chapter chapter ) throws JSONException, InterruptedException { + int taskID= downloadTasks.get(taskIndex).getId() ; int msg =2; - + Message mg = Message.obtain(); + mg.what =msg; + Bundle bundleData = new Bundle(); + bundleData.putInt("tIndex", taskIndex); + mg.setData(bundleData); String url = chapter.getChapterUrl(); if( TextUtils.isEmpty( url)){ - handler.sendEmptyMessage(msg); + // handler.sendEmptyMessage(msg); + handler.sendMessage(mg); return ; } long startTime= new Date().getTime(); - Log.d(TAG,String.format("ServiceDowload----start download %s from %s", chapter.getChapterName() ,url )); + Log.d(TAG,String.format("ServiceDownload----start download %s from %s", chapter.getChapterName() ,url )); - // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); + // Log.d( "ServiceDownload",String.format("ServiceDownload isDownloadChapt: %s",isDownloadChapt)); JSONObject siteJson = new JSONObject(); siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); @@ -290,10 +487,10 @@ public class ServiceDownload extends IntentService { HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { + handler.sendMessage(mg); + // handler.sendEmptyMessage(msg); - handler.sendEmptyMessage(msg); - - // Log.d( "ServiceDowload",String.format("ServiceDowload fail, isDownloadChapt: %s",isDownloadChapt)); + // Log.d( "ServiceDownload",String.format("ServiceDownload fail, isDownloadChapt: %s",isDownloadChapt)); e.printStackTrace(); // throw new RuntimeException("Error during writing " + fileChapterName( index)); } @@ -303,12 +500,13 @@ public class ServiceDownload extends IntentService { ResponseBody body = response.body(); if (body != null ) { if(response.code()!=200){ - Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); + Log.d(TAG, "ServiceDownload----network failure returnCode " + response.code()); // setDownloadFlag(true); // chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); - // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); - handler.sendEmptyMessage(msg); - return; + // Log.d( "ServiceDownload",String.format("ServiceDownload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); + // handler.sendEmptyMessage(msg); + handler.sendMessage(mg); + return; } try { @@ -322,7 +520,7 @@ public class ServiceDownload extends IntentService { final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 writer.write(buf); writer.close(); - Log.d( "ServiceDowload",String.format("ServiceDowload file created: %s", file.getPath())); + Log.d( "ServiceDownload",String.format("ServiceDownload file created: %s", file.getPath())); processingTask.setFinishedChpats(processingTask.getFinishedChpats()+1); processingTask.update(processingTask.getId()); Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); @@ -340,11 +538,16 @@ public class ServiceDownload extends IntentService { chapter.setChapterPath(fileChapterName(chapter)); chapter.update(chapter.getId()); - handler.sendEmptyMessage(msg); + if(! tasksMapDone.containsKey(taskID)){ + tasksMapDone.put(taskID,new ArrayList()); + } + tasksMapDone.get(taskID).add(chapter); + + handler.sendMessage(mg); //setDownloadFlag(true); // chaptDownStatus.put(index, BookUtil.DownloadStatus.success); - Log.d(TAG,String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() )); + Log.d(TAG,String.format("ServiceDownload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() )); } } @@ -370,10 +573,10 @@ public class ServiceDownload extends IntentService { return; } long startTime = new Date().getTime(); - Log.d(TAG, String.format("ServiceDowload----start download %s from %s", chapter.getChapterName(), url)); + Log.d(TAG, String.format("ServiceDownload----start download %s from %s", chapter.getChapterName(), url)); - // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); + // Log.d( "ServiceDownload",String.format("ServiceDownload isDownloadChapt: %s",isDownloadChapt)); JSONObject siteJson = new JSONObject(); siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); @@ -382,10 +585,10 @@ public class ServiceDownload extends IntentService { ResponseBody body = response.body(); if (body != null) { if (response.code() != 200) { - Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); + Log.d(TAG, "ServiceDownload----network failure returnCode " + response.code()); // setDownloadFlag(true); // chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); - // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); + // Log.d( "ServiceDownload",String.format("ServiceDownload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); handler.sendEmptyMessage(msg); return; } @@ -401,7 +604,7 @@ public class ServiceDownload extends IntentService { final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 writer.write(buf); writer.close(); - Log.d("ServiceDowload", String.format("ServiceDowload file created: %s", file.getPath())); + Log.d("ServiceDownload", String.format("ServiceDownload file created: %s", file.getPath())); processingTask.setFinishedChpats(processingTask.getFinishedChpats() + 1); processingTask.update(processingTask.getId()); Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); @@ -422,7 +625,7 @@ public class ServiceDownload extends IntentService { //setDownloadFlag(true); // chaptDownStatus.put(index, BookUtil.DownloadStatus.success); - Log.d(TAG, String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath())); + Log.d(TAG, String.format("ServiceDownload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath())); } diff --git a/zhuike/src/main/java/com/novelbook/android/service/ServiceDownloadIntent.java b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownloadIntent.java new file mode 100644 index 0000000..d64a61c --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/service/ServiceDownloadIntent.java @@ -0,0 +1,500 @@ +package com.novelbook.android.service; + +import android.app.IntentService; +import android.content.Intent; +import android.os.Handler; +import android.os.Message; +import android.text.TextUtils; +import android.util.Log; + +import com.novelbook.android.db.Chapter; +import com.novelbook.android.db.DownloadTask; +import com.novelbook.android.db.SiteRule; +import com.novelbook.android.netutils.HttpMethods; +import com.novelbook.android.utils.BookUtil; +import com.novelbook.android.utils.NovelParseUtil; + +import org.json.JSONException; +import org.json.JSONObject; +import org.litepal.LitePal; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + + +public class ServiceDownloadIntent extends IntentService { + private static final String TAG ="ServiceDownload" ; + + private final String storagePath = BookUtil.storagePath; + private final String cachedPath = BookUtil.cachedPath; + private final String chapterPath = BookUtil.chapterPath; + + public final String EXTR_TASKID ="taskId"; + public final String EXTR_OFFSET ="offset"; //多线程下载,每个线程取章节偏移数量 + + + + + // public ServiceDownload(String name) { + // super(name); + // } + public ServiceDownloadIntent() { + super("ServiceDownload"); + } + + private Map siteRuleMap = new HashMap() ; // key = novelId + private DownloadTask processingTask ; + private int taskIndex=0; + private int chaptIndex=0; + + private Map> tasksMap = new ConcurrentHashMap>();// key = taskId + + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG,"test service onCreate..."); + + /* + downloadTasks =LitePal.where("status = ?","0").find(DownloadTask.class); + for(DownloadTask dt :downloadTasks){ + List chps =Chapter.getUnCachedChapters(dt.getNovelId(),dt.getDomain()); + if(chps.size()>0) { + SiteRule sr = SiteRule.getSiteRuleByDomain(dt.getDomain()); + siteRuleMap.put(dt.getNovelId(), sr); + tasksMap.put(dt.getId(), chps); + } + } + + for(DownloadTask tmp: downloadTasks){ + Log.d(TAG, String.format("test service task list : %s",tmp.getId())); + } + */ + + + } + @Override + public void onStart(Intent intent, int startId) { + super.onStart(intent, startId); + Log.d(TAG,"test service onStart"); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG,"test service onStartCommand"); + return super.onStartCommand(intent, flags, startId); + + } + + @Override + public void onDestroy() { + Log.d(TAG,"test service onDestroy"); + super.onDestroy(); + } + + + + private List downloadTasks = new ArrayList(); + + int cancelId =0; + @Override + protected void onHandleIntent( Intent intent) { + Log.d(TAG,"test service onHandleIntent...begin"); + + String key ="taskId"; + int taskId =0; + + if(intent.hasExtra(key)){ + taskId= intent.getExtras().getInt(key); + DownloadTask dt = LitePal.find(DownloadTask.class,taskId); + + if(intent.hasExtra("start")){ + if(!intent.getBooleanExtra("start",true)){ + cancelId = taskId; + stopTask(taskId); + }else{ + startNewTask(dt); + } + } + + + } + else{ + if(downloadTasks.size()==0) { + List tmp = LitePal.findAll(DownloadTask.class); + taskIndex=0; + for(DownloadTask dt :tmp) { + startNewTask(dt); + } + + + } + + + /* + if(processingTask==null) { + startTask(); + }*/ + } + Log.d(TAG,"test service onHandleIntent...over"); + } + + private void stopTask(int taskId) { + for(DownloadTask dt : downloadTasks){ + if(dt.getId() == taskId){ + dt.setDownSatus(DownloadTask.DownStatus.等待下载); + } + } + + startTask(); + } + + Handler handler = new Handler() { + @Override + public void handleMessage(Message msg) { + if(msg.what ==1){ + startTask(); + }else if(msg.what==2){ + + if( downloadTasks.get(taskIndex).getDownSatus() == DownloadTask.DownStatus.等待下载){ + return; + } + if(tasksMap.get(processingTask.getId())==null){ + return; + } + Log.d(TAG,String.format("%s start new chapt download---- taskId :%s, chapter count %s,chaptIndex %s",TAG + , processingTask.getId(), + tasksMap.get(processingTask.getId()).size(),chaptIndex )); + + + Intent broadcastIntent = new Intent(); + broadcastIntent.setAction("ServiceDownload.ChapterContent.finished"); + broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); + broadcastIntent.putExtra("progress", processingTask.getFinishedChpats()); + broadcastIntent.putExtra("novelId", processingTask.getNovelId()); + broadcastIntent.putExtra("taskId", processingTask.getId()); + sendBroadcast(broadcastIntent); + + + if( tasksMap.get(processingTask.getId()).size()-1 > chaptIndex){ + + chaptIndex++; + + }else{ + Log.d(TAG,String.format("%s task done ---- taskId :%s, chapter count %s,chaptIndex %s",TAG , processingTask.getId(), + tasksMap.get(processingTask.getId()).size(),chaptIndex )); + //章节全部处理完毕了 + processingTask.setStatus(1); + processingTask.update(processingTask.getId()); + + tasksMap.remove(processingTask.getId()); //会不会线程冲突? + + startTask(); + } + + doDownloadContent(); + } + + } + + }; + + + + private void startTask() { + + if(processingTask!=null) { + processingTask.update(processingTask.getId()); + } + + + + if(downloadTasks.size() <=taskIndex){ + processingTask =null; + Log.d(TAG,"No task to download."); + return; + } + + processingTask = downloadTasks.get(taskIndex); + if(processingTask.getDownSatus()== DownloadTask.DownStatus.等待下载){ + taskIndex++; + startTask(); + return; + } + processingTask.setDownSatus(DownloadTask.DownStatus.正在下载); + chaptIndex=0; + doDownloadContent(); + if(taskIndex < downloadTasks.size()-1){ + taskIndex++; + } + + } + + + void doDownloadContent(){ + + Log.d(TAG, String.format("ServiceDowload--- taskId: %s ",processingTask.getId())); + List chps = tasksMap.get(processingTask.getId()); + if(chps!=null && chps.size()>0) { + Chapter chapter = chps.get(chaptIndex); + + if (TextUtils.isEmpty(chapter.getChapterPath())) { + try { + ServiceDownload(chapter); + } catch (JSONException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + // } catch (IOException e) { + // e.printStackTrace(); + } + + } else { + handler.sendEmptyMessage(2); + } + }else{ + handler.sendEmptyMessage(2); + } + } + + void startNewTask(DownloadTask dt){ + + + + if(dt!=null){ + List chps = Chapter.getUnCachedChapters(dt.getId() ); + if(chps==null || chps.size()==0){ + return; + } + SiteRule siteRule = SiteRule. getSiteRuleByDomain(dt.getDomain()); + if(siteRule==null){ + //to do get siterule from web + Log.d(TAG, String.format("没找到site rule: %s",dt.getDomain())); + }else { + siteRuleMap.put(dt.getNovelId(),siteRule); + + downloadTasks.add(dt); + + for(DownloadTask tmp: downloadTasks){ + Log.d(TAG, String.format("test service task list : %s",tmp.getId())); + } + + + tasksMap.put(dt.getId(), chps); + if(taskIndex==0) { + startTask(); + // handler.sendEmptyMessage(1); + } + } + } + /* + new Thread() { + + @Override + public void run() { + + + + } + }.start(); + + */ + } + private void ServiceDownload( Chapter chapter ) throws JSONException, InterruptedException { + + int msg =2; + + String url = chapter.getChapterUrl(); + if( TextUtils.isEmpty( url)){ + handler.sendEmptyMessage(msg); + return ; + } + long startTime= new Date().getTime(); + Log.d(TAG,String.format("ServiceDowload----start download %s from %s", chapter.getChapterName() ,url )); + + + + // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); + JSONObject siteJson = new JSONObject(); + siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); + siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); + Request request = getTagRequest(url); + HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + + handler.sendEmptyMessage(msg); + + // Log.d( "ServiceDowload",String.format("ServiceDowload fail, isDownloadChapt: %s",isDownloadChapt)); + e.printStackTrace(); + // throw new RuntimeException("Error during writing " + fileChapterName( index)); + } + + @Override + public void onResponse(Call call, Response response){ + ResponseBody body = response.body(); + if (body != null ) { + if(response.code()!=200){ + Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); + // setDownloadFlag(true); + // chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); + // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); + handler.sendEmptyMessage(msg); + return; + } + + try { + String bodyStr = body.string(); + String title = chapter.getChapterName(); + String chapterContent = title+ "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); + char[] buf = chapterContent.toCharArray(); + File file = new File(fileChapterName(chapter)); + file.createNewFile(); + + final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 + writer.write(buf); + writer.close(); + Log.d( "ServiceDowload",String.format("ServiceDowload file created: %s", file.getPath())); + processingTask.setFinishedChpats(processingTask.getFinishedChpats()+1); + processingTask.update(processingTask.getId()); + Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); + // setDownloadFlag(true); + } catch (IOException | JSONException | InterruptedException e) { + e.printStackTrace(); + // throw new RuntimeException("Error during writing " + fileChapterName( index)); + } + finally { + body.close(); + + + // setDownloadFlag(true); + } + + chapter.setChapterPath(fileChapterName(chapter)); + chapter.update(chapter.getId()); + handler.sendEmptyMessage(msg); + + //setDownloadFlag(true); + // chaptDownStatus.put(index, BookUtil.DownloadStatus.success); + Log.d(TAG,String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() -startTime ,chapter.getChapterPath() )); + + } + } + }); + + + } + + /** + * 直接 + * @param chapter + * @throws JSONException + * @throws InterruptedException + + + private void ServiceDownload2( Chapter chapter ) throws IOException, JSONException, InterruptedException { + + int msg = 2; + + String url = chapter.getChapterUrl(); + if (TextUtils.isEmpty(url)) { + handler.sendEmptyMessage(msg); + return; + } + long startTime = new Date().getTime(); + Log.d(TAG, String.format("ServiceDowload----start download %s from %s", chapter.getChapterName(), url)); + + + // Log.d( "ServiceDowload",String.format("ServiceDowload isDownloadChapt: %s",isDownloadChapt)); + JSONObject siteJson = new JSONObject(); + siteJson.put("chapterContentRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentRegex()); + siteJson.put("chapterContentDumpRegex", siteRuleMap.get(chapter.getNovelId()).getChapterContentDumpRegex()); + Request request = getTagRequest(url); + Response response = HttpMethods.getOkClient().newCall(request).execute(); + ResponseBody body = response.body(); + if (body != null) { + if (response.code() != 200) { + Log.d(TAG, "ServiceDowload----network failure returnCode " + response.code()); + // setDownloadFlag(true); + // chaptDownStatus.put(index, BookUtil.DownloadStatus.failure); + // Log.d( "ServiceDowload",String.format("ServiceDowload error %s ,isDownloadChapt: %s", response.code(),isDownloadChapt)); + handler.sendEmptyMessage(msg); + return; + } + + try { + String bodyStr = body.string(); + String title = chapter.getChapterName(); + String chapterContent = title + "\n" + NovelParseUtil.getChapterContent(bodyStr, siteJson); + char[] buf = chapterContent.toCharArray(); + File file = new File(fileChapterName(chapter)); + file.createNewFile(); + + final OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(fileChapterName(chapter)), "utf-8");//"UTF-16LE"); // UTF-16LE 比 utf-8 文件小 + writer.write(buf); + writer.close(); + Log.d("ServiceDowload", String.format("ServiceDowload file created: %s", file.getPath())); + processingTask.setFinishedChpats(processingTask.getFinishedChpats() + 1); + processingTask.update(processingTask.getId()); + Thread.sleep(siteRuleMap.get(chapter.getNovelId()).getMiniInterval4AccessChapter()); + // setDownloadFlag(true); + } catch (IOException | JSONException | InterruptedException e) { + e.printStackTrace(); + // throw new RuntimeException("Error during writing " + fileChapterName( index)); + } finally { + body.close(); + + + // setDownloadFlag(true); + } + + chapter.setChapterPath(fileChapterName(chapter)); + chapter.update(chapter.getId()); + handler.sendEmptyMessage(msg); + + //setDownloadFlag(true); + // chaptDownStatus.put(index, BookUtil.DownloadStatus.success); + Log.d(TAG, String.format("ServiceDowload---- finished download %s, cost time %s ,content path %s ", chapter.getChapterName(), new Date().getTime() - startTime, chapter.getChapterPath())); + + } + + + } +*/ + + protected String fileChapterName(Chapter chapter ) { + return getChapterPath(chapter.getNovelId()) +chapter.getDomain()+"/"+ chapter.getIndex() ; + + } + String getChapterPath(int novelId){ + File file = new File(chapterPath +novelId); + if(!file.exists()){ + file.mkdir(); + } + return chapterPath +novelId+"/"; + } + + private Request getTagRequest(String url) { + return new Request.Builder() + .tag(processingTask.getNovelId()) //标记 + .url(url) + // .header("User-Agent", "OkHttp Example") + .build(); + } + + + +} diff --git a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java index b1361a5..832c946 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/BookUtil.java @@ -248,6 +248,7 @@ public class BookUtil { file.mkdir(); } mNovel.setDomain(mSite.getDomain()); + mNovel.setDomainName(mSite.getName()); mNovel.setMuluUrl(mSite.getMuluUrl()); mNovel.update(mNovel.getId()); } @@ -818,7 +819,7 @@ int muluRetryCount =0; if (!st.getDomain().equals(mSite.getDomain())) { //mSite = st; mNovel.setDomain(st.getDomain()); - + mNovel.setDomainName(mSite.getName()); bundleData.putString("siteName", st.getName()); msg.setData(bundleData); break; diff --git a/zhuike/src/main/res/layout/activitycache.xml b/zhuike/src/main/res/layout/activitycache.xml new file mode 100644 index 0000000..55aa51d --- /dev/null +++ b/zhuike/src/main/res/layout/activitycache.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml b/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml index f35dc6a..e63142c 100644 --- a/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml +++ b/zhuike/src/main/res/layout/fragment_shelf_botoomsheetdialog.xml @@ -17,36 +17,37 @@ tools:ignore="UnusedAttribute"> + android:paddingStart="105dp" + android:paddingLeft="120dp"> + android:orientation="vertical" + android:paddingStart="15dp" + android:paddingRight="10dp" + android:paddingTop="5dp"> @@ -54,21 +55,21 @@ android:id="@+id/tvAuthor" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="visible" android:text="金庸" + android:visibility="visible" tools:ignore="HardcodedText" /> + /> + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zhuike/src/main/res/mipmap-mdpi/line_height_add.png b/zhuike/src/main/res/mipmap-mdpi/line_height_add.png new file mode 100644 index 0000000..68e907a Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/line_height_add.png differ diff --git a/zhuike/src/main/res/mipmap-mdpi/line_height_lessen.png b/zhuike/src/main/res/mipmap-mdpi/line_height_lessen.png new file mode 100644 index 0000000..4d181f8 Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/line_height_lessen.png differ diff --git a/zhuike/src/main/res/mipmap-mdpi/pause.png b/zhuike/src/main/res/mipmap-mdpi/pause.png new file mode 100644 index 0000000..46ddfc7 Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/pause.png differ diff --git a/zhuike/src/main/res/mipmap-mdpi/play.png b/zhuike/src/main/res/mipmap-mdpi/play.png new file mode 100644 index 0000000..bab6989 Binary files /dev/null and b/zhuike/src/main/res/mipmap-mdpi/play.png differ