private void resetTheTime() { Logger.v(TAG, "reset unread block"); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); // 指定时间 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.SECOND, AppSettings.getUnreadInterval()); Logger.v(TAG, String.format("未读消息,在%s后还是读取", AppSettings.getUnreadInterval())); am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), getOperation()); }
@Override public void onDestroy() { super.onDestroy(); Logger.v(TAG, "服务停止"); if (unreadTask != null) unreadTask.cancel(true); }
private void trimToSize() throws IOException { while (size > maxSize) { // Map.Entry<String, Entry> toEvict = lruEntries.eldest(); final Map.Entry<String, Entry> toEvict = lruEntries.entrySet().iterator().next(); Logger.d( BitmapLoader.class.getSimpleName(), "清理缓存文件size=" + size + ",maxSize=" + maxSize + ",file=" + toEvict.getKey()); remove(toEvict.getKey()); } }
private synchronized void completeEdit(Editor editor, boolean success) throws IOException { Entry entry = editor.entry; if (entry.currentEditor != editor) { throw new IllegalStateException(); } // if this edit is creating the entry for the first time, every index // must have a value if (success && !entry.readable) { for (int i = 0; i < valueCount; i++) { if (!entry.getDirtyFile(i).exists()) { editor.abort(); throw new IllegalStateException("edit didn't create file " + i); } } } for (int i = 0; i < valueCount; i++) { File dirty = entry.getDirtyFile(i); if (success) { if (dirty.exists()) { File clean = entry.getCleanFile(i); dirty.renameTo(clean); long oldLength = entry.lengths[i]; long newLength = clean.length(); entry.lengths[i] = newLength; size = size - oldLength + newLength; } } else { Logger.d(BitmapLoader.class.getSimpleName(), "completeEdit"); deleteIfExists(dirty); } } redundantOpCount++; entry.currentEditor = null; if (entry.readable | success) { entry.readable = true; journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); if (success) { entry.sequenceNumber = nextSequenceNumber++; } } else { lruEntries.remove(entry.key); journalWriter.write(REMOVE + ' ' + entry.key + '\n'); } if (size > maxSize || journalRebuildRequired()) { executorService.submit(cleanupCallable); } }
/** * 点赞 * * @param statusId * @param like * @param cookie * @return * @throws TaskException */ public LikeResultBean doLike(String statusId, boolean like, String cookie) throws TaskException { try { String url = like ? "http://m.weibo.cn/attitudesDeal/add" : "http://m.weibo.cn/attitudesDeal/delete"; Map<String, String> cookieMap = new HashMap<String, String>(); String[] cookieValues = cookie.split(";"); for (String cookieValue : cookieValues) { String key = cookieValue.split("=")[0]; String value = cookieValue.split("=")[1]; cookieMap.put(key, value); } // Logger.d(WeiboClientActivity.TAG, cookieMap); Connection connection = Jsoup.connect(url); connection .userAgent( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:33.0) Gecko/20100101 Firefox/33.0") .referrer("http://m.weibo.cn/") .cookies(cookieMap) .data("id", statusId) .method(Connection.Method.POST); if (like) connection.data("attitude", "heart"); String body = connection.execute().body(); if (!TextUtils.isEmpty(body)) { Logger.d(TAG, body); if (body.indexOf("http://passport.weibo.cn/sso/crossdomain") != -1) throw new TaskException("-100", "未登录"); else if (body.indexOf("<html") != -1) throw new TaskException("-100", "未登录"); LikeResultBean likeBean = JSON.parseObject(body, LikeResultBean.class); if (likeBean.getOk() == 1) { return likeBean; } else if (likeBean.getOk() == -100) { throw new TaskException("-100", "未登录"); } else { throw new TaskException("", likeBean.getMsg()); } } } catch (Exception e) { if (e instanceof TaskException) throw (TaskException) e; e.printStackTrace(); } throw new TaskException(TaskException.TaskError.timeout.toString()); }
@Override protected void onSuccess(WeiBoUser result) { super.onSuccess(result); Logger.d(TAG, "授权成功"); BaiduAnalyzeUtils.onEvent("add_account", "添加授权账号"); showMessage(R.string.account_auth_success); if (getActivity() != null) { getActivity().finish(); } }
private static void deleteIfExists(File file) throws IOException { // try { // Libcore.os.remove(file.getPath()); // } catch (ErrnoException errnoException) { // if (errnoException.errno != OsConstants.ENOENT) { // throw errnoException.rethrowAsIOException(); // } // } Logger.d(BitmapLoader.class.getSimpleName(), "deleteIfExists file = " + file.getName()); // FIXME 把删除文件的操作注释掉了 // if (file.exists() && !file.delete()) { // throw new IOException(); // } }
@Override public TokenInfo workInBackground(AccountBean... params) throws TaskException { Logger.w("run CheckAccountValidTask"); TokenInfo token = null; TokenInfo adToken = null; try { AccountBean account = params[0]; // Aisen授权 try { token = SinaSDK.getInstance(account.getAccessToken()) .getTokenInfo(account.getAccessToken().getToken()); } catch (TaskException e) { e.printStackTrace(); if ("21327".equals(e.getCode()) || "21317".equals(e.getCode())) { token = new TokenInfo(); token.setExpire_in(0); } } if (token != null) account.getAccessToken().setExpires_in(token.getExpire_in()); // Weico授权 try { if (account.getAdvancedToken() != null) adToken = SinaSDK.getInstance(account.getAdvancedToken()) .getTokenInfo(account.getAdvancedToken().getToken()); else { adToken = new TokenInfo(); adToken.setExpire_in(0); } } catch (TaskException e) { e.printStackTrace(); if ("21327".equals(e.getCode()) || "21317".equals(e.getCode())) { adToken = new TokenInfo(); adToken.setExpire_in(0); } } if (account.getAdvancedToken() != null && adToken != null) account.getAdvancedToken().setExpires_in(adToken.getExpire_in()); } catch (Throwable e) { } if (token != null) { token.setUid(params[0].getUid()); } return token; }
// TODO: this should specify paths as Strings rather than as Files public static void deleteContents(File dir) throws IOException { File[] files = dir.listFiles(); if (files == null) { throw new IllegalArgumentException("not a directory: " + dir); } for (File file : files) { if (file.isDirectory()) { deleteContents(file); } if (!file.delete()) { throw new IOException("failed to delete file: " + file); } Logger.d(BitmapLoader.class.getSimpleName(), "deleteContents file = " + file.getName()); } }
private void readJournal() throws IOException { InputStream in = new BufferedInputStream(new FileInputStream(journalFile), IO_BUFFER_SIZE); try { String magic = readAsciiLine(in); String version = readAsciiLine(in); String appVersionString = readAsciiLine(in); String valueCountString = readAsciiLine(in); String blank = readAsciiLine(in); if (!MAGIC.equals(magic) || !VERSION_1.equals(version) || !Integer.toString(appVersion).equals(appVersionString) || !Integer.toString(valueCount).equals(valueCountString) || !"".equals(blank)) { Logger.d( BitmapLoader.TAG, "unexpected journal header: [" + magic + ", " + version + ", " + valueCountString + ", " + blank + "]"); throw new IOException( "unexpected journal header: [" + magic + ", " + version + ", " + valueCountString + ", " + blank + "]"); } while (true) { try { readJournalLine(readAsciiLine(in)); } catch (EOFException endOfJournal) { endOfJournal.printStackTrace(); break; } } } finally { closeQuietly(in); } }
/** * Computes the initial size and collects garbage as a part of opening the cache. Dirty entries * are assumed to be inconsistent and will be deleted. */ private void processJournal() throws IOException { deleteIfExists(journalFileTmp); for (Iterator<Entry> i = lruEntries.values().iterator(); i.hasNext(); ) { Entry entry = i.next(); if (entry.currentEditor == null) { for (int t = 0; t < valueCount; t++) { size += entry.lengths[t]; Logger.d(BitmapLoader.class.getSimpleName(), entry.getCleanFile(0).getName()); } } else { entry.currentEditor = null; for (int t = 0; t < valueCount; t++) { deleteIfExists(entry.getCleanFile(t)); deleteIfExists(entry.getDirtyFile(t)); } i.remove(); } } }
/** * 触发一次离线,如果没有设置过离线分组,优先设置后再离线 * * @param context */ public static void toggleOffline(final Activity context) { if (!AppContext.isLogedin()) return; List<Group> groups = SinaDB.getOfflineSqlite() .select(new Extra(AppContext.getUser().getIdstr(), null), Group.class); if (groups.size() == 0) { Logger.d(TAG, "离线分组未设置过"); new AlertDialogWrapper.Builder(context) .setMessage(R.string.offline_none_groups_remind) .setNegativeButton(R.string.cancel, null) .setPositiveButton( R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { showOfflineGroupsModifyDialog( context, new ArrayList<Group>(), new OnOfflineGroupSetCallback() { @Override public void onChanged(List<Group> newGroups) { // 设置离线分组 Logger.d(TAG, "设置离线分组%d个", newGroups.size()); if (newGroups.size() > 0) { SinaDB.getOfflineSqlite().insert(getLoggedExtra(null), newGroups); toggleOffline(context); } } }, R.string.offline_groups_dialog); } }) .show(); } else { OfflineService.startOffline((ArrayList) groups); } }
/** * Opens the cache in {@code directory}, creating a cache if none exists there. * * @param directory a writable directory * @param appVersion * @param valueCount the number of values per cache entry. Must be positive. * @param maxSize the maximum number of bytes this cache should use to store * @throws IOException if reading or writing the cache directory fails */ public static LruDiskCache open(File directory, int appVersion, int valueCount, long maxSize) throws IOException { if (maxSize <= 0) { throw new IllegalArgumentException("maxSize <= 0"); } if (valueCount <= 0) { throw new IllegalArgumentException("valueCount <= 0"); } // prefer to pick up where we left off LruDiskCache cache = new LruDiskCache(directory, appVersion, valueCount, maxSize); if (cache.journalFile.exists()) { Logger.d(BitmapLoader.TAG, "journalFile exists"); try { cache.readJournal(); cache.refreshJournal(); cache.processJournal(); cache.journalWriter = new BufferedWriter(new FileWriter(cache.journalFile, true), IO_BUFFER_SIZE); return cache; } catch (IOException journalIsCorrupt) { journalIsCorrupt.printStackTrace(); // System.logW("DiskLruCache " + directory + " is corrupt: " // + journalIsCorrupt.getMessage() + ", removing"); // cache.delete(); cache.journalFile.delete(); } } // create a new empty cache directory.mkdirs(); cache = new LruDiskCache(directory, appVersion, valueCount, maxSize); cache.rebuildJournal(); cache.readJournal(); cache.refreshJournal(); cache.processJournal(); return cache; }
@Override public int onStartCommand(Intent intent, int flags, int startId) { if (unreadCountNotifier == null) unreadCountNotifier = new UnreadCountNotifier(this); if (!AppContext.isLogedin()) { stopSelf(); return super.onStartCommand(intent, flags, startId); } String action = intent != null ? intent.getAction() : ""; if (ACTION_GET.equals(action)) { resetTheTime(); new UnreadTask().execute(); } else if (ACTION_UPDATE.equals(action)) { Logger.v(TAG, "刷新时间"); resetTheTime(); } return super.onStartCommand(intent, flags, startId); }
UnreadTask() { if (unreadTask != null) unreadTask.cancel(true); unreadTask = this; Logger.v(TAG, "execute UnreadTask"); }
public static File getUploadFile(File source) { if (source.getName().toLowerCase().endsWith(".gif")) { Logger.w("上传图片是GIF图片,上传原图"); return source; } File file = null; String imagePath = GlobalContext.getInstance().getAppPath() + SettingUtility.getStringSetting("draft") + File.separator; int sample = 1; int maxSize = 0; int type = AppSettings.getUploadSetting(); // 自动,WIFI时原图,移动网络时高 if (type == 0) { if (SystemUtils.getNetworkType() == SystemUtils.NetWorkType.wifi) type = 1; else type = 2; } BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(source.getAbsolutePath(), opts); switch (type) { // 原图 case 1: Logger.w("原图上传"); file = source; break; // 高 case 2: sample = BitmapDecoder.calculateInSampleSize(opts, 1920, 1080); Logger.w("高质量上传"); maxSize = 700 * 1024; imagePath = imagePath + "高" + File.separator + source.getName(); file = new File(imagePath); break; // 中 case 3: Logger.w("中质量上传"); sample = BitmapDecoder.calculateInSampleSize(opts, 1280, 720); maxSize = 300 * 1024; imagePath = imagePath + "中" + File.separator + source.getName(); file = new File(imagePath); break; // 低 case 4: Logger.w("低质量上传"); sample = BitmapDecoder.calculateInSampleSize(opts, 1280, 720); maxSize = 100 * 1024; imagePath = imagePath + "低" + File.separator + source.getName(); file = new File(imagePath); break; default: break; } // 压缩图片 if (type != 1 && !file.exists()) { Logger.w(String.format("压缩图片,原图片 path = %s", source.getAbsolutePath())); byte[] imageBytes = FileUtils.readFileToBytes(source); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { out.write(imageBytes); } catch (Exception e) { } Logger.w(String.format("原图片大小%sK", String.valueOf(imageBytes.length / 1024))); if (imageBytes.length > maxSize) { // 尺寸做压缩 BitmapFactory.Options options = new BitmapFactory.Options(); if (sample > 1) { options.inSampleSize = sample; Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options); Logger.w(String.format("压缩图片至大小:%d*%d", bitmap.getWidth(), bitmap.getHeight())); out.reset(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); imageBytes = out.toByteArray(); } options.inSampleSize = 1; if (imageBytes.length > maxSize) { BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options); Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options); int quality = 90; out.reset(); Logger.w(String.format("压缩图片至原来的百分之%d大小", quality)); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out); while (out.toByteArray().length > maxSize) { out.reset(); quality -= 10; Logger.w(String.format("压缩图片至原来的百分之%d大小", quality)); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out); } } } try { if (!file.getParentFile().exists()) file.getParentFile().mkdirs(); Logger.w(String.format("最终图片大小%sK", String.valueOf(out.toByteArray().length / 1024))); FileOutputStream fo = new FileOutputStream(file); fo.write(out.toByteArray()); fo.flush(); fo.close(); } catch (Exception e) { e.printStackTrace(); } } return file; }
@Override public byte[] downloadBitmap(String url, ImageConfig config) throws Exception { try { File imgFile = new File(url); if (imgFile.exists()) { DownloadProcess process = config.getProgress(); if (process != null) process.prepareDownload(url); // 如果图片需要压缩,直接解析成bitmap if (config.getMaxHeight() > 0 || config.getMaxWidth() > 0) { Bitmap bitmap = BitmapDecoder.decodeSampledBitmapFromFile( imgFile.getAbsolutePath(), config.getMaxWidth(), config.getMaxHeight()); ByteArrayOutputStream out = new ByteArrayOutputStream(); boolean isPng = url.toLowerCase().endsWith("png") ? true : false; bitmap.compress(isPng ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG, 100, out); byte[] result = out.toByteArray(); out.close(); if (process != null) { process.sendLength(result.length); process.sendProgress(result.length); process.sendFinishedDownload(result); } Logger.w("直接解析sd卡图片,压缩尺寸"); return result; } else { InputStream in = new FileInputStream(new File(url)); if (process != null) process.sendLength(in.available()); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[8 * 1024]; int length = -1; long readBytes = 0; while ((length = in.read(buffer)) != -1) { readBytes += length; if (process != null) process.sendProgress(readBytes); out.write(buffer, 0, length); } out.flush(); byte[] result = out.toByteArray(); in.close(); out.close(); if (process != null) process.sendFinishedDownload(result); return result; } } if (config.getProgress() != null) config.getProgress().downloadFailed(null); throw new Exception(""); } catch (Exception e) { if (config.getProgress() != null) config.getProgress().sendException(e); throw new Exception(e.getCause()); } }
@Override public void onCreate() { super.onCreate(); Logger.v(TAG, "服务初始化"); }
private static void clearAlarm() { Logger.v(TAG, "clear unread block"); AlarmManager am = (AlarmManager) GlobalContext.getInstance().getSystemService(ALARM_SERVICE); am.cancel(getOperation()); }