項目目錄結構圖:
目錄:
1. 項目 build.gradle---查看項目主要涉及到哪些第三方庫
2. 將Html文本轉換成能正常顯示的
3. 啓動定時服務
一、項目 build.gradle—查看項目主要涉及到哪些第三方庫
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'org.jsoup:jsoup:1.9.2'
compile 'com.android.support:cardview-v7:24.0.0'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
// MaterialDesignDialog
compile 'com.lb:materialdesigndialog:1.0.1'
// lb封裝的工具庫
compile 'com.lb:utils:1.0.2'
// nohttp 網絡請求框架
compile 'com.yolanda.nohttp:nohttp:1.0.0'
// 點贊
compile 'com.sackcentury:shinebutton:0.1.2'
}
二、將Html文本轉換成能正常顯示的Text
String desc = Html.fromHtml(englishBean.getDesc()).toString();
三、啓動定時服務
1. 清單文件註冊:
// 註冊service
<service android:name=".service.TimingTaskService" />
// 靜態註冊接收器
<receiver
android:name=".receiver.TimingTaskReceiver"
android:exported="true">
<intent-filter android:priority="999">
<action android:name="com.lb.wecharenglish.getRemoteData" />
</intent-filter>
</receiver>
2、在MainActivity 中啓動服務:
Intent service = new Intent(mContext, TimingTaskService.class);
startService(service);
3、定時任務 TimingTaskService:
* 類描述:後臺定時任務,每隔一段時間請求網絡數據<br>
*/
public class TimingTaskService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
timingTask(this);
return super.onStartCommand(intent, flags, startId);
}
private void timingTask(Context context) {
Intent intent = new Intent(getPackageName() + ".getRemoteData");
PendingIntent sender = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
// Schedule the alarm!
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 間隔時間
int interval = 1000 * 60 * 60 * 4; // 4h
// setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
interval, sender);
}
}
// 關於系統服務提醒器 http://blog.csdn.net/wangxingwu_314/article/details/8060312
4、接收器開一個工作線程執行耗時網絡操作
public class TimingTaskReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
LogUtil.e(this, "接收到廣播");
String action = intent.getAction();
if ((context.getPackageName() + ".getRemoteData").equals(action)) {
new Thread() {
@Override
public void run() {
// 獲取遠端數據
List<EnglishBean> remoteDatas = new EnglishServer().getDataFromRemote();
// 遍歷並添加到數據庫
for (EnglishBean bean : remoteDatas) {
// 查詢數據庫是否包含該條數據
EnglishBean dbBean = new EnglishServer().findById(context, bean.getId());
if (null == dbBean) {
// 需要發出狀態欄通知
LogUtil.e(this, "顯示通知");
showNewNotification(context);
}
// 添加進數據庫操作
new EnglishServer().add(context, bean);
}
}
}.start();
} else {
LogUtil.e(this, "action 不一致");
LogUtil.e(this, "action=" + action);
}
}
/**
* 狀態欄顯示一條新通知
* @param context 上下文對象
*/
private void showNewNotification(Context context, int id, EnglishBean bean) {
// 使用通知推送消息
Notification.Builder builder = new Notification.Builder(context);
// 設置消息屬性
// 必須設置的屬性:小圖標 標題 內容
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle(bean.getTitle());
// noinspection deprecation
builder.setContentText(Html.fromHtml(bean.getDesc()));
//創建一個通知對象
Notification notification = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
notification = builder.build();
}
// 使用通知管理器發送一條通知
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(id, notification);
}
}
四、加載圖片相關配置
//設置啓動圖片,使用ImageLoader 防止內存溢出
ImageLoader.getInstance().displayImage("drawable://" + R.drawable.splash_pic,
iv_splash_pic, ImageLoaderOptions.fadein_options);
//延遲3秒進入主頁面
mHandler.sendEmptyMessageDelayed(ENTER_HOME, 3 * 1000);
/**
* 顯示圖片的所有配置
* @return
*/
private DisplayImageOptions getWholeOptions() {
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.loading) //設置圖片在下載期間顯示的圖片
.showImageForEmptyUri(R.drawable.ic_launcher)//設置圖片Uri爲空或是錯誤的時候顯示的圖片
.showImageOnFail(R.drawable.error) //設置圖片加載/解碼過程中錯誤時候顯示的圖片
.cacheInMemory(true)//設置下載的圖片是否緩存在內存中
.cacheOnDisk(true)//設置下載的圖片是否緩存在SD卡中
.considerExifParams(true) //是否考慮JPEG圖像EXIF參數(旋轉,翻轉)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)//設置圖片以如何的編碼方式顯示
.bitmapConfig(Bitmap.Config.RGB_565)//設置圖片的解碼類型
//.decodingOptions(BitmapFactory.Options decodingOptions)//設置圖片的解碼配置
.delayBeforeLoading(0)//int delayInMillis爲你設置的下載前的延遲時間
//設置圖片加入緩存前,對bitmap進行設置
//.preProcessor(BitmapProcessor preProcessor)
.resetViewBeforeLoading(true)//設置圖片在下載前是否重置,復位
.displayer(new RoundedBitmapDisplayer(20))//不推薦用!!!!是否設置爲圓角,弧度爲多少
.displayer(new FadeInBitmapDisplayer(100))//是否圖片加載好後漸入的動畫時間,可能會出現閃動
.build();//構建完成
return options;
}
//圖片加載方式
displayer(BitmapDisplayer displayer) // 設置圖片的顯示方式,如:
.displayer(new FadeInBitmapDisplayer(100))
其中,displayer的選擇值:
RoundedBitmapDisplayer(int roundPixels)設置圓角圖片,不推薦!!!
FakeBitmapDisplayer()這個類什麼都沒做
FadeInBitmapDisplayer(int durationMillis)設置圖片漸顯的時間
SimpleBitmapDisplayer()正常顯示一張圖片
//圖片加載時監聽
imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted() {
//開始加載的時候執行 }
@Override
public void onLoadingFailed(FailReason failReason) {
//加載失敗的時候執行 }
@Override
public void onLoadingComplete(Bitmap loadedImage) {
//加載成功的時候執行 }
@Override
public void onLoadingCancelled() {
//加載取消的時候執行
}});
//避免內存泄漏
@Override
protected void onDestroy() {
mHandler.removeCallbacksAndMessages(null);
super.onDestroy();
}
五、設置apk 生成方式
applicationVariants.all { variant ->
variant.outputs.each { output ->
def oldFile = output.outputFile
// edian_channel_01_v1.1.6_360手機助手
//1.創建 edian_v
def firstName = "everyday_v";
//3.獲取清單文件中的版本號
def versionName = versionName;
//4.根基標示渠道號填寫對應的渠道商店
//5.構建類型 是否是debug等
def buildType = "";
if (variant.buildType.name.equals('release')) {
buildType = "release_";
} else if (variant.buildType.name.equals('debug')) {
buildType = "debug_";
}
def releaseApkName = buildType + firstName + versionName + '.apk'
// + "_" + getDate()
output.outputFile = new File(oldFile.parent as File, releaseApkName)
}
}
六、播放網絡音頻
final MediaPlayer player = new MediaPlayer();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
player.start();
}
});
try {
player.setDataSource("https://mp.weixin.qq.com/cgi-bin/readtemplate?t=tmpl/audio_tmpl&name=132&play_length=04:31");
} catch (Exception e) {
e.printStackTrace();
}
player.prepareAsync();
七、使用noHttp 網絡框架建立下載任務
private DownloadRequest downloadRequest;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case START_DOWNLOAD:
pb_setting_synchronousing.setVisibility(View.VISIBLE);
break;
case DOWNLOAD_FINISH:
pb_setting_synchronousing.setVisibility(View.GONE);
break;
}
}
};
downloadRequest = NoHttp.createDownloadRequest(url, filePath, fileName, true, false);
// what 區分下載
// downloadRequest 下載請求對象
// downloadListener 下載監聽
NoHttp.newDownloadQueue(2).add(0, downloadRequest, new DownloadListener() {
@Override
public void onDownloadError(int what, Exception exception) {
LogUtil.log(this, exception);
mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
ToastUtil.showShortToast(mContext, "同步遠程數據庫失敗,請重試");
}
@Override
public void onStart(int what, boolean isResume, long rangeSize, Headers responseHeaders, long allCount) {
LogUtil.log(this, "開始下載");
mHandler.sendEmptyMessage(START_DOWNLOAD);
}
@Override
public void onProgress(int what, int progress, long fileCount) {
// 更新下載進度
}
@Override
public void onFinish(int what, String filePath) {
//下載完成,打開數據庫
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(filePath, null);
final int count = new EnglishServer().copyDataFromDatabas(mContext, db);
db.close();
//刪除已經下載的數據
File file = new File(filePath);
//noinspection ResultOfMethodCallIgnored
file.delete();
ToastUtil.showShortToast(mContext, "更新了" + count + "條數據");
mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
}
@Override
public void onCancel(int what) {
LogUtil.log(this, "下載取消");
pb_setting_synchronousing.setVisibility(View.GONE);
}
});
感謝作者的分享。項目地址:https://github.com/291700351/WeCharEnglish