├── .directory ├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── muzei-api-2.0-javadoc.jar │ └── muzei-api-2.0.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── moe │ │ └── democyann │ │ └── pixivformuzeiplus │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── moe │ │ │ └── democyann │ │ │ └── pixivformuzeiplus │ │ │ ├── PixivSource.java │ │ │ ├── activity │ │ │ ├── IcoActivity.java │ │ │ └── MainActivity.java │ │ │ ├── dbUtil │ │ │ ├── DbHelper.java │ │ │ └── DbUtil.java │ │ │ ├── settings │ │ │ ├── Setting.java │ │ │ └── SettingFragment.java │ │ │ └── util │ │ │ ├── ConfigManger.java │ │ │ ├── Cookie.java │ │ │ ├── HttpUtil.java │ │ │ ├── ImgInfo.java │ │ │ ├── Pixiv.java │ │ │ ├── PixivLike.java │ │ │ ├── PixivTop50.java │ │ │ ├── PixivUser.java │ │ │ └── TagFliter.java │ └── res │ │ ├── drawable-nodpi │ │ ├── back.png │ │ ├── backa.png │ │ └── ic_launcher.png │ │ ├── drawable-xxxhdpi │ │ ├── back.png │ │ ├── backa.png │ │ └── ic_launcher.png │ │ ├── layout │ │ ├── activity_ico.xml │ │ └── activity_main.xml │ │ ├── mipmap-nodpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-en │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ ├── values-ja │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ ├── values-zh │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── filepaths.xml │ │ └── setting.xml │ └── test │ └── java │ └── moe │ └── democyann │ └── pixivformuzeiplus │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | PreviewsShown=true 3 | Timestamp=2017,4,5,22,17,53 4 | Version=3 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuildi 10 | *.apk 11 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, MOEOVERFLOW 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ========================= 31 | 32 | I don't like GPL blackmail,so I want used BSD License. 33 | 34 | 我不喜欢GPL敲诈,所以我用BSD协议。 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PixivForMuzeiPlus 2 | 3 | This is a Muzei Live Wallpaper's Source. 4 | 5 | ![i1](http://image.coolapk.com/apk_image/2017/0406/E5AEA3E4BCA0E59BBE1-for-127776-o_1bd1pjh358p310n91sen1d0llcs10-uid-776252.jpg) 6 | 7 | ---------- 8 | 9 | 1.You can configure the interval of image changings. 10 | 2.Three push mode your choose (Daily TOP50,Recommend,Bookmarks) 11 | 3.You can changing image under WiFi only. 12 | 4.You can configure tags filter. 13 | 5.You can using R-18 switch. 14 | 6.You can configure min views 15 | 7. Auto preloading 16 | 17 | ### Download 18 | [![Get it on Google Play](https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=moe.democyann.pixivformuzeiplus&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1) 19 | 20 | ### Language 21 | 22 | 1.中文(简体) 23 | 2.日本語 24 | 3.English 25 | 26 | ### License 27 | 28 | BSD 29 | 30 | ### Thanks 31 | 32 | Japanese translator is [琉千歌_Luccica](https://twitter.com/Stella_Luccica) 33 | Icon is by 秋守空 " [Le Ciel Bleu](http://www.pixiv.net/member_illust.php?mode=medium&illust_id=51927352) " 34 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion '25.0.0' 6 | defaultConfig { 7 | applicationId "moe.democyann.pixivformuzeiplus" 8 | minSdkVersion 19 9 | targetSdkVersion 25 10 | versionCode 11 11 | versionName "1.2.1" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled true 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.3.1' 28 | testCompile 'junit:junit:4.12' 29 | compile files('libs/muzei-api-2.0.jar') 30 | compile files('libs/muzei-api-2.0-javadoc.jar') 31 | } 32 | -------------------------------------------------------------------------------- /app/libs/muzei-api-2.0-javadoc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moeoverflow/PixivForMuzeiPlus/89c252c3622d6b8e611ca25267860d5f8e4455d8/app/libs/muzei-api-2.0-javadoc.jar -------------------------------------------------------------------------------- /app/libs/muzei-api-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moeoverflow/PixivForMuzeiPlus/89c252c3622d6b8e611ca25267860d5f8e4455d8/app/libs/muzei-api-2.0.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/demo/Data/SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -dontusemixedcaseclassnames 20 | -dontskipnonpubliclibraryclasses 21 | -verbose 22 | 23 | # Optimization is turned off by default. Dex does not like code run 24 | # through the ProGuard optimize and preverify steps (and performs some 25 | # of these optimizations on its own). 26 | -dontoptimize 27 | -dontpreverify 28 | # Note that if you want to enable optimization, you cannot just 29 | # include optimization flags in your own project configuration file; 30 | # instead you will need to point to the 31 | # "proguard-android-optimize.txt" file instead of this one from your 32 | # project.properties file. 33 | 34 | -keepattributes *Annotation* 35 | -keep public class com.google.vending.licensing.ILicensingService 36 | -keep public class com.android.vending.licensing.ILicensingService 37 | 38 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 39 | -keepclasseswithmembernames class * { 40 | native ; 41 | } 42 | 43 | # keep setters in Views so that animations can still work. 44 | # see http://proguard.sourceforge.net/manual/examples.html#beans 45 | -keepclassmembers public class * extends android.view.View { 46 | void set*(***); 47 | *** get*(); 48 | } 49 | 50 | # We want to keep methods in Activity that could be used in the XML attribute onClick 51 | -keepclassmembers class * extends android.app.Activity { 52 | public void *(android.view.View); 53 | } 54 | 55 | # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 56 | -keepclassmembers enum * { 57 | public static **[] values(); 58 | public static ** valueOf(java.lang.String); 59 | } 60 | 61 | -keepclassmembers class * implements android.os.Parcelable { 62 | public static final android.os.Parcelable$Creator CREATOR; 63 | } 64 | 65 | -keepclassmembers class **.R$* { 66 | public static ; 67 | } 68 | 69 | # The support library contains references to newer platform versions. 70 | # Don't warn about those in case this app is linking against an older 71 | # platform version. We know about them, and they are safe. 72 | -dontwarn android.support.** 73 | 74 | # Understand the @Keep support annotation. 75 | -keep class android.support.annotation.Keep 76 | 77 | -keep @android.support.annotation.Keep class * {*;} 78 | 79 | -keepclasseswithmembers class * { 80 | @android.support.annotation.Keep ; 81 | } 82 | 83 | -keepclasseswithmembers class * { 84 | @android.support.annotation.Keep ; 85 | } 86 | 87 | -keepclasseswithmembers class * { 88 | @android.support.annotation.Keep (...); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /app/src/androidTest/java/moe/democyann/pixivformuzeiplus/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("moe.democyann.pixivformuzeiplus", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 25 | 26 | 27 | 28 | 29 | 32 | 35 | 36 | 37 | 42 | 43 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/PixivSource.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus; 2 | 3 | 4 | import android.app.Application; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.net.ConnectivityManager; 8 | import android.net.NetworkInfo; 9 | import android.util.Log; 10 | 11 | import com.google.android.apps.muzei.api.Artwork; 12 | import com.google.android.apps.muzei.api.RemoteMuzeiArtSource; 13 | 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | 17 | import java.io.File; 18 | import java.io.FileNotFoundException; 19 | import java.io.FileOutputStream; 20 | import java.io.IOException; 21 | import java.util.Locale; 22 | 23 | import moe.democyann.pixivformuzeiplus.dbUtil.DbUtil; 24 | import moe.democyann.pixivformuzeiplus.util.ConfigManger; 25 | import moe.democyann.pixivformuzeiplus.util.PixivLike; 26 | import moe.democyann.pixivformuzeiplus.util.PixivTop50; 27 | import moe.democyann.pixivformuzeiplus.util.PixivUser; 28 | 29 | 30 | /** 31 | * Created by demo on 4/3/17. 32 | * Pixiv Source for Muzei 33 | * Auth:Democyann 34 | * email:support@democyann.moe 35 | * github:@democyann 36 | * blog:https://democyann.moe 37 | */ 38 | 39 | public class PixivSource extends RemoteMuzeiArtSource { 40 | private static final String TAG = "PixivSource"; 41 | private static final String SOURCE_NAME = "PixivSource"; 42 | private static final int MINUTE = 60*1000; 43 | 44 | private static boolean loadflag=false; 45 | private static String error=""; 46 | 47 | 48 | private static PixivTop50 pixivtop; //Top50类 49 | private static PixivUser pixivUser; //Pixiv用户推荐类 50 | private static PixivLike pixivLike; //Pixiv收藏夹 51 | 52 | private static ConfigManger conf; //设置管理器 53 | private DbUtil db; //数据库辅助类 54 | 55 | 56 | private int cont=0; 57 | private long lasttime=0; 58 | 59 | private Runnable runnable = new Runnable() { 60 | @Override 61 | public void run() { 62 | loadflag=true; 63 | 64 | Artwork a = null; 65 | while (true) { 66 | 67 | error=""; 68 | 69 | int method=conf.getMethod(); 70 | //每日TOP50模式 71 | if (method == 0) { 72 | try { 73 | a = pixivtop.getArtwork(); 74 | } catch (Exception e) { 75 | error = pixivtop.getError(); 76 | e.printStackTrace(); 77 | } 78 | }else if(method == 1){ 79 | //用户推荐模式 80 | try{ 81 | a = pixivUser.getArtwork(); 82 | }catch (Exception e){ 83 | Log.i(TAG, "run: ERROR get User ArtWork"); 84 | error=pixivUser.getError(); 85 | Log.i(TAG, "run: ERROR !"+error); 86 | e.printStackTrace(); 87 | try { 88 | a = pixivtop.getArtwork(); 89 | }catch (Exception er){ 90 | er.printStackTrace(); 91 | error+=","+pixivtop.getError(); 92 | } 93 | } 94 | 95 | }else{ 96 | //收藏夹模式 97 | try{ 98 | a = pixivLike.getArtwork(); 99 | }catch (Exception e){ 100 | Log.i(TAG, "run: ERROR get Like ArtWork"); 101 | error=pixivLike.getError(); 102 | Log.i(TAG, "run: ERROR !"+error); 103 | e.printStackTrace(); 104 | try { 105 | a = pixivtop.getArtwork(); 106 | }catch (Exception er){ 107 | er.printStackTrace(); 108 | error+=","+pixivtop.getError(); 109 | } 110 | } 111 | } 112 | int i=0; 113 | if(a!=null) { 114 | try { 115 | i= db.insertImg(a.toJson().toString()); 116 | }catch (Exception e){ 117 | e.printStackTrace(); 118 | } 119 | } 120 | 121 | Log.i(TAG, "run: ERROR"+error); 122 | if(!"".equals(error)){ 123 | if(error.equals("1100")) error=getString(R.string.u_err); 124 | if(error.equals("1005")) error=getString(R.string.login_failed); 125 | if(error.equals("2001")) error=getString(R.string.permission); 126 | cont++; 127 | Artwork t= PixivSource.this.getCurrentArtwork(); 128 | Artwork p = new Artwork.Builder() 129 | .title(t.getTitle()) 130 | .byline(t.getByline()+"\nERROR:"+error) 131 | .imageUri(t.getImageUri()) 132 | .viewIntent(t.getViewIntent()) 133 | .token(t.getToken()) 134 | .build(); 135 | publishArtwork(p); 136 | break; 137 | }else { 138 | cont=0; 139 | } 140 | if (i > 5) break; 141 | } 142 | loadflag=false; 143 | } 144 | }; 145 | 146 | 147 | 148 | public PixivSource() { 149 | super(SOURCE_NAME); 150 | } 151 | 152 | @Override 153 | public void onCreate() { 154 | super.onCreate(); 155 | setUserCommands(BUILTIN_COMMAND_ID_NEXT_ARTWORK); 156 | conf=new ConfigManger(this); 157 | pixivtop= new PixivTop50(this,getDir()); 158 | pixivUser=new PixivUser(this,getDir()); 159 | pixivLike=new PixivLike(this,getDir()); 160 | db=new DbUtil(this); 161 | } 162 | 163 | @Override 164 | protected void onTryUpdate(int i) throws RetryException { 165 | 166 | Log.i(TAG, "onTryUpdate: ===== info:"+i); 167 | 168 | if(System.currentTimeMillis()-lasttime<1000){ 169 | scheduleUpdate(); 170 | return; 171 | } 172 | 173 | 174 | if(i==3 && conf.getChangeInterval()==0){ 175 | scheduleUpdate(0); 176 | Log.i(TAG, "onTryUpdate: STOP Update"); 177 | return; 178 | } 179 | 180 | lasttime=System.currentTimeMillis(); 181 | 182 | if(!isEnabledWifi() && conf.isOnlyUpdateOnWifi()){ 183 | scheduleUpdate(); 184 | return; 185 | } 186 | if(cont>=6){ 187 | scheduleUpdate(0); 188 | } 189 | 190 | String [] arr = {"KP","PRK","408","KR","KOR","410","ko","kor"}; 191 | String ct=Locale.getDefault().getCountry(); 192 | String lg=Locale.getDefault().getLanguage(); 193 | for(String te:arr){ 194 | if(ct.equals(te) || lg.equals(te)) 195 | return; 196 | } 197 | 198 | Artwork last=getCurrentArtwork(); 199 | Artwork artwork=last; 200 | 201 | String json = db.getImg(); 202 | JSONObject o = null; 203 | try { 204 | o = new JSONObject(json); 205 | } catch (JSONException e) { 206 | e.printStackTrace(); 207 | } 208 | if (o != null) { 209 | try { 210 | artwork = Artwork.fromJson(o); 211 | } catch (JSONException e) { 212 | e.printStackTrace(); 213 | 214 | } 215 | } 216 | 217 | //进程未启动时则获取新图片 218 | if(!loadflag) { 219 | Thread t = new Thread(runnable); 220 | Log.i(TAG, "onTryUpdate: Thread Start"); 221 | Log.i(TAG, "onTryUpdate: ==========METHOD======"+conf.getMethod()); 222 | t.start(); 223 | } 224 | 225 | //未找到文件则2秒后重新获取下一张图片 226 | if(cont<6) { 227 | if (artwork != null) { 228 | File test = new File(getDir(), artwork.getToken()); 229 | if (!test.exists()) { 230 | Log.i(TAG, "onTryUpdate: No Find File"); 231 | scheduleUpdate(System.currentTimeMillis() + 2 * 1000); 232 | cont++; 233 | return; 234 | } 235 | } else { 236 | scheduleUpdate(System.currentTimeMillis() + 5 * 1000); 237 | cont++; 238 | return; 239 | } 240 | }else{ 241 | scheduleUpdate(0); 242 | return; 243 | } 244 | 245 | Log.i(TAG, "onTryUpdate: AWRK URI:"+artwork.getImageUri().toString()); 246 | //分享文件前进行授权 247 | grantUriPermission("net.nurik.roman.muzei", artwork.getImageUri(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 248 | 249 | //推送图片 250 | publishArtwork(artwork); 251 | 252 | //清理无用缓存 253 | if(!artwork.equals(last)){ 254 | try { 255 | File f= new File(getDir(),last.getToken()); 256 | f.delete(); 257 | }catch (Exception e){ 258 | e.printStackTrace(); 259 | } 260 | 261 | } 262 | 263 | scheduleUpdate(); 264 | } 265 | 266 | private File getDir(){ 267 | Application app = getApplication(); 268 | if(app.getExternalCacheDir()==null){ 269 | return app.getCacheDir(); 270 | }else{ 271 | return app.getExternalCacheDir(); 272 | } 273 | } 274 | 275 | 276 | /*** 277 | * 获取是否开启了 Wifi 网络 278 | * @return 279 | */ 280 | private boolean isEnabledWifi() { 281 | ConnectivityManager connectivityManager = 282 | (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 283 | NetworkInfo wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 284 | return wifi.isConnected(); 285 | } 286 | 287 | 288 | /*** 289 | * 设置默认更新时间 290 | */ 291 | 292 | private void scheduleUpdate() { 293 | int changeInterval = conf.getChangeInterval(); 294 | if (changeInterval > 0) { 295 | scheduleUpdate(System.currentTimeMillis() + changeInterval * MINUTE); 296 | } 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/activity/IcoActivity.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.activity; 2 | 3 | import android.content.ComponentName; 4 | import android.content.pm.PackageManager; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.util.Log; 8 | import android.widget.Toast; 9 | 10 | import moe.democyann.pixivformuzeiplus.R; 11 | import moe.democyann.pixivformuzeiplus.util.ConfigManger; 12 | 13 | public class IcoActivity extends AppCompatActivity { 14 | 15 | private ConfigManger conf; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_ico); 21 | conf=new ConfigManger(this); 22 | if(conf.get_icon()){ 23 | PackageManager p = getPackageManager(); 24 | ComponentName test = new ComponentName("moe.democyann.pixivformuzeiplus", "moe.democyann.pixivformuzeiplus.activity.MainActivity"); 25 | p.setComponentEnabledSetting(test, 26 | PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 27 | PackageManager.DONT_KILL_APP); 28 | Log.i("ICO", "onCreate: DISABLED"); 29 | Toast.makeText(getApplicationContext(), "隐藏图标", 30 | Toast.LENGTH_SHORT).show(); 31 | conf.set_icon(false); 32 | }else { 33 | PackageManager p = getPackageManager(); 34 | ComponentName test = new ComponentName("moe.democyann.pixivformuzeiplus", "moe.democyann.pixivformuzeiplus.activity.MainActivity"); 35 | p.setComponentEnabledSetting(test, 36 | PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 37 | PackageManager.DONT_KILL_APP); 38 | Log.i("ICO", "onCreate: ENABLED"); 39 | Toast.makeText(getApplicationContext(), "显示图标", 40 | Toast.LENGTH_SHORT).show(); 41 | conf.set_icon(true); 42 | } 43 | 44 | finish(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.activity; 2 | 3 | import android.content.Intent; 4 | import android.content.pm.PackageManager; 5 | import android.net.Uri; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.View; 9 | import android.widget.Button; 10 | import android.widget.TextView; 11 | import java.util.Locale; 12 | 13 | import moe.democyann.pixivformuzeiplus.R; 14 | import moe.democyann.pixivformuzeiplus.settings.Setting; 15 | 16 | public class MainActivity extends AppCompatActivity { 17 | 18 | private Button open_btn; 19 | private Button setting_btn; 20 | private TextView tv_1; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_main); 26 | 27 | open_btn=(Button)findViewById(R.id.open_btn); 28 | setting_btn=(Button)findViewById(R.id.setting_btn); 29 | tv_1=(TextView)findViewById(R.id.tv_1); 30 | 31 | open_btn.setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(View v) { 34 | try { 35 | PackageManager packageManager = MainActivity.this.getPackageManager(); 36 | Intent intent; 37 | intent =packageManager.getLaunchIntentForPackage("net.nurik.roman.muzei"); 38 | startActivity(intent); 39 | }catch (Exception e){ 40 | Uri uri = Uri.parse("market://details?id=net.nurik.roman.muzei"); 41 | Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri); 42 | startActivity(goToMarket); 43 | } 44 | } 45 | }); 46 | setting_btn.setOnClickListener(new View.OnClickListener() { 47 | @Override 48 | public void onClick(View v) { 49 | Intent intent=new Intent(MainActivity.this, Setting.class); 50 | startActivity(intent); 51 | } 52 | }); 53 | 54 | String [] arr = {"KP","PRK","408","KR","KOR","410","ko","kor"}; 55 | String ct= Locale.getDefault().getCountry(); 56 | String lg=Locale.getDefault().getLanguage(); 57 | for(String te:arr){ 58 | if(ct.equals(te) || lg.equals(te)){ 59 | tv_1.setText("The app is not currently available in your country"); 60 | } 61 | 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/dbUtil/DbHelper.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.dbUtil; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | /** 8 | * Created by demo on 4/3/17. 9 | */ 10 | 11 | public class DbHelper extends SQLiteOpenHelper { 12 | 13 | private static final int DB_VERSION = 1; 14 | private static final String DB_NAME = "pixiv.db"; 15 | public static final String TABLE_NAME1 = "image"; 16 | public static final String TABLE_NAME2 = "info"; 17 | 18 | public DbHelper(Context context){ 19 | super(context,DB_NAME,null,DB_VERSION); 20 | 21 | } 22 | 23 | @Override 24 | public void onCreate(SQLiteDatabase db) { 25 | String sql = "create table if not exists " + TABLE_NAME1 + " (Id integer primary key AUTOINCREMENT, Info text)"; 26 | db.execSQL(sql); 27 | sql="create table if not exists " + TABLE_NAME2 + " (Key text primary key, Value text)"; 28 | db.execSQL(sql); 29 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('last','0')"); 30 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('rallList','')"); 31 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('commList','')"); 32 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('likeList','')"); 33 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('cookie','')"); 34 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('token','')"); 35 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('username','')"); 36 | db.execSQL("insert into "+ TABLE_NAME2 + " (Key,Value) values('userid','')"); 37 | 38 | } 39 | 40 | @Override 41 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/dbUtil/DbUtil.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.dbUtil; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | 8 | /** 9 | * Created by demo on 4/3/17. 10 | */ 11 | 12 | public class DbUtil { 13 | private Context context; 14 | private DbHelper dbHelper; 15 | private SQLiteDatabase db; 16 | 17 | public DbUtil(Context context){ 18 | this.context=context; 19 | dbHelper=new DbHelper(this.context); 20 | } 21 | 22 | /*** 23 | * 插入图片信息数据 24 | * @param str 25 | */ 26 | public int insertImg(String str){ 27 | int count=0; 28 | ContentValues values=new ContentValues(); 29 | values.put("Info",str); 30 | db=dbHelper.getWritableDatabase(); 31 | // db.beginTransaction(); 32 | db.insert(dbHelper.TABLE_NAME1,null,values); 33 | Cursor cursor = db.query(dbHelper.TABLE_NAME1,new String[]{"Info"},null,null,null,null,null); 34 | count=cursor.getCount(); 35 | db.close(); 36 | return count; 37 | // db.setTransactionSuccessful(); 38 | } 39 | 40 | /*** 41 | * 清空图片信息数据 42 | */ 43 | public void cleanDb(){ 44 | db=dbHelper.getWritableDatabase(); 45 | // db.beginTransaction(); 46 | db.delete(dbHelper.TABLE_NAME1,null,null); 47 | db.close(); 48 | // db.setTransactionSuccessful(); 49 | 50 | } 51 | 52 | 53 | /*** 54 | * 获取图片信息并删除图片信息 55 | * @return 56 | */ 57 | public String getImg(){ 58 | String con=""; 59 | db=dbHelper.getWritableDatabase(); 60 | Cursor cursor = db.query(dbHelper.TABLE_NAME1,new String[]{"Id","Info"},null,null,null,null,"Id","1"); 61 | if(cursor.getCount()>0) { 62 | if (cursor.moveToFirst()) { 63 | con = cursor.getString(1); 64 | } 65 | // db.beginTransaction(); 66 | db.delete(dbHelper.TABLE_NAME1, "Id=?", new String[]{String.valueOf(cursor.getInt(0))}); 67 | } 68 | db.close(); 69 | // db.setTransactionSuccessful(); 70 | return con; 71 | } 72 | 73 | /*** 74 | * 设置信息 75 | * @param key 76 | * @param value 77 | */ 78 | public void setInfo(String key,String value){ 79 | ContentValues values=new ContentValues(); 80 | values.put("Value",value); 81 | db=dbHelper.getWritableDatabase(); 82 | // db.beginTransaction(); 83 | db.update(dbHelper.TABLE_NAME2,values,"Key=?",new String[]{key}); 84 | db.close(); 85 | // db.setTransactionSuccessful(); 86 | } 87 | 88 | /*** 89 | * 获取信息 90 | * @param key 91 | * @return 92 | */ 93 | public String getInfo(String key){ 94 | String con=""; 95 | db=dbHelper.getWritableDatabase(); 96 | Cursor cursor = db.query(dbHelper.TABLE_NAME2,new String[]{"Value"},"Key=?",new String[]{key},null,null,null); 97 | if(cursor.moveToFirst()){ 98 | con=cursor.getString(0); 99 | } 100 | db.close(); 101 | return con; 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/settings/Setting.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.settings; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | public class Setting extends Activity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | getFragmentManager().beginTransaction().replace(android.R.id.content,new SettingFragment()).commit(); 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/settings/SettingFragment.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.settings; 2 | 3 | import android.os.Bundle; 4 | import android.preference.PreferenceFragment; 5 | 6 | import moe.democyann.pixivformuzeiplus.R; 7 | 8 | public class SettingFragment extends PreferenceFragment { 9 | @Override 10 | public void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | addPreferencesFromResource(R.xml.setting); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/ConfigManger.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.preference.PreferenceManager; 7 | import android.util.DisplayMetrics; 8 | import android.util.Log; 9 | import android.view.WindowManager; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import moe.democyann.pixivformuzeiplus.PixivSource; 15 | import moe.democyann.pixivformuzeiplus.R; 16 | 17 | /** 18 | * Created by demo on 4/3/17. 19 | */ 20 | 21 | public class ConfigManger { 22 | 23 | private Context context; 24 | private SharedPreferences preferences; 25 | private static final String TAG = "ConfigManager"; 26 | 27 | public ConfigManger(Context context) { 28 | this.context = context; 29 | preferences = PreferenceManager.getDefaultSharedPreferences(context); 30 | } 31 | 32 | public String getPassword() { 33 | 34 | String defaultValue = "", 35 | v = preferences.getString("password", defaultValue); 36 | return v; 37 | } 38 | 39 | public String getUsername() { 40 | String defaultValue = "", 41 | v = preferences.getString("pixivid", defaultValue); 42 | return v; 43 | } 44 | 45 | public boolean isOnlyUpdateOnWifi() { 46 | boolean defaultValue = false, 47 | v = preferences.getBoolean("only_wifi", defaultValue); 48 | Log.d(TAG, "pref_onlyWifi = " + v); 49 | return v; 50 | } 51 | 52 | public String getTage() { 53 | String defaultValue = "", 54 | v = preferences.getString("tags", defaultValue); 55 | return v; 56 | } 57 | 58 | public long getView() { 59 | String defaultValue = "0", 60 | s = preferences.getString("views", defaultValue); 61 | long v = 0; 62 | try { 63 | v = Long.valueOf(s); 64 | } catch (Exception e) { 65 | Log.e(TAG, "getViews: ", e); 66 | } 67 | if (v > 50000) v = 50000; 68 | return v; 69 | } 70 | 71 | public boolean getIs_no_R18() { 72 | boolean defaultValue = true, 73 | v = preferences.getBoolean("is_no_r18", defaultValue); 74 | return v; 75 | } 76 | 77 | public int getChangeInterval() { 78 | 79 | final String defaultValue = context.getString(R.string.time_default), 80 | s = preferences.getString("time_change", defaultValue); 81 | Log.d(TAG, "time_change = \"" + s + "\""); 82 | try { 83 | return Integer.parseInt(s); 84 | } catch (NumberFormatException e) { 85 | Log.w(TAG, e.toString(), e); 86 | return 0; 87 | } 88 | } 89 | 90 | public int getMethod() { 91 | final String defaultValue = context.getString(R.string.method_default), 92 | s = preferences.getString("method", defaultValue); 93 | try { 94 | return Integer.parseInt(s); 95 | } catch (NumberFormatException e) { 96 | Log.w(TAG, e.toString(), e); 97 | return 0; 98 | } 99 | } 100 | 101 | public boolean getIs_check_Tag() { 102 | boolean defaultValue = false, 103 | v = preferences.getBoolean("is_tag", defaultValue); 104 | return v; 105 | } 106 | public boolean getIs_autopx() { 107 | boolean defaultValue = false, 108 | v = preferences.getBoolean("is_autopx", defaultValue); 109 | return v; 110 | } 111 | 112 | public boolean get_icon(){ 113 | boolean defaultValue = true, 114 | v = preferences.getBoolean("icon", defaultValue); 115 | return v; 116 | } 117 | 118 | public void set_icon(boolean v){ 119 | SharedPreferences.Editor edit = preferences.edit(); 120 | edit.putBoolean("icon",v); 121 | edit.commit(); 122 | } 123 | 124 | 125 | 126 | public String listToString(List list) { 127 | StringBuilder sb = new StringBuilder(); 128 | 129 | for (int i = 0; i < list.size(); i++) { 130 | sb.append(list.get(i)).append(','); 131 | } 132 | return sb.toString().substring(0, sb.toString().length() - 1); 133 | } 134 | public List stringToList(String str) { 135 | ArrayList list= new ArrayList(); 136 | if(!"".equals(str) && str.length()>100) { 137 | String arr[] = str.split(","); 138 | for (String a : arr) { 139 | list.add(a); 140 | } 141 | } 142 | return list; 143 | } 144 | 145 | public double getPx(){ 146 | DisplayMetrics dm =context.getResources().getDisplayMetrics(); 147 | int w_screen = dm.widthPixels; 148 | int h_screen = dm.heightPixels; 149 | Log.i(TAG, "getPx: "+w_screen+" * " + h_screen); 150 | return (w_screen*1.00)/h_screen; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/Cookie.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by demo on 3/31/17. 8 | */ 9 | 10 | public class Cookie { 11 | private Map cookie; 12 | public Cookie(){ 13 | cookie=new HashMap(); 14 | } 15 | public Cookie(String str){ 16 | cookie=new HashMap(); 17 | 18 | if(!"".equals(str)){ 19 | String[] cooarr=str.split(";"); 20 | for(String c:cooarr){ 21 | add(c); 22 | } 23 | } 24 | 25 | } 26 | public boolean add(String key,String value){ 27 | cookie.put(key, value); 28 | return true; 29 | } 30 | 31 | public boolean add(String str){ 32 | if(str.indexOf("=")==-1) return false; 33 | String[] arr=str.split("="); 34 | this.add(arr[0], arr[1]); 35 | return true; 36 | } 37 | 38 | public void remove(String key){ 39 | cookie.remove(key); 40 | } 41 | 42 | public String toString(){ 43 | StringBuffer temp = new StringBuffer(); 44 | for(String key:cookie.keySet()){ 45 | temp.append(key).append("=").append(cookie.get(key)).append(";"); 46 | } 47 | return temp.toString(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/HttpUtil.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | import android.util.Log; 4 | 5 | import com.google.android.apps.muzei.api.RemoteMuzeiArtSource; 6 | 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.InputStreamReader; 12 | import java.io.OutputStream; 13 | import java.net.HttpURLConnection; 14 | import java.net.MalformedURLException; 15 | import java.net.URL; 16 | import java.util.List; 17 | import java.util.Map; 18 | import java.util.zip.GZIPInputStream; 19 | 20 | /** 21 | * Created by demo on 3/31/17. 22 | */ 23 | 24 | public class HttpUtil { 25 | private HttpURLConnection conn; 26 | private URL url; 27 | private String uri; 28 | private InputStream inputStream; 29 | private OutputStream outputStream; 30 | private InputStreamReader inputStreamReader; 31 | private String restring; 32 | private char[] buffer; 33 | private Cookie cookie; 34 | 35 | private String TAG="PixivHttpUtil"; 36 | 37 | public HttpUtil(String uri,Cookie cookie){ 38 | this.uri=uri; 39 | this.cookie=cookie; 40 | } 41 | 42 | public String getData(Map head){ 43 | try{ 44 | conn=(HttpURLConnection)url.openConnection(); 45 | conn.setReadTimeout(10000); 46 | conn.setConnectTimeout(15000); 47 | conn.setRequestMethod("GET"); 48 | conn.setRequestProperty("Cookie",cookie.toString()); 49 | for(String key:head.keySet()) { 50 | conn.setRequestProperty(key,head.get(key)); 51 | } 52 | conn.setDoInput(true); 53 | conn.connect(); 54 | 55 | int status = conn.getResponseCode(); 56 | 57 | if (status != 200) { 58 | Log.w(TAG, "Response code: " + status); 59 | Log.i(TAG, "getData: "+conn.getHeaderField("location")); 60 | throw new RemoteMuzeiArtSource.RetryException(new Exception("HTTP ERROR "+status)); 61 | } 62 | Log.d(TAG, "Response code: " + status); 63 | 64 | List set_cookie = conn.getHeaderFields().get("Set-Cookie"); 65 | if(set_cookie!=null) { 66 | for (String str : set_cookie) { 67 | String ci = str.substring(0, str.indexOf(";")); 68 | cookie.add(ci); 69 | } 70 | } 71 | 72 | 73 | try { 74 | inputStream = conn.getInputStream(); 75 | inputStreamReader= new InputStreamReader(inputStream); 76 | int read; 77 | if("gzip".equals(conn.getContentEncoding())){ 78 | GZIPInputStream gzip= new GZIPInputStream(inputStream); 79 | inputStreamReader=new InputStreamReader(gzip); 80 | } 81 | buffer = new char[1024]; 82 | while ((read = inputStreamReader.read(buffer)) != -1) { 83 | restring += String.valueOf(buffer, 0, read); 84 | } 85 | }finally { 86 | try{ 87 | inputStream.close(); 88 | }catch (final IOException e) { 89 | Log.e(TAG, e.toString(), e); 90 | throw new RemoteMuzeiArtSource.RetryException(e); 91 | } 92 | } 93 | 94 | }catch (Exception e){ 95 | Log.e(TAG, e.toString(), e); 96 | return "ERROR"; 97 | } 98 | 99 | return restring; 100 | } 101 | 102 | public String postData(Map head,String poststr){ 103 | try{ 104 | conn=(HttpURLConnection)url.openConnection(); 105 | conn.setReadTimeout(10000); 106 | conn.setConnectTimeout(15000); 107 | conn.setRequestMethod("GET"); 108 | conn.setRequestProperty("Cookie",cookie.toString()); 109 | for(String key:head.keySet()) { 110 | conn.setRequestProperty(key,head.get(key)); 111 | } 112 | conn.setDoInput(true); 113 | conn.setDoOutput(true); 114 | try{ 115 | outputStream=conn.getOutputStream(); 116 | outputStream.write(poststr.getBytes()); 117 | }finally { 118 | try{ 119 | outputStream.flush(); 120 | outputStream.close(); 121 | }catch(Exception e) { 122 | Log.e(TAG, e.toString(), e); 123 | return "ERROR"; 124 | } 125 | } 126 | 127 | 128 | conn.connect(); 129 | 130 | int status = conn.getResponseCode(); 131 | 132 | if (status != 200) { 133 | Log.w(TAG, "Response code: " + status); 134 | throw new RemoteMuzeiArtSource.RetryException(new Exception("HTTP ERROR "+status)); 135 | } 136 | Log.d(TAG, "Response code: " + status); 137 | 138 | List set_cookie = conn.getHeaderFields().get("Set-Cookie"); 139 | 140 | if(set_cookie!=null) { 141 | for (String str : set_cookie) { 142 | String ci = str.substring(0, str.indexOf(";")); 143 | cookie.add(ci); 144 | } 145 | } 146 | Log.i(TAG, "postData: COOKIE:"+cookie.toString()); 147 | 148 | try { 149 | inputStream = conn.getInputStream(); 150 | inputStreamReader= new InputStreamReader(inputStream); 151 | int read; 152 | if("gzip".equals(conn.getContentEncoding())){ 153 | GZIPInputStream gzip= new GZIPInputStream(inputStream); 154 | inputStreamReader=new InputStreamReader(gzip); 155 | } 156 | buffer=new char[1024]; 157 | while ((read=inputStreamReader.read(buffer)) != -1) { 158 | restring += String.valueOf(buffer,0,read); 159 | // buffer=new char[1024*10]; 160 | } 161 | }finally { 162 | try{ 163 | inputStream.close(); 164 | }catch (final IOException e) { 165 | Log.e(TAG, e.toString(), e); 166 | throw new RemoteMuzeiArtSource.RetryException(e); 167 | } 168 | } 169 | 170 | }catch (Exception e){ 171 | Log.e(TAG, e.toString(), e); 172 | return "ERROR"; 173 | } 174 | 175 | return restring; 176 | } 177 | 178 | 179 | public Cookie getCookie(){ 180 | return cookie; 181 | } 182 | 183 | public boolean checkURL(){ 184 | boolean flag=true; 185 | try { 186 | url = new URL(uri); 187 | } catch (MalformedURLException e) { 188 | Log.e(TAG, e.toString(),e ); 189 | flag=false; 190 | } 191 | return flag; 192 | } 193 | 194 | public boolean downloadImg(String referer,String USER_AGENT,File file){ 195 | try{ 196 | conn=(HttpURLConnection)url.openConnection(); 197 | conn.setReadTimeout(10000); 198 | conn.setConnectTimeout(15000); 199 | conn.setRequestMethod("GET"); 200 | conn.setRequestProperty("User-Agent", USER_AGENT); 201 | conn.setRequestProperty("Referer", referer); 202 | conn.setDoInput(true); 203 | conn.connect(); 204 | int status = conn.getResponseCode(); 205 | if(status!=200) { 206 | Log.i(TAG, "downloadImg: ERROR"); 207 | return false; 208 | } 209 | FileOutputStream fileStream = new FileOutputStream(file); 210 | inputStream=conn.getInputStream(); 211 | if("gzip".equals(conn.getContentEncoding())){ 212 | GZIPInputStream gzip = new GZIPInputStream(inputStream); 213 | inputStream = gzip; 214 | } 215 | try{ 216 | byte[] buff=new byte[1024*50]; 217 | int read; 218 | while((read=inputStream.read(buff))>0){ 219 | fileStream.write(buff,0,read); 220 | } 221 | }finally { 222 | fileStream.close(); 223 | try{ 224 | inputStream.close(); 225 | }catch (Exception e){ 226 | Log.e(TAG, e.toString(), e); 227 | return false; 228 | } 229 | } 230 | } catch (Exception e){ 231 | Log.e(TAG, e.toString(), e); 232 | return false; 233 | } 234 | return true; 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/ImgInfo.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | /** 4 | * Created by demo on 4/3/17. 5 | * 图像信息实体 6 | */ 7 | 8 | public class ImgInfo { 9 | private String img_url=""; //图像地址 10 | private String img_name=""; //图像标题 11 | private String img_id=""; //图像ID 12 | private String user_id=""; //作者ID 13 | private String user_name="";//作者名称 14 | private String tags=""; //图像标签 15 | private boolean r18=false; //R18标志 16 | private double px=0.5; //图片宽高比 17 | 18 | private int view=0; //浏览数量 19 | 20 | public double getPx() { 21 | return px; 22 | } 23 | 24 | public void setPx(double px) { 25 | this.px = px; 26 | } 27 | 28 | public String getImg_url() { 29 | return img_url; 30 | } 31 | 32 | public void setImg_url(String img_url) { 33 | this.img_url = img_url; 34 | } 35 | 36 | public String getImg_name() { 37 | return img_name; 38 | } 39 | 40 | public void setImg_name(String img_name) { 41 | this.img_name = img_name; 42 | } 43 | 44 | public String getImg_id() { 45 | return img_id; 46 | } 47 | 48 | public void setImg_id(String img_id) { 49 | this.img_id = img_id; 50 | } 51 | 52 | public String getUser_id() { 53 | return user_id; 54 | } 55 | 56 | public void setUser_id(String user_id) { 57 | this.user_id = user_id; 58 | } 59 | 60 | public String getUser_name() { 61 | return user_name; 62 | } 63 | 64 | public void setUser_name(String user_name) { 65 | this.user_name = user_name; 66 | } 67 | 68 | public String getTags() { 69 | return tags; 70 | } 71 | 72 | public void setTags(String tags) { 73 | this.tags = tags; 74 | } 75 | 76 | public boolean isR18() { 77 | return r18; 78 | } 79 | 80 | public void setR18(boolean r18) { 81 | this.r18 = r18; 82 | } 83 | 84 | public int getView() { 85 | return view; 86 | } 87 | 88 | public void setView(int view) { 89 | this.view = view; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/Pixiv.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | import android.net.Uri; 4 | import android.util.Log; 5 | 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | 10 | import java.io.File; 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.regex.Matcher; 16 | import java.util.regex.Pattern; 17 | 18 | /** 19 | * Created by demo on 3/31/17. 20 | */ 21 | 22 | public class Pixiv { 23 | private static Cookie cookie; 24 | private static String token; 25 | private static String userid; 26 | private String restring; 27 | 28 | private final String INDEX_URL = "https://www.pixiv.net"; 29 | private final String POST_KEY_URL = "https://accounts.pixiv.net/login?lang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index"; 30 | private final String LOGIN_URL = "https://accounts.pixiv.net/api/login?lang=zh"; 31 | private final String RECOMM_URL = "https://www.pixiv.net/rpc/recommender.php?type=illust&sample_illusts=auto&num_recommendations=500&tt="; 32 | private final String ILLUST_URL="https://www.pixiv.net/rpc/illust_list.php?verbosity=&exclude_muted_illusts=1&illust_ids="; 33 | 34 | private final String DETA_URL="https://app-api.pixiv.net/v1/illust/detail?illust_id="; 35 | 36 | private final String RALL_URL="https://www.pixiv.net/ranking.php?mode=daily&content=illust&p=1&format=json"; 37 | 38 | private final String BOOK_URL="https://app-api.pixiv.net/v1/user/bookmarks/illust?restrict=public&user_id="; 39 | 40 | private static final String USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " 41 | + "Chrome/42.0.2311.152 Safari/537.36"; 42 | 43 | private Map basepre; 44 | private final String TAG="PixivUtil"; 45 | private Pattern pattern; 46 | private Matcher matcher; 47 | private String PostKey=""; 48 | private String error="0"; 49 | 50 | public Pixiv(){ 51 | this.cookie=new Cookie(); 52 | basepre= new HashMap(); 53 | basepre.put("User-Agent", USER_AGENT); 54 | basepre.put("Accept-Encoding", "gzip,deflate,sdch"); 55 | basepre.put("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 56 | Log.i(TAG, "Pixiv: init"); 57 | } 58 | 59 | public String getUserid() { 60 | return userid; 61 | } 62 | 63 | public void setUserid(String userid) { 64 | this.userid = userid; 65 | } 66 | 67 | /*** 68 | * 获取错误代码 69 | * @return 错误代码 70 | */ 71 | public String getError(){ 72 | return error; 73 | } 74 | 75 | /*** 76 | * 设置Cookie 77 | * @param cookie 78 | */ 79 | public void setCookie(Cookie cookie){ 80 | this.cookie=cookie; 81 | } 82 | 83 | /*** 84 | * 获取字符串类型的Cookie 85 | * @return 86 | */ 87 | public String getCookie(){ 88 | return cookie.toString(); 89 | } 90 | 91 | public void setToken(String token){ 92 | this.token =token; 93 | } 94 | 95 | /*** 96 | * 获取POST ID 私有 97 | */ 98 | private void getPostKey(){ 99 | 100 | error="0"; 101 | 102 | HttpUtil postkeyurl=new HttpUtil(POST_KEY_URL,cookie); 103 | if(postkeyurl.checkURL()) { 104 | restring = postkeyurl.getData(basepre); 105 | if (restring.equals("ERROR")) { 106 | Log.e(TAG, "Post Key get Filed"); 107 | error="1001"; 108 | return; 109 | } 110 | cookie=postkeyurl.getCookie(); 111 | pattern=Pattern.compile("name=\"post_key\"\\svalue=\"([a-z0-9]{32})\"",Pattern.DOTALL); 112 | matcher= pattern.matcher(restring); 113 | if (matcher.find()) { 114 | PostKey = matcher.group(1); 115 | } else { 116 | Log.e(TAG, "Post Key Not Find"); 117 | error="1002"; 118 | return; 119 | } 120 | }else{ 121 | Log.e(TAG, "URL Error"); 122 | error="1003"; 123 | return; 124 | } 125 | } 126 | 127 | /*** 128 | * 登录 Pixiv 私有 129 | * @param pixiv_id 用户名/邮箱/ID 130 | * @param password 密码 131 | * @return 成功返回 OK 失败返回 ERROR 132 | */ 133 | private boolean login(String pixiv_id,String password){ 134 | getPostKey(); 135 | if(PostKey.equals("")){ 136 | return false; 137 | } 138 | HttpUtil login_url=new HttpUtil(LOGIN_URL,cookie); 139 | if(login_url.checkURL()){ 140 | basepre.put("Accept", "application/json, text/javascript, */*; q=0.01"); 141 | restring= login_url.postData(basepre,"pixiv_id="+pixiv_id+"&password="+password+"&captcha=&g_recaptcha_response=&post_key=" 142 | + PostKey 143 | + "&source=pc&ref=wwwtop_accounts_index&return_to=http://www.pixiv.net/"); 144 | 145 | if (restring.equals("ERROR")) { 146 | Log.e(TAG, "Login Filed"); 147 | error="1004"; 148 | return false; 149 | } 150 | cookie=login_url.getCookie(); 151 | 152 | try { 153 | 154 | restring=restring.replaceFirst("null",""); 155 | Log.i(TAG, "======LOGIN restart:"+restring); 156 | JSONObject json= new JSONObject(restring); 157 | JSONObject obj= json.getJSONObject("body"); 158 | if(obj.isNull("success")){ 159 | Log.i(TAG, json.getString("message")); 160 | error="1005"; 161 | return false; 162 | }else{ 163 | return true; 164 | } 165 | } catch (JSONException e) { 166 | e.printStackTrace(); 167 | error="1006"; 168 | return false; 169 | } 170 | }else{ 171 | Log.e(TAG, "URL Error"); 172 | error="1007"; 173 | return false; 174 | } 175 | } 176 | 177 | 178 | /*** 179 | * 登录并获取tooken 180 | * @param pixiv_id 用户名 181 | * @param password 密码 182 | * @param login 是否登录 183 | * @return 184 | */ 185 | public String getToken(String pixiv_id,String password,boolean login){ 186 | boolean re; 187 | if(login) { 188 | re = login(pixiv_id, password); 189 | }else{ 190 | re=true; 191 | } 192 | if(!re){ 193 | token=""; 194 | return ""; 195 | }else{ 196 | HttpUtil index = new HttpUtil(INDEX_URL,cookie); 197 | index.checkURL(); 198 | basepre.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 199 | restring=index.getData(basepre); 200 | if(restring.equals("ERROR")){ 201 | error="1008"; 202 | return ""; 203 | } 204 | cookie=index.getCookie(); 205 | pattern = Pattern.compile("pixiv.context.token\\s=\\s\"([a-z0-9]{32})\"", Pattern.DOTALL); 206 | matcher = pattern.matcher(restring); 207 | if (matcher.find()) { 208 | token = matcher.group(1); 209 | 210 | }else{ 211 | Log.e(TAG, "Not Find Token"); 212 | error="1009"; 213 | return ""; 214 | } 215 | pattern = Pattern.compile("pixiv.user.id\\s=\\s\"(\\d+)\"", Pattern.DOTALL); 216 | matcher = pattern.matcher(restring); 217 | if (matcher.find()) { 218 | userid = matcher.group(1); 219 | Log.i(TAG, "USER_ID: "+ userid); 220 | } 221 | 222 | return token; 223 | } 224 | } 225 | 226 | /*** 227 | * 获取推荐列表 228 | * @return 推荐列表 229 | */ 230 | public List getRcomm(){ 231 | List list= new ArrayList(); 232 | Log.i(TAG, "getRcomm: TOKEN:"+token); 233 | Log.i(TAG, "getRcomm: COOKIE:"+cookie); 234 | HttpUtil recomm=new HttpUtil(RECOMM_URL+token,cookie); 235 | recomm.checkURL(); 236 | Map recprer=basepre; 237 | recprer.put("Referer", "http://www.pixiv.net/recommended.php"); 238 | recprer.put("Accept", "application/json, text/javascript, */*; q=0.01"); 239 | restring=recomm.getData(recprer); 240 | if(restring.equals("ERROR")){ 241 | error="1021"; 242 | return null; 243 | } 244 | 245 | try { 246 | restring=restring.replaceFirst("null",""); 247 | Log.i(TAG, restring); 248 | JSONObject o= new JSONObject(restring); 249 | JSONArray arr= o.getJSONArray("recommendations"); 250 | for(int i=0;i recprer = basepre; 300 | recprer.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 301 | restring = book.getData(recprer); 302 | if (restring.equals("ERROR")) { 303 | error = "1041"; 304 | return null; 305 | } 306 | 307 | try { 308 | restring = restring.replaceFirst("null", ""); 309 | Log.i(TAG, restring); 310 | JSONObject o = new JSONObject(restring); 311 | JSONArray ill = o.getJSONArray("illusts"); 312 | for (int i = 0; i < ill.length(); i++) { 313 | JSONObject t = ill.getJSONObject(i); 314 | list.add(t.get("id")); 315 | } 316 | tempurl=o.getString("next_url"); 317 | if(o.isNull("next_url")){ 318 | break; 319 | } 320 | 321 | } catch (JSONException e) { 322 | Log.e(TAG, e.toString(), e); 323 | error = "1042"; 324 | return null; 325 | } 326 | 327 | } 328 | 329 | return list; 330 | } 331 | 332 | /*** 333 | * 获取作品信息方式1(R18作品会获取失败) 334 | * @param id 作品ID 335 | * @return 336 | */ 337 | private JSONObject getIllInfo1(String id){ 338 | HttpUtil illust=new HttpUtil(DETA_URL+id,cookie); 339 | illust.checkURL(); 340 | Map recprer=basepre; 341 | // recprer.put("Referer", "http://www.pixiv.net/recommended.php"); 342 | recprer.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 343 | // recprer.put("Authorization","Bearer "+token); 344 | restring=illust.getData(recprer); 345 | if(restring.equals("ERROR")){ 346 | error="1031"; 347 | return null; 348 | } 349 | try { 350 | restring=restring.replaceFirst("null",""); 351 | Log.i(TAG, restring); 352 | JSONObject o = new JSONObject(restring); 353 | return o; 354 | } catch (JSONException e) { 355 | Log.e(TAG, e.toString(),e ); 356 | error="1032"; 357 | return null; 358 | } 359 | } 360 | 361 | /*** 362 | * 获取作品信息方式2 363 | * @param id 作品ID 364 | * @return 365 | */ 366 | private JSONObject getIllInfo2(String id){ 367 | Log.i(TAG, "getIllInfo: "+token); 368 | HttpUtil illust=new HttpUtil(ILLUST_URL+id+"&tt="+token,cookie); 369 | illust.checkURL(); 370 | Map recprer=basepre; 371 | recprer.put("Referer", "http://www.pixiv.net/recommended.php"); 372 | recprer.put("Accept", "application/json, text/javascript, */*; q=0.01"); 373 | restring=illust.getData(recprer); 374 | if(restring.equals("ERROR")){ 375 | error="1033"; 376 | return null; 377 | } 378 | try { 379 | restring=restring.replaceFirst("null",""); 380 | Log.i(TAG, restring); 381 | JSONArray arr = new JSONArray(restring); 382 | return arr.getJSONObject(0); 383 | } catch (JSONException e) { 384 | Log.e(TAG, e.toString(),e ); 385 | error="1034"; 386 | return null; 387 | } 388 | } 389 | 390 | /*** 391 | * 获取作品信息方式 392 | * @param id 作品ID 393 | * @return 394 | */ 395 | public ImgInfo getIllInfo(String id){ 396 | 397 | ImgInfo o = new ImgInfo(); 398 | 399 | String img_url=""; //图像地址 400 | String img_name=""; //图像标题 401 | String img_id=""; //图像ID 402 | String user_id=""; //作者ID 403 | String user_name="";//作者名称 404 | String tags=""; //图像标签 405 | boolean r18=false; //R18标志 406 | int img_width=0; 407 | int img_height=0; 408 | 409 | int view=0; //浏览数量 410 | 411 | //=============解析信息1============= 412 | 413 | JSONObject temp=getIllInfo1(id); 414 | 415 | if(temp==null) { 416 | return null; 417 | } 418 | 419 | try { 420 | 421 | JSONObject ill=temp.getJSONObject("illust"); 422 | JSONObject imgurls; 423 | 424 | //获取浏览数量 425 | view=ill.getInt("total_view"); 426 | 427 | //根据不同的页数获取图片地址 428 | if(ill.getInt("page_count")>1){ 429 | imgurls=ill.getJSONArray("meta_pages").getJSONObject(0).getJSONObject("image_urls"); 430 | img_url=imgurls.getString("original"); 431 | }else { 432 | imgurls = ill.getJSONObject("meta_single_page"); 433 | img_url=imgurls.getString("original_image_url"); 434 | } 435 | img_width=ill.getInt("width"); 436 | img_height=ill.getInt("height"); 437 | 438 | CharSequence c= "limit_r18"; 439 | 440 | if(img_url.contains(c)){ 441 | r18=true; 442 | }else{ 443 | r18=false; 444 | } 445 | 446 | JSONObject user = ill.getJSONObject("user"); 447 | user_id=user.getString("id"); 448 | user_name=user.getString("name"); 449 | img_id=ill.getString("id"); 450 | img_name=ill.getString("title"); 451 | tags=ill.getString("tags"); 452 | 453 | 454 | } catch (JSONException e) { 455 | e.printStackTrace(); 456 | error+=",1035"; 457 | return null; 458 | } 459 | 460 | //=================解析信息2============= 461 | if(r18){ 462 | temp=getIllInfo2(id); 463 | if(temp==null) { 464 | return null; 465 | } 466 | 467 | try { 468 | 469 | user_id=temp.getString("illust_user_id"); 470 | img_id=temp.getString("illust_id"); 471 | img_url=temp.getString("url"); 472 | user_name=temp.getString("user_name"); 473 | img_name=temp.getString("illust_title"); 474 | tags=temp.getString("tags"); 475 | 476 | } catch (JSONException e) { 477 | error+=",1036"; 478 | e.printStackTrace(); 479 | return null; 480 | } 481 | } 482 | 483 | o.setImg_id(img_id); 484 | o.setImg_name(img_name); 485 | o.setImg_url(img_url); 486 | o.setUser_id(user_id); 487 | o.setUser_name(user_name); 488 | o.setR18(r18); 489 | o.setTags(tags); 490 | o.setView(view); 491 | o.setPx((img_width*1.00)/img_height); 492 | Log.i(TAG, "getIllInfo: IMGPX"+img_width+" * "+img_height); 493 | 494 | return o; 495 | } 496 | 497 | 498 | /*** 499 | * 下载图片 500 | * @param imgurl 图片地址 501 | * @param workid 作品ID 502 | * @param file 存储位置 503 | * @param x true 进行地址转换,false 不转换 504 | * @return 图片文件 Uri 505 | */ 506 | public Uri downloadImage(String imgurl, String workid, File file,boolean x){ 507 | String smail=imgurl; 508 | String ref="https://www.pixiv.net/member_illust.php?mode=medium&illust_id=" + workid; 509 | 510 | 511 | String big=smail; 512 | 513 | if(x) { 514 | pattern = Pattern.compile("/c/[0-9]+x[0-9]+/img-master"); 515 | matcher = pattern.matcher(imgurl); 516 | if(matcher.find()) { 517 | big = matcher.replaceFirst("/img-master"); 518 | } 519 | } 520 | 521 | Log.i(TAG, "downloadImage: "+big); 522 | HttpUtil download = new HttpUtil(big,null); 523 | download.checkURL(); 524 | 525 | if(download.downloadImg(ref,USER_AGENT,file)){ 526 | return Uri.parse("file://" + file.getAbsolutePath()); 527 | }else{ 528 | return null; 529 | } 530 | } 531 | 532 | 533 | 534 | 535 | } 536 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/PixivLike.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.support.v4.content.FileProvider; 7 | import android.util.Log; 8 | 9 | import com.google.android.apps.muzei.api.Artwork; 10 | import com.google.android.apps.muzei.api.RemoteMuzeiArtSource; 11 | 12 | import java.io.File; 13 | import java.util.List; 14 | import java.util.Random; 15 | 16 | import moe.democyann.pixivformuzeiplus.dbUtil.DbUtil; 17 | 18 | /** 19 | * Created by demo on 4/3/17. 20 | * pixiv 收藏夹作品获取类 21 | */ 22 | 23 | public class PixivLike { 24 | private static final String TAG = "Pixiv Like"; 25 | private static final int MINUTE=1000*60; 26 | 27 | private Context context; //应用程序上下文 28 | private Pixiv pixiv; //Pixiv操作类 29 | private long last; //上次列表更新时间 30 | private DbUtil db; //数据库操作类 31 | private ConfigManger conf; //配置管理器 32 | private File dir; //文件路径 33 | private static List list=null; //推荐列表 34 | 35 | private static String token=""; //登录Token 36 | private static Cookie cookie; //登录Cookie 37 | private static String userid=""; 38 | private int cont=0; 39 | 40 | 41 | private String error=""; 42 | 43 | public PixivLike(Context context,File dir){ 44 | this.context=context; 45 | this.dir=dir; 46 | pixiv=new Pixiv(); 47 | db= new DbUtil(context); 48 | conf=new ConfigManger(context); 49 | } 50 | 51 | public String getError() { 52 | return error; 53 | } 54 | 55 | public void listUpdate(){ 56 | try { 57 | last = Long.valueOf(db.getInfo("last")); 58 | }catch (Exception e){ 59 | e.printStackTrace(); 60 | } 61 | 62 | //列表为空,超时则重新获取 63 | if(list==null||list.size()<=0||(System.currentTimeMillis()-last)>(60*MINUTE)){ 64 | list=pixiv.getBooklist(); 65 | last=System.currentTimeMillis(); 66 | db.setInfo("last",String.valueOf(last)); 67 | Log.i(TAG, "listUpdate: Internet List Update"); 68 | db.setInfo("likeList",conf.listToString(list)); 69 | } 70 | } 71 | 72 | public Artwork getArtwork()throws RemoteMuzeiArtSource.RetryException { 73 | Artwork artwork; 74 | 75 | if("".equals(conf.getUsername()) ||"".equals(conf.getPassword())){ 76 | error="1100"; 77 | throw new RemoteMuzeiArtSource.RetryException(); 78 | } 79 | 80 | //如果没有Cookie,首先尝试从本地获取Cookie缓存 81 | if(pixiv.getCookie()==null || "".equals(pixiv.getCookie())){ 82 | String coostr = db.getInfo("cookie"); 83 | cookie=new Cookie(coostr); 84 | pixiv.setCookie(cookie); 85 | } 86 | 87 | //首先尝试本地获取Token,如没有则重新登录获取 88 | token=db.getInfo("token"); 89 | if("".equals(token) || !conf.getUsername().equals(db.getInfo("username")) ){ 90 | pixiv.setCookie(new Cookie()); 91 | token=pixiv.getToken(conf.getUsername(),conf.getPassword(),true); 92 | if(!"".equals(token)){ 93 | //登录成功后,写入本地Token和Cookie 94 | Log.i(TAG, "getArtwork: ==============="+pixiv.getCookie()+pixiv.getUserid()); 95 | db.setInfo("token",token); 96 | db.setInfo("cookie",pixiv.getCookie()); 97 | db.setInfo("username",conf.getUsername()); 98 | db.setInfo("userid",pixiv.getUserid()); 99 | db.setInfo("likeList",""); 100 | }else{ 101 | error=pixiv.getError(); 102 | 103 | //出现登录失败则清空所有登录记录 104 | db.setInfo("token",""); 105 | db.setInfo("cookie",""); 106 | db.setInfo("likeList",""); 107 | cookie=new Cookie(); 108 | pixiv.setCookie(cookie); 109 | throw new RemoteMuzeiArtSource.RetryException(); 110 | } 111 | } 112 | 113 | Log.i(TAG, "getArtwork: TOKEN:"+token); 114 | 115 | userid=db.getInfo("userid"); 116 | if(!"".equals(userid) && userid!=null){ 117 | Log.i(TAG, "getArtwork: USERID"+userid); 118 | pixiv.setUserid(userid); 119 | } 120 | //获取本地推荐列表 121 | 122 | list=conf.stringToList(db.getInfo("likeList")); 123 | 124 | listUpdate(); 125 | 126 | Log.i(TAG, "getArtwork: List SIZE:"+list.size()); 127 | 128 | if(list.size()==0){ 129 | 130 | Log.i(TAG, "getArtwork: TOKEN 过期重新获取"); 131 | token=pixiv.getToken(conf.getUsername(),conf.getPassword(),false); 132 | listUpdate(); 133 | 134 | if(list.size()==0){ 135 | Log.i(TAG, "getArtwork: TOKEN 过期重新获取(LOGIN)"); 136 | token=pixiv.getToken(conf.getUsername(),conf.getPassword(),true); 137 | listUpdate(); 138 | 139 | if(list.size()==0) { 140 | error = pixiv.getError(); 141 | throw new RemoteMuzeiArtSource.RetryException(); 142 | } 143 | } 144 | 145 | db.setInfo("token",token); 146 | db.setInfo("cookie",pixiv.getCookie()); 147 | db.setInfo("userid",pixiv.getUserid()); 148 | db.setInfo("likeList",conf.listToString(list)); 149 | 150 | Log.i(TAG, "getArtwork: "+conf.listToString(list)); 151 | 152 | // listUpdate(); 153 | } 154 | 155 | ImgInfo info; 156 | Random r = new Random(); 157 | while(true) { 158 | int i = r.nextInt(list.size()); 159 | 160 | info = pixiv.getIllInfo(String.valueOf(list.get(i))); 161 | 162 | //信息获取失败直接返回 163 | if (info == null) { 164 | error = pixiv.getError(); 165 | db.setInfo("likeList", ""); 166 | throw new RemoteMuzeiArtSource.RetryException(); 167 | } 168 | 169 | // if(conf.getIs_check_Tag()){ 170 | // if(TagFliter.checkTagAll(conf.getTage(),info.getTags())){ 171 | // continue; 172 | // } 173 | // } 174 | // 175 | // if(conf.getView()>info.getView()){ 176 | // continue; 177 | // } 178 | 179 | if(cont>=5){ 180 | break; 181 | } 182 | 183 | if(list.size()>50 && conf.getIs_autopx()){ 184 | Log.i(TAG, "getArtwork: =========PX======="); 185 | Log.i(TAG, "getArtwork: D:"+conf.getPx()); 186 | Log.i(TAG, "getArtwork: I:"+info.getPx()); 187 | double max=conf.getPx()+0.2; 188 | double min=conf.getPx()-0.1; 189 | if(info.getPx()>max || info.getPx()(120*MINUTE)){ 68 | rall=pixiv.getRalllist(); 69 | last=System.currentTimeMillis(); 70 | db.setInfo("last",String.valueOf(last)); 71 | 72 | Log.i(TAG, "getArtwork: Internet [+]"+rall.toString()); 73 | Log.i(TAG, "getArtwork: ERROR:" + pixiv.getError()); 74 | db.setInfo("rallList",rall.toString()); 75 | } 76 | } 77 | 78 | 79 | public Artwork getArtwork() throws RemoteMuzeiArtSource.RetryException { 80 | 81 | Artwork artwork = null; 82 | 83 | try { 84 | Log.i(TAG, "getArtwork: DB"+db.getInfo("rallList")); 85 | rall=new JSONArray(db.getInfo("rallList")); 86 | } catch (JSONException e) { 87 | rall=null; 88 | e.printStackTrace(); 89 | } 90 | 91 | listUpdate(); 92 | 93 | if(rall!=null&&rall.length()>0){ 94 | JSONObject o=null; 95 | String user_id = "1"; 96 | String img_id = "1"; 97 | String img_url = ""; 98 | String user_name; 99 | String illust_title; 100 | String tags = ""; 101 | 102 | Random r= new Random(); 103 | cont=0; 104 | while(true){ 105 | int i=r.nextInt(rall.length()); 106 | 107 | try { 108 | o = rall.getJSONObject(i); 109 | user_id = o.getString("user_id"); 110 | img_id = o.getString("illust_id"); 111 | img_url = o.getString("url"); 112 | user_name = o.getString("user_name"); 113 | illust_title = "TOP "+(i+1)+"\n"+o.getString("title"); 114 | tags = o.getString("tags"); 115 | } catch (JSONException e) { 116 | Log.e(TAG, e.toString(), e); 117 | error=pixiv.getError(); 118 | throw new RemoteMuzeiArtSource.RetryException(); 119 | } 120 | 121 | if(cont>=5){ 122 | break; 123 | } 124 | 125 | if(conf.getIs_check_Tag()){ 126 | if(TagFliter.checkTagAll(conf.getTage(),tags)){ 127 | cont++; 128 | continue; 129 | } 130 | } 131 | 132 | break; 133 | } 134 | 135 | 136 | // Random ra = new Random(); 137 | int rn=r.nextInt(1000); 138 | File file = new File(dir,user_id+img_id+rn); 139 | Uri fileUri=pixiv.downloadImage(img_url,img_id,file,true); 140 | // if(!mess.equals("")) user_name=mess; 141 | if(fileUri==null){ 142 | error="2001"; 143 | throw new RemoteMuzeiArtSource.RetryException(); 144 | } 145 | Uri f = FileProvider.getUriForFile(context, "moe.democyann.pixivformuzeiplus.fileprovider", file); 146 | // context.grantUriPermission("net.nurik.roman.muzei", f, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 147 | 148 | Log.i(TAG, "getArtwork: file"+f.toString()); 149 | Log.i(TAG, "getArtwork: uri"+fileUri.toString()); 150 | artwork= new Artwork.Builder() 151 | .title(illust_title) 152 | .byline(user_name) 153 | .imageUri(f) 154 | .token(user_id+img_id+rn) 155 | .viewIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.pixiv.net/member_illust.php?mode=medium&illust_id=" + img_id))) 156 | .build(); 157 | } 158 | return artwork; 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /app/src/main/java/moe/democyann/pixivformuzeiplus/util/PixivUser.java: -------------------------------------------------------------------------------- 1 | package moe.democyann.pixivformuzeiplus.util; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.support.v4.content.FileProvider; 7 | import android.util.Log; 8 | 9 | import com.google.android.apps.muzei.api.Artwork; 10 | import com.google.android.apps.muzei.api.RemoteMuzeiArtSource; 11 | 12 | import java.io.File; 13 | import java.util.List; 14 | import java.util.Random; 15 | 16 | import moe.democyann.pixivformuzeiplus.dbUtil.DbUtil; 17 | 18 | 19 | /** 20 | * Created by demo on 4/3/17. 21 | * Pixiv 为你推荐 作品获取类 22 | */ 23 | 24 | public class PixivUser { 25 | private static final String TAG = "Pixiv User"; 26 | private static final int MINUTE=1000*60; 27 | 28 | private Context context; //应用程序上下文 29 | private Pixiv pixiv; //Pixiv操作类 30 | private long last; //上次列表更新时间 31 | private DbUtil db; //数据库操作类 32 | private ConfigManger conf; //配置管理器 33 | private File dir; //文件路径 34 | private static List list=null; //推荐列表 35 | 36 | private static String token=""; //登录Token 37 | private static Cookie cookie; //登录Cookie 38 | private int cont=0; 39 | 40 | 41 | private String error=""; 42 | 43 | public PixivUser(Context context,File dir){ 44 | this.context=context; 45 | this.dir=dir; 46 | pixiv=new Pixiv(); 47 | db= new DbUtil(context); 48 | conf=new ConfigManger(context); 49 | } 50 | 51 | public String getError() { 52 | return error; 53 | } 54 | 55 | 56 | private void listUpdate(){ 57 | 58 | try { 59 | last = Long.valueOf(db.getInfo("last")); 60 | }catch (Exception e){ 61 | e.printStackTrace(); 62 | } 63 | 64 | //列表为空,超时则重新获取 65 | if(list==null||list.size()<=0||(System.currentTimeMillis()-last)>(60*MINUTE)){ 66 | list=pixiv.getRcomm(); 67 | last=System.currentTimeMillis(); 68 | db.setInfo("last",String.valueOf(last)); 69 | Log.i(TAG, "listUpdate: Internet List Update"); 70 | db.setInfo("commList",conf.listToString(list)); 71 | } 72 | } 73 | 74 | 75 | 76 | public Artwork getArtwork() throws RemoteMuzeiArtSource.RetryException{ 77 | 78 | Artwork artwork; 79 | 80 | if("".equals(conf.getUsername()) ||"".equals(conf.getPassword())){ 81 | error="1100"; 82 | throw new RemoteMuzeiArtSource.RetryException(); 83 | } 84 | 85 | 86 | //如果没有Cookie,首先尝试从本地获取Cookie缓存 87 | if(pixiv.getCookie()==null || "".equals(pixiv.getCookie())){ 88 | String coostr = db.getInfo("cookie"); 89 | cookie=new Cookie(coostr); 90 | pixiv.setCookie(cookie); 91 | } 92 | 93 | //首先尝试本地获取Token,如没有则重新登录获取 94 | token=db.getInfo("token"); 95 | if("".equals(token) || !conf.getUsername().equals(db.getInfo("username")) ){ 96 | pixiv.setCookie(new Cookie()); 97 | token=pixiv.getToken(conf.getUsername(),conf.getPassword(),true); 98 | if(!"".equals(token)){ 99 | //登录成功后,写入本地Token和Cookie 100 | db.setInfo("token",token); 101 | db.setInfo("cookie",pixiv.getCookie()); 102 | db.setInfo("username",conf.getUsername()); 103 | db.setInfo("commList",""); 104 | db.setInfo("userid",pixiv.getUserid()); 105 | }else{ 106 | error=pixiv.getError(); 107 | 108 | //出现登录失败则清空所有登录记录 109 | db.setInfo("token",""); 110 | db.setInfo("cookie",""); 111 | cookie=new Cookie(); 112 | pixiv.setCookie(cookie); 113 | throw new RemoteMuzeiArtSource.RetryException(); 114 | } 115 | } 116 | Log.i(TAG, "getArtwork: TOKEN:"+token); 117 | 118 | //获取本地推荐列表 119 | 120 | list=conf.stringToList(db.getInfo("commList")); 121 | 122 | listUpdate(); 123 | 124 | Log.i(TAG, "getArtwork: List SIZE:"+list.size()); 125 | 126 | if(list.size()==0){ 127 | 128 | Log.i(TAG, "getArtwork: TOKEN 过期重新获取"); 129 | token=pixiv.getToken(conf.getUsername(),conf.getPassword(),false); 130 | listUpdate(); 131 | 132 | if(list.size()==0){ 133 | Log.i(TAG, "getArtwork: TOKEN 过期重新获取(LOGIN)"); 134 | token=pixiv.getToken(conf.getUsername(),conf.getPassword(),true); 135 | listUpdate(); 136 | 137 | if(list.size()==0) { 138 | error = pixiv.getError(); 139 | throw new RemoteMuzeiArtSource.RetryException(); 140 | } 141 | } 142 | 143 | db.setInfo("token",token); 144 | db.setInfo("cookie",pixiv.getCookie()); 145 | db.setInfo("commList",conf.listToString(list)); 146 | 147 | // listUpdate(); 148 | } 149 | 150 | ImgInfo info; 151 | Random r = new Random(); 152 | cont=0; 153 | while(true){ 154 | 155 | int i = r.nextInt(list.size()); 156 | 157 | info = pixiv.getIllInfo(String.valueOf(list.get(i))); 158 | 159 | //信息获取失败直接返回 160 | if(info==null){ 161 | error=pixiv.getError(); 162 | db.setInfo("commList",""); 163 | throw new RemoteMuzeiArtSource.RetryException(); 164 | } 165 | 166 | if(cont>=5){ 167 | break; 168 | } 169 | 170 | if(conf.getIs_check_Tag()){ 171 | if(TagFliter.checkTagAll(conf.getTage(),info.getTags())){ 172 | cont++; 173 | continue; 174 | } 175 | } 176 | 177 | if(conf.getView()>info.getView()){ 178 | cont++; 179 | continue; 180 | } 181 | 182 | if(conf.getIs_autopx()){ 183 | Log.i(TAG, "getArtwork: =========PX======="); 184 | Log.i(TAG, "getArtwork: D:"+conf.getPx()); 185 | Log.i(TAG, "getArtwork: I:"+info.getPx()); 186 | double max=conf.getPx()+0.2; 187 | double min=conf.getPx()-0.1; 188 | if(info.getPx()>max || info.getPx() 2 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 62 | 63 |