V1.0.0(1)完成版
This commit is contained in:
parent
2b76217e86
commit
55b2e6d5fc
BIN
app/NatureWallpaper.jks
Normal file
BIN
app/NatureWallpaper.jks
Normal file
Binary file not shown.
14
app/proguard-rules.pro
vendored
14
app/proguard-rules.pro
vendored
@ -19,3 +19,17 @@
|
|||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-keepclassmembers class com.nature.wallpaper.naturewallpaper.MyApplication {
|
||||||
|
public static final java.lang.String DB_NAME;
|
||||||
|
public static final int DB_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@androidx.room.Query <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class com.nature.wallpaper.naturewallpaper.room.AppDatabase{ *; }
|
||||||
|
-keep class com.nature.wallpaper.naturewallpaper.room.NatureData { *; }
|
||||||
|
-keep class com.nature.wallpaper.naturewallpaper.room.NatureList { *; }
|
||||||
|
-keep class com.nature.wallpaper.naturewallpaper.room.NatureDataDao { *; }
|
||||||
@ -9,45 +9,71 @@ import com.nature.wallpaper.naturewallpaper.util.JsonParse;
|
|||||||
import com.nature.wallpaper.naturewallpaper.util.RoomUtils;
|
import com.nature.wallpaper.naturewallpaper.util.RoomUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
public class MyApplication extends Application {
|
public class MyApplication extends Application {
|
||||||
|
private static volatile MyApplication instance;
|
||||||
public static MyApplication application;
|
|
||||||
public static final int DB_VERSION = 1;
|
|
||||||
public static final String DB_NAME = "cool_database";
|
|
||||||
private static final String PREF_NAME = "app_preferences";
|
private static final String PREF_NAME = "app_preferences";
|
||||||
private static final String KEY_INIT = "isInit";
|
private static final String KEY_DB_INITIALIZED = "is_database_initialized";
|
||||||
|
private static final String JSON_FILE_NAME = "nature_wallpapers.json";
|
||||||
|
|
||||||
|
public static final int DB_VERSION = 1;
|
||||||
|
public static final String DB_NAME = "nature_database";
|
||||||
|
|
||||||
|
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
initializeInstance();
|
||||||
application = this;
|
initializeDatabaseIfNeeded();
|
||||||
|
|
||||||
SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
|
|
||||||
boolean isDatabaseInitialized = sharedPreferences.getBoolean(KEY_INIT, false);
|
|
||||||
|
|
||||||
if (!isDatabaseInitialized) {
|
|
||||||
initializeDatabase();
|
|
||||||
sharedPreferences.edit().putBoolean(KEY_INIT, true).apply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeInstance() {
|
||||||
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Context getContext() {
|
public static Context getContext() {
|
||||||
return application.getApplicationContext();
|
if (instance == null) {
|
||||||
|
throw new IllegalStateException("Application not initialized yet");
|
||||||
|
}
|
||||||
|
return instance.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeDatabase() {
|
private void initializeDatabaseIfNeeded() {
|
||||||
Executors.newSingleThreadExecutor().execute(() -> {
|
SharedPreferences prefs = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
|
||||||
List<NatureList> natureListList = getCategoryList();
|
if (!prefs.getBoolean(KEY_DB_INITIALIZED, false)) {
|
||||||
|
initializeDatabaseAsync();
|
||||||
|
markDatabaseAsInitialized(prefs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeDatabaseAsync() {
|
||||||
|
executor.execute(() -> {
|
||||||
|
List<NatureList> natureLists = loadCategoryList();
|
||||||
RoomUtils roomUtils = new RoomUtils(getContext());
|
RoomUtils roomUtils = new RoomUtils(getContext());
|
||||||
roomUtils.insertAllImages(natureListList);
|
roomUtils.insertAllImages(natureLists);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<NatureList> getCategoryList() {
|
private void markDatabaseAsInitialized(SharedPreferences prefs) {
|
||||||
return JsonParse.parseJson("nature_wallpapers.json");
|
prefs.edit()
|
||||||
|
.putBoolean(KEY_DB_INITIALIZED, true)
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<NatureList> loadCategoryList() {
|
||||||
|
return JsonParse.parseJson(JSON_FILE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTerminate() {
|
||||||
|
super.onTerminate();
|
||||||
|
shutdownExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shutdownExecutor() {
|
||||||
|
executor.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,88 +20,84 @@ import com.nature.wallpaper.naturewallpaper.databinding.TabLayoutBinding;
|
|||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
private ActivityMainBinding binding;
|
private ActivityMainBinding binding;
|
||||||
|
|
||||||
|
private static final int[] TAB_TITLES = {R.string.home, R.string.favorite};
|
||||||
|
private static final int[] TAB_ICONS_UNSELECTED = {R.drawable.un_home, R.drawable.un_favoriteslist};
|
||||||
|
private static final int[] TAB_ICONS_SELECTED = {R.drawable.home, R.drawable.favoriteslist};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
setupEdgeToEdge();
|
||||||
|
initializeBinding();
|
||||||
|
setupWindowInsets();
|
||||||
|
setupViewPager();
|
||||||
|
setupTabLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupEdgeToEdge() {
|
||||||
EdgeToEdge.enable(this);
|
EdgeToEdge.enable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeBinding() {
|
||||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
}
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
private void setupWindowInsets() {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.getRoot(), (v, insets) -> {
|
||||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
return insets;
|
return insets;
|
||||||
});
|
});
|
||||||
|
|
||||||
initData();
|
|
||||||
initEvent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initData() {
|
private void setupViewPager() {
|
||||||
MainAdapter adapter = new MainAdapter(this);
|
MainAdapter adapter = new MainAdapter(this);
|
||||||
binding.mainViewpager2.setAdapter(adapter);
|
binding.mainViewpager2.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initEvent() {
|
private void setupTabLayout() {
|
||||||
new TabLayoutMediator(binding.mainTabLayout, binding.mainViewpager2, (tab, position) -> {
|
new TabLayoutMediator(binding.mainTabLayout, binding.mainViewpager2,
|
||||||
TabLayoutBinding tabLayoutBinding = TabLayoutBinding.inflate(LayoutInflater.from(this));
|
this::configureTab).attach();
|
||||||
tab.setCustomView(tabLayoutBinding.getRoot());
|
|
||||||
setTab(tabLayoutBinding, position);
|
|
||||||
}).attach();
|
|
||||||
|
|
||||||
binding.mainTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
binding.mainTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onTabSelected(TabLayout.Tab tab) {
|
public void onTabSelected(TabLayout.Tab tab) {
|
||||||
updateTab(tab, true);
|
updateTabState(tab, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTabUnselected(TabLayout.Tab tab) {
|
public void onTabUnselected(TabLayout.Tab tab) {
|
||||||
updateTab(tab, false);
|
updateTabState(tab, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTabReselected(TabLayout.Tab tab) {
|
public void onTabReselected(TabLayout.Tab tab) {}
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTab(TabLayout.Tab tab, boolean isSelected) {
|
|
||||||
if (tab.getCustomView() != null) {
|
|
||||||
TabLayoutBinding mainCustomBinding = TabLayoutBinding.bind(tab.getCustomView());
|
|
||||||
|
|
||||||
int iconResId = getIconResource(tab.getPosition(), isSelected);
|
|
||||||
mainCustomBinding.image.setImageResource(iconResId);
|
|
||||||
|
|
||||||
int textColor = isSelected ? R.color.black : R.color.gray;
|
|
||||||
mainCustomBinding.text.setTextColor(ContextCompat.getColor(MainActivity.this, textColor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTab(TabLayoutBinding tabLayoutBinding, int position) {
|
private void configureTab(TabLayout.Tab tab, int position) {
|
||||||
int iconResId = getIconResource(position, false);
|
TabLayoutBinding tabBinding = TabLayoutBinding.inflate(LayoutInflater.from(this));
|
||||||
int textColorResId = R.color.gray;
|
tab.setCustomView(tabBinding.getRoot());
|
||||||
|
|
||||||
switch (position) {
|
boolean isFirstTab = position == 0;
|
||||||
case 0:
|
tabBinding.text.setText(TAB_TITLES[position]);
|
||||||
tabLayoutBinding.text.setText("Home");
|
tabBinding.image.setImageResource(isFirstTab ? TAB_ICONS_SELECTED[position] : TAB_ICONS_UNSELECTED[position]);
|
||||||
iconResId = R.drawable.home;
|
tabBinding.text.setTextColor(ContextCompat.getColor(this,
|
||||||
textColorResId = R.color.black;
|
isFirstTab ? R.color.black : R.color.gray));
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
tabLayoutBinding.text.setText("Favorite");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tabLayoutBinding.image.setImageResource(iconResId);
|
private void updateTabState(TabLayout.Tab tab, boolean isSelected) {
|
||||||
tabLayoutBinding.text.setTextColor(ContextCompat.getColor(this, textColorResId));
|
if (tab.getCustomView() == null) return;
|
||||||
}
|
|
||||||
|
|
||||||
private int getIconResource(int position, boolean isSelected) {
|
TabLayoutBinding tabBinding = TabLayoutBinding.bind(tab.getCustomView());
|
||||||
if (position == 1) {
|
int position = tab.getPosition();
|
||||||
return isSelected ? R.drawable.favoriteslist : R.drawable.un_favoriteslist;
|
|
||||||
}
|
tabBinding.image.setImageResource(isSelected
|
||||||
return isSelected ? R.drawable.home : R.drawable.un_home;
|
? TAB_ICONS_SELECTED[position]
|
||||||
|
: TAB_ICONS_UNSELECTED[position]);
|
||||||
|
tabBinding.text.setTextColor(ContextCompat.getColor(this,
|
||||||
|
isSelected ? R.color.black : R.color.gray));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -25,7 +25,6 @@ public class NatureListActivity extends AppCompatActivity {
|
|||||||
private ActivityNatureListBinding binding;
|
private ActivityNatureListBinding binding;
|
||||||
private WallpaperAdapter wallpaperAdapter;
|
private WallpaperAdapter wallpaperAdapter;
|
||||||
private RoomUtils roomUtils;
|
private RoomUtils roomUtils;
|
||||||
private NatureData coolEntity;
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,9 +46,9 @@ public class NatureListActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initData() {
|
private void initData() {
|
||||||
coolEntity = (NatureData) getIntent().getSerializableExtra("nature");
|
NatureData data = (NatureData) getIntent().getSerializableExtra("nature");
|
||||||
if (coolEntity != null) {
|
if (data != null) {
|
||||||
name = coolEntity.getName();
|
name = data.getName();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, "The picture does not exist", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "The picture does not exist", Toast.LENGTH_SHORT).show();
|
||||||
finish();
|
finish();
|
||||||
@ -62,8 +61,7 @@ public class NatureListActivity extends AppCompatActivity {
|
|||||||
wallpaperAdapter = new WallpaperAdapter(this, new ArrayList<>(),1);
|
wallpaperAdapter = new WallpaperAdapter(this, new ArrayList<>(),1);
|
||||||
binding.recyclerView.setAdapter(wallpaperAdapter);
|
binding.recyclerView.setAdapter(wallpaperAdapter);
|
||||||
|
|
||||||
ItemDecoration itemDecoration = new ItemDecoration(25, 15, 10);
|
binding.recyclerView.addItemDecoration(new ItemDecoration(25, 15, 10));
|
||||||
binding.recyclerView.addItemDecoration(itemDecoration);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,10 +70,10 @@ public class NatureListActivity extends AppCompatActivity {
|
|||||||
binding.back.setOnClickListener(v -> finish());
|
binding.back.setOnClickListener(v -> finish());
|
||||||
binding.text.setText(name);
|
binding.text.setText(name);
|
||||||
|
|
||||||
loadImage();
|
loadAllCategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadImage() {
|
private void loadAllCategory() {
|
||||||
roomUtils
|
roomUtils
|
||||||
.getAllCategory(name)
|
.getAllCategory(name)
|
||||||
.observe(this, new Observer<List<NatureData>>() {
|
.observe(this, new Observer<List<NatureData>>() {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package com.nature.wallpaper.naturewallpaper.activity;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CountDownTimer;
|
|
||||||
|
|
||||||
import androidx.activity.EdgeToEdge;
|
import androidx.activity.EdgeToEdge;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
@ -18,48 +17,70 @@ import com.nature.wallpaper.naturewallpaper.databinding.ActivityStartBinding;
|
|||||||
|
|
||||||
public class StartActivity extends AppCompatActivity {
|
public class StartActivity extends AppCompatActivity {
|
||||||
private ActivityStartBinding binding;
|
private ActivityStartBinding binding;
|
||||||
private static final long TOTAL_TIME = 1000;
|
private static final long TOTAL_TIME_MS = 1000;
|
||||||
private CountDownTimer countDownTimer;
|
private static final long COUNTDOWN_INTERVAL_MS = 100;
|
||||||
|
private android.os.CountDownTimer countDownTimer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
EdgeToEdge.enable(this);
|
setupEdgeToEdge();
|
||||||
|
initializeBinding();
|
||||||
|
setupWindowInsets();
|
||||||
|
loadSplashImage();
|
||||||
|
startCountdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupEdgeToEdge() {
|
||||||
|
EdgeToEdge.enable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeBinding() {
|
||||||
binding = ActivityStartBinding.inflate(getLayoutInflater());
|
binding = ActivityStartBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
}
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
private void setupWindowInsets() {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.getRoot(), (v, insets) -> {
|
||||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
return insets;
|
return insets;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSplashImage() {
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.load(R.mipmap.placeholder)
|
.load(R.mipmap.placeholder)
|
||||||
.transform(new CenterCrop(), new RoundedCorners(32))
|
.transform(new CenterCrop(), new RoundedCorners(32))
|
||||||
.into(binding.image);
|
.into(binding.image);
|
||||||
|
}
|
||||||
|
|
||||||
countDownTimer = new CountDownTimer(TOTAL_TIME, 100) {
|
private void startCountdown() {
|
||||||
|
countDownTimer = new android.os.CountDownTimer(TOTAL_TIME_MS, COUNTDOWN_INTERVAL_MS) {
|
||||||
@Override
|
@Override
|
||||||
public void onTick(long millisUntilFinished) {
|
public void onTick(long millisUntilFinished) {
|
||||||
int percentage = (int) (100 - (float) millisUntilFinished / TOTAL_TIME * 100);
|
updateProgress(millisUntilFinished);
|
||||||
binding.progressBar.setProgress(percentage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
startMain();
|
navigateToMain();
|
||||||
}
|
}
|
||||||
};
|
}.start();
|
||||||
|
|
||||||
countDownTimer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startMain() {
|
private void updateProgress(long millisUntilFinished) {
|
||||||
|
int progress = calculateProgress(millisUntilFinished);
|
||||||
|
binding.progressBar.setProgress(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateProgress(long millisUntilFinished) {
|
||||||
|
return (int) (100 - ((float) millisUntilFinished / TOTAL_TIME_MS * 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMain() {
|
||||||
binding.progressBar.setProgress(100);
|
binding.progressBar.setProgress(100);
|
||||||
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
Intent intent = new Intent(StartActivity.this, MainActivity.class);
|
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
@ -67,9 +88,14 @@ public class StartActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (countDownTimer != null) {
|
cleanupResources();
|
||||||
countDownTimer.cancel();
|
|
||||||
}
|
|
||||||
binding = null;
|
binding = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cleanupResources() {
|
||||||
|
if (countDownTimer != null) {
|
||||||
|
countDownTimer.cancel();
|
||||||
|
countDownTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,5 @@
|
|||||||
package com.nature.wallpaper.naturewallpaper.activity;
|
package com.nature.wallpaper.naturewallpaper.activity;
|
||||||
|
|
||||||
import static com.nature.wallpaper.naturewallpaper.util.SetAndDownloadUtils.REQUEST_CODE_WRITE_EXTERNAL_STORAGE;
|
|
||||||
|
|
||||||
import android.app.WallpaperManager;
|
import android.app.WallpaperManager;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
@ -19,7 +17,6 @@ import androidx.activity.EdgeToEdge;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.graphics.Insets;
|
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
@ -31,159 +28,168 @@ import com.nature.wallpaper.naturewallpaper.R;
|
|||||||
import com.nature.wallpaper.naturewallpaper.databinding.ActivityWallpaperBinding;
|
import com.nature.wallpaper.naturewallpaper.databinding.ActivityWallpaperBinding;
|
||||||
import com.nature.wallpaper.naturewallpaper.room.NatureData;
|
import com.nature.wallpaper.naturewallpaper.room.NatureData;
|
||||||
import com.nature.wallpaper.naturewallpaper.util.RoomUtils;
|
import com.nature.wallpaper.naturewallpaper.util.RoomUtils;
|
||||||
import com.nature.wallpaper.naturewallpaper.util.SetAndDownloadUtils;
|
import com.nature.wallpaper.naturewallpaper.util.SetDownloadUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
public class WallpaperActivity extends AppCompatActivity implements SetAndDownloadUtils.DownloadCallback {
|
public class WallpaperActivity extends AppCompatActivity implements SetDownloadUtil.DownloadCallback {
|
||||||
|
private static final int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = SetDownloadUtil.REQUEST_CODE_WRITE_EXTERNAL_STORAGE;
|
||||||
|
|
||||||
private ActivityWallpaperBinding binding;
|
private ActivityWallpaperBinding binding;
|
||||||
|
private NatureData data;
|
||||||
private String original;
|
private String original;
|
||||||
private String source;
|
private String source;
|
||||||
private NatureData coolEntity;
|
|
||||||
private RoomUtils roomUtils;
|
|
||||||
private String name;
|
private String name;
|
||||||
private Bitmap bitmap;
|
private Bitmap bitmap;
|
||||||
private SetAndDownloadUtils setAndDownloadUtils;
|
private SetDownloadUtil setDownloadUtil;
|
||||||
|
private RoomUtils roomUtils;
|
||||||
private ExecutorService executorService;
|
private ExecutorService executorService;
|
||||||
private Handler handler;
|
private Handler mainHandler;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
setupUI();
|
||||||
|
if (initializeData()) {
|
||||||
|
setupEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
EdgeToEdge.enable(this);
|
EdgeToEdge.enable(this);
|
||||||
binding = ActivityWallpaperBinding.inflate(getLayoutInflater());
|
binding = ActivityWallpaperBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
applyWindowInsets();
|
||||||
int navigationBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
}
|
||||||
v.setPadding(0, 0, 0, navigationBars);
|
|
||||||
|
private void applyWindowInsets() {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.getRoot(), (v, insets) -> {
|
||||||
|
int navigationBarsHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
||||||
|
v.setPadding(0, 0, 0, navigationBarsHeight);
|
||||||
return insets;
|
return insets;
|
||||||
});
|
});
|
||||||
|
|
||||||
initData();
|
|
||||||
initEvent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initData() {
|
private boolean initializeData() {
|
||||||
coolEntity = (NatureData) getIntent().getSerializableExtra("nature");
|
data = (NatureData) getIntent().getSerializableExtra("nature");
|
||||||
if (coolEntity != null) {
|
if (data == null) {
|
||||||
original = coolEntity.getOriginal();
|
showToast("Error loading wallpaper data");
|
||||||
source = coolEntity.getSource();
|
|
||||||
name = coolEntity.getName();
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
|
|
||||||
finish();
|
finish();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setAndDownloadUtils = new SetAndDownloadUtils();
|
original = data.getOriginal();
|
||||||
|
source = data.getSource();
|
||||||
|
name = data.getName();
|
||||||
|
|
||||||
|
setDownloadUtil = new SetDownloadUtil();
|
||||||
roomUtils = new RoomUtils(this);
|
roomUtils = new RoomUtils(this);
|
||||||
|
mainHandler = new Handler(Looper.getMainLooper());
|
||||||
handler = new Handler(Looper.getMainLooper());
|
|
||||||
executorService = Executors.newSingleThreadExecutor();
|
executorService = Executors.newSingleThreadExecutor();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initEvent() {
|
private void setupEvents() {
|
||||||
showProgress();
|
showProgress();
|
||||||
|
|
||||||
binding.backButton.setOnClickListener(v -> finish());
|
binding.backButton.setOnClickListener(v -> finish());
|
||||||
|
binding.likeButton.setOnClickListener(v -> toggleLikeStatus());
|
||||||
binding.likeButton.setOnClickListener(v -> {
|
binding.setWallpaperContainer.setOnClickListener(v -> showWallpaperOptions());
|
||||||
boolean newStatus = !coolEntity.getLike();
|
binding.downloadContainer.setOnClickListener(v -> downloadWallpaper());
|
||||||
coolEntity.setLike(newStatus);
|
|
||||||
executorService.submit(() -> roomUtils.update(coolEntity));
|
|
||||||
});
|
|
||||||
|
|
||||||
binding.setWallpaperContainer.setOnClickListener(v -> {
|
|
||||||
showCustomBottomSheet();
|
|
||||||
});
|
|
||||||
|
|
||||||
binding.downloadContainer.setOnClickListener(v -> {
|
|
||||||
showProgress();
|
|
||||||
setAndDownloadUtils.setAsWallpaper(WallpaperActivity.this, source, WallpaperActivity.this);
|
|
||||||
});
|
|
||||||
|
|
||||||
loadImage();
|
loadImage();
|
||||||
loadFavorite();
|
loadFavoriteStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void toggleLikeStatus() {
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
boolean newStatus = !data.getLike();
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
data.setLike(newStatus);
|
||||||
if (requestCode == REQUEST_CODE_WRITE_EXTERNAL_STORAGE) {
|
executorService.submit(() -> roomUtils.update(data));
|
||||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
updateLikeButton();
|
||||||
setAndDownloadUtils.setAsWallpaper(this, source, this);
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showCustomBottomSheet() {
|
private void downloadWallpaper() {
|
||||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
|
|
||||||
View bottomSheetView = LayoutInflater.from(this).inflate(R.layout.set_wallpaper_dialog, null);
|
|
||||||
|
|
||||||
bottomSheetView.findViewById(R.id.both).setOnClickListener(v -> {
|
|
||||||
disableButtons(bottomSheetView);
|
|
||||||
applyWallpaper(bitmap, WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK, bottomSheetDialog);
|
|
||||||
bottomSheetDialog.dismiss();
|
|
||||||
});
|
|
||||||
|
|
||||||
bottomSheetView.findViewById(R.id.lock).setOnClickListener(v -> {
|
|
||||||
disableButtons(bottomSheetView);
|
|
||||||
applyWallpaper(bitmap, WallpaperManager.FLAG_LOCK, bottomSheetDialog);
|
|
||||||
bottomSheetDialog.dismiss();
|
|
||||||
});
|
|
||||||
|
|
||||||
bottomSheetView.findViewById(R.id.desktop).setOnClickListener(v -> {
|
|
||||||
disableButtons(bottomSheetView);
|
|
||||||
applyWallpaper(bitmap, WallpaperManager.FLAG_SYSTEM, bottomSheetDialog);
|
|
||||||
bottomSheetDialog.dismiss();
|
|
||||||
});
|
|
||||||
|
|
||||||
bottomSheetDialog.setContentView(bottomSheetView);
|
|
||||||
bottomSheetDialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableButtons(View bottomSheetView) {
|
|
||||||
bottomSheetView.findViewById(R.id.both).setEnabled(false);
|
|
||||||
bottomSheetView.findViewById(R.id.lock).setEnabled(false);
|
|
||||||
bottomSheetView.findViewById(R.id.desktop).setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyWallpaper(Bitmap bitmap, int flag, BottomSheetDialog bottomSheetDialog) {
|
|
||||||
showProgress();
|
showProgress();
|
||||||
|
setDownloadUtil.setAsWallpaper(this, source, this);
|
||||||
|
}
|
||||||
|
|
||||||
executorService.submit(() -> {
|
private void showWallpaperOptions() {
|
||||||
boolean success = false;
|
BottomSheetDialog dialog = new BottomSheetDialog(this);
|
||||||
try {
|
View sheetView = LayoutInflater.from(this).inflate(R.layout.set_wallpaper_dialog, null);
|
||||||
success = setWallpaperImage(bitmap, flag);
|
|
||||||
} catch (Exception e) {
|
setupBottomSheetListeners(sheetView, dialog);
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
dialog.setContentView(sheetView);
|
||||||
boolean finalSuccess = success;
|
dialog.show();
|
||||||
handler.post(() -> {
|
}
|
||||||
|
|
||||||
|
private void setupBottomSheetListeners(View sheetView, BottomSheetDialog dialog) {
|
||||||
|
sheetView.findViewById(R.id.both).setOnClickListener(v ->
|
||||||
|
setWallpaperAndDismiss(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK, sheetView, dialog));
|
||||||
|
|
||||||
|
sheetView.findViewById(R.id.lock).setOnClickListener(v ->
|
||||||
|
setWallpaperAndDismiss(WallpaperManager.FLAG_LOCK, sheetView, dialog));
|
||||||
|
|
||||||
|
sheetView.findViewById(R.id.desktop).setOnClickListener(v ->
|
||||||
|
setWallpaperAndDismiss(WallpaperManager.FLAG_SYSTEM, sheetView, dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setWallpaperAndDismiss(int flag, View sheetView, BottomSheetDialog dialog) {
|
||||||
|
disableSheetButtons(sheetView);
|
||||||
|
applyWallpaperAsync(bitmap, flag, dialog);
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disableSheetButtons(View sheetView) {
|
||||||
|
setButtonEnabled(sheetView, R.id.both, false);
|
||||||
|
setButtonEnabled(sheetView, R.id.lock, false);
|
||||||
|
setButtonEnabled(sheetView, R.id.desktop, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyWallpaperAsync(Bitmap bitmap, int flag, BottomSheetDialog dialog) {
|
||||||
|
if (bitmap == null) {
|
||||||
|
showToast("No image available to set as wallpaper");
|
||||||
hideProgress();
|
hideProgress();
|
||||||
bottomSheetDialog.findViewById(R.id.both).setEnabled(true);
|
return;
|
||||||
bottomSheetDialog.findViewById(R.id.lock).setEnabled(true);
|
}
|
||||||
bottomSheetDialog.findViewById(R.id.desktop).setEnabled(true);
|
|
||||||
|
|
||||||
String message = finalSuccess ? "Wallpaper set successfully" : "Failed to set wallpaper";
|
showProgress();
|
||||||
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
|
executorService.submit(() -> {
|
||||||
|
boolean success = setWallpaperImage(bitmap, flag);
|
||||||
|
mainHandler.post(() -> {
|
||||||
|
hideProgress();
|
||||||
|
enableSheetButtons(dialog);
|
||||||
|
showToast(success ? "Wallpaper set successfully" : "Failed to set wallpaper");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
private void enableSheetButtons(BottomSheetDialog dialog) {
|
||||||
|
View sheetView = dialog.getCurrentFocus() != null ? dialog.getCurrentFocus().getRootView() : null;
|
||||||
|
if (sheetView != null) {
|
||||||
|
setButtonEnabled(sheetView, R.id.both, true);
|
||||||
|
setButtonEnabled(sheetView, R.id.lock, true);
|
||||||
|
setButtonEnabled(sheetView, R.id.desktop, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButtonEnabled(View view, int id, boolean enabled) {
|
||||||
|
View button = view.findViewById(id);
|
||||||
|
if (button != null) {
|
||||||
|
button.setEnabled(enabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setWallpaperImage(Bitmap bitmap, int flag) {
|
private boolean setWallpaperImage(Bitmap bitmap, int flag) {
|
||||||
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
|
WallpaperManager manager = WallpaperManager.getInstance(this);
|
||||||
try {
|
try {
|
||||||
binding.wallpaperImage.setDrawingCacheEnabled(true);
|
binding.wallpaperImage.setDrawingCacheEnabled(true);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
wallpaperManager.setBitmap(bitmap, null, true, flag);
|
manager.setBitmap(bitmap, null, true, flag);
|
||||||
} else {
|
} else {
|
||||||
wallpaperManager.setBitmap(bitmap);
|
manager.setBitmap(bitmap);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -194,7 +200,6 @@ public class WallpaperActivity extends AppCompatActivity implements SetAndDownlo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void loadImage() {
|
private void loadImage() {
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
@ -227,16 +232,39 @@ public class WallpaperActivity extends AppCompatActivity implements SetAndDownlo
|
|||||||
return ContextCompat.getDrawable(this, R.mipmap.placeholder);
|
return ContextCompat.getDrawable(this, R.mipmap.placeholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFavorite() {
|
private void loadFavoriteStatus() {
|
||||||
roomUtils.getWallpaperLike(source, name).observe(this, wallpaper -> setFavoriteButton());
|
roomUtils.getWallpaperLike(source, name).observe(this, wallpaper -> updateLikeButton());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFavoriteButton() {
|
private void updateLikeButton() {
|
||||||
binding.likeButton.setImageResource(
|
binding.likeButton.setImageResource(
|
||||||
coolEntity.getLike() ? R.drawable.like : R.drawable.un_like
|
data.getLike() ? R.drawable.like : R.drawable.un_like
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||||
|
@NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
if (requestCode == REQUEST_CODE_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) {
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
downloadWallpaper();
|
||||||
|
} else {
|
||||||
|
showToast("Permission denied");
|
||||||
|
hideProgress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showToast(String message) {
|
||||||
|
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showProgress() {
|
||||||
|
binding.progressBar.setVisibility(View.VISIBLE);
|
||||||
|
binding.view.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
private void hideProgress() {
|
private void hideProgress() {
|
||||||
if (binding != null) {
|
if (binding != null) {
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
binding.progressBar.setVisibility(View.GONE);
|
||||||
@ -244,11 +272,6 @@ public class WallpaperActivity extends AppCompatActivity implements SetAndDownlo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showProgress() {
|
|
||||||
binding.progressBar.setVisibility(View.VISIBLE);
|
|
||||||
binding.view.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadStart() {
|
public void onDownloadStart() {
|
||||||
showProgress();
|
showProgress();
|
||||||
@ -257,22 +280,31 @@ public class WallpaperActivity extends AppCompatActivity implements SetAndDownlo
|
|||||||
@Override
|
@Override
|
||||||
public void onDownloadComplete(Uri uri) {
|
public void onDownloadComplete(Uri uri) {
|
||||||
hideProgress();
|
hideProgress();
|
||||||
|
showToast("Download completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDownloadFailed() {
|
public void onDownloadFailed() {
|
||||||
hideProgress();
|
hideProgress();
|
||||||
|
showToast("Download failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (handler != null) {
|
cleanupResources();
|
||||||
handler.removeCallbacksAndMessages(null);
|
|
||||||
}
|
}
|
||||||
if (executorService != null) {
|
|
||||||
|
private void cleanupResources() {
|
||||||
|
if (mainHandler != null) {
|
||||||
|
mainHandler.removeCallbacksAndMessages(null);
|
||||||
|
}
|
||||||
|
if (executorService != null && !executorService.isShutdown()) {
|
||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
}
|
}
|
||||||
|
if (setDownloadUtil != null) {
|
||||||
|
setDownloadUtil.shutdown();
|
||||||
|
}
|
||||||
binding = null;
|
binding = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ public class WallpaperAdapter extends RecyclerView.Adapter<WallpaperAdapter.View
|
|||||||
private List<NatureData> natureDataList;
|
private List<NatureData> natureDataList;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private final int displayMode; // 0: 显示标题跳转NatureList, 其他: 隐藏标题跳转Wallpaper
|
private final int displayMode;
|
||||||
private static final int MODE_WITH_TITLE = 0;
|
private static final int MODE_WITH_TITLE = 0;
|
||||||
|
|
||||||
public WallpaperAdapter(Context context, List<NatureData> natureDataList, int displayMode) {
|
public WallpaperAdapter(Context context, List<NatureData> natureDataList, int displayMode) {
|
||||||
|
|||||||
@ -43,18 +43,17 @@ public class FavoriteFragment extends Fragment {
|
|||||||
adapter = new WallpaperAdapter(requireContext(), new ArrayList<>(),1);
|
adapter = new WallpaperAdapter(requireContext(), new ArrayList<>(),1);
|
||||||
binding.recyclerView.setAdapter(adapter);
|
binding.recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
ItemDecoration itemDecoration = new ItemDecoration(25, 15, 10);
|
binding.recyclerView.addItemDecoration(new ItemDecoration(25, 15, 10));
|
||||||
binding.recyclerView.addItemDecoration(itemDecoration);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initEvent() {
|
private void initEvent() {
|
||||||
loadCategoryImage();
|
loadAllFavoriteList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCategoryImage() {
|
private void loadAllFavoriteList() {
|
||||||
roomUtils
|
roomUtils
|
||||||
.getAllFavoriteList()
|
.getAllFavorite()
|
||||||
.observe(getViewLifecycleOwner(), new Observer<List<NatureData>>() {
|
.observe(getViewLifecycleOwner(), new Observer<List<NatureData>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<NatureData> natureDataList) {
|
public void onChanged(List<NatureData> natureDataList) {
|
||||||
|
|||||||
@ -10,9 +10,7 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.nature.wallpaper.naturewallpaper.R;
|
|
||||||
import com.nature.wallpaper.naturewallpaper.adapter.WallpaperAdapter;
|
import com.nature.wallpaper.naturewallpaper.adapter.WallpaperAdapter;
|
||||||
import com.nature.wallpaper.naturewallpaper.databinding.FragmentFavoriteBinding;
|
|
||||||
import com.nature.wallpaper.naturewallpaper.databinding.FragmentNatureBinding;
|
import com.nature.wallpaper.naturewallpaper.databinding.FragmentNatureBinding;
|
||||||
import com.nature.wallpaper.naturewallpaper.room.NatureData;
|
import com.nature.wallpaper.naturewallpaper.room.NatureData;
|
||||||
import com.nature.wallpaper.naturewallpaper.util.ItemDecoration;
|
import com.nature.wallpaper.naturewallpaper.util.ItemDecoration;
|
||||||
@ -45,18 +43,16 @@ public class NatureFragment extends Fragment {
|
|||||||
adapter = new WallpaperAdapter(requireContext(), new ArrayList<>(), 0);
|
adapter = new WallpaperAdapter(requireContext(), new ArrayList<>(), 0);
|
||||||
binding.recyclerView.setAdapter(adapter);
|
binding.recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
ItemDecoration itemDecoration = new ItemDecoration(25, 15, 10);
|
binding.recyclerView.addItemDecoration(new ItemDecoration(25, 15, 10));
|
||||||
binding.recyclerView.addItemDecoration(itemDecoration);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initEvent() {
|
private void initEvent() {
|
||||||
loadCategoryImage();
|
loadCategoryFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCategoryImage() {
|
private void loadCategoryFirst() {
|
||||||
roomUtils
|
roomUtils
|
||||||
.getCategoryFirst()
|
.getFirstCategory()
|
||||||
.observe(getViewLifecycleOwner(), new Observer<List<NatureData>>() {
|
.observe(getViewLifecycleOwner(), new Observer<List<NatureData>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(List<NatureData> natureDataList) {
|
public void onChanged(List<NatureData> natureDataList) {
|
||||||
|
|||||||
@ -19,12 +19,12 @@ public interface NatureDataDao {
|
|||||||
@Query("SELECT * FROM NatureData WHERE isLike = 1 ")
|
@Query("SELECT * FROM NatureData WHERE isLike = 1 ")
|
||||||
LiveData<List<NatureData>> getAllFavoriteLive();
|
LiveData<List<NatureData>> getAllFavoriteLive();
|
||||||
|
|
||||||
@Query("SELECT * FROM NatureData WHERE id IN (SELECT MIN(id) FROM NatureData GROUP BY name)")
|
@Query("SELECT * FROM NatureData WHERE id IN (SELECT MAX(id) FROM NatureData GROUP BY name) ORDER BY id DESC")
|
||||||
LiveData<List<NatureData>> getFirstRecordOfEachName();
|
LiveData<List<NatureData>> getFirstCategoryByFirst();
|
||||||
|
|
||||||
@Query("SELECT * FROM NatureData WHERE name = :name")
|
@Query("SELECT * FROM NatureData WHERE name = :name ORDER BY id DESC")
|
||||||
LiveData<List<NatureData>> getAllCategoryLive(String name);
|
LiveData<List<NatureData>> getAllCategoryByName(String name);
|
||||||
|
|
||||||
@Query("SELECT isLIKE FROM NatureData WHERE source = :source AND name = :name")
|
@Query("SELECT isLIKE FROM NatureData WHERE source = :source AND name = :name ORDER BY id DESC")
|
||||||
LiveData<Boolean> getWallpaperLike(String source, String name);
|
LiveData<Boolean> getWallpaperLikeBySourceAndName(String source, String name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
package com.nature.wallpaper.naturewallpaper.util;
|
package com.nature.wallpaper.naturewallpaper.util;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.nature.wallpaper.naturewallpaper.MyApplication;
|
import com.nature.wallpaper.naturewallpaper.MyApplication;
|
||||||
import com.nature.wallpaper.naturewallpaper.room.NatureData;
|
import com.nature.wallpaper.naturewallpaper.room.NatureData;
|
||||||
import com.nature.wallpaper.naturewallpaper.room.NatureList;
|
import com.nature.wallpaper.naturewallpaper.room.NatureList;
|
||||||
@ -13,58 +11,70 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class JsonParse {
|
public class JsonParse {
|
||||||
|
private static String loadJsonFromAsset(String fileName) throws IOException {
|
||||||
private static String loadJSONFromAsset(String fileName) {
|
|
||||||
StringBuilder jsonString = new StringBuilder();
|
StringBuilder jsonString = new StringBuilder();
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(MyApplication.getContext().getAssets().open(fileName)))) {
|
try (BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(MyApplication.getContext().getAssets().open(fileName)))) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
jsonString.append(line);
|
jsonString.append(line);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
Log.d("JsonParse", "Loaded JSON: " + jsonString.toString());
|
|
||||||
return jsonString.toString();
|
return jsonString.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<NatureList> parseJson(String fileName) {
|
public static List<NatureList> parseJson(String fileName) {
|
||||||
List<NatureList> categoryList = new ArrayList<>();
|
|
||||||
try {
|
try {
|
||||||
String jsonString = loadJSONFromAsset(fileName);
|
String jsonString = loadJsonFromAsset(fileName);
|
||||||
if (jsonString.isEmpty()) {
|
if (jsonString.isEmpty()) {
|
||||||
throw new IllegalArgumentException("JSON file is empty or invalid.");
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return parseJsonArray(new JSONArray(jsonString));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray jsonArray = new JSONArray(jsonString);
|
private static List<NatureList> parseJsonArray(JSONArray jsonArray) throws org.json.JSONException {
|
||||||
|
List<NatureList> categoryList = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
JSONObject categoryObject = jsonArray.getJSONObject(i);
|
JSONObject categoryObject = jsonArray.getJSONObject(i);
|
||||||
String name = categoryObject.getString("name");
|
String categoryName = categoryObject.getString("name");
|
||||||
|
JSONArray dataArray = categoryObject.getJSONArray("data");
|
||||||
|
|
||||||
JSONArray listArray = categoryObject.getJSONArray("data");
|
List<NatureData> natureDataList = parseNatureDataList(dataArray, categoryName);
|
||||||
List<NatureData> natureDataList = new ArrayList<>();
|
categoryList.add(new NatureList(categoryName, natureDataList));
|
||||||
|
|
||||||
for (int j = 0; j < listArray.length(); j++) {
|
|
||||||
JSONObject imageObject = listArray.getJSONObject(j);
|
|
||||||
String original = imageObject.getString("original");
|
|
||||||
String previewThumb = imageObject.getString("previewThumb");
|
|
||||||
String source = imageObject.getString("source");
|
|
||||||
|
|
||||||
natureDataList.add(new NatureData(original, previewThumb, source, name, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryList.add(new NatureList(name, natureDataList));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return categoryList;
|
return categoryList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<NatureData> parseNatureDataList(JSONArray dataArray, String categoryName)
|
||||||
|
throws org.json.JSONException {
|
||||||
|
List<NatureData> natureDataList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < dataArray.length(); j++) {
|
||||||
|
JSONObject imageObject = dataArray.getJSONObject(j);
|
||||||
|
String original = getStringSafe(imageObject, "original");
|
||||||
|
String previewThumb = getStringSafe(imageObject, "previewThumb");
|
||||||
|
String source = getStringSafe(imageObject, "source");
|
||||||
|
|
||||||
|
natureDataList.add(new NatureData(original, previewThumb, source, categoryName, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
return natureDataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getStringSafe(JSONObject jsonObject, String key) {
|
||||||
|
try {
|
||||||
|
return jsonObject.getString(key);
|
||||||
|
} catch (org.json.JSONException e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -22,29 +22,29 @@ public class RoomUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void insertAllImages(List<NatureList> categoryList) {
|
public void insertAllImages(List<NatureList> categoryList) {
|
||||||
List<NatureData> coolEntities = new ArrayList<>();
|
List<NatureData> dataList = new ArrayList<>();
|
||||||
|
|
||||||
for (NatureList category : categoryList) {
|
for (NatureList category : categoryList) {
|
||||||
coolEntities.addAll(category.getList());
|
dataList.addAll(category.getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
natureDataDao.insertAll(coolEntities);
|
natureDataDao.insertAll(dataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<NatureData>> getAllFavoriteList() {
|
public LiveData<List<NatureData>> getAllFavorite() {
|
||||||
return natureDataDao.getAllFavoriteLive();
|
return natureDataDao.getAllFavoriteLive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<NatureData>> getCategoryFirst() {
|
public LiveData<List<NatureData>> getFirstCategory() {
|
||||||
return natureDataDao.getFirstRecordOfEachName();
|
return natureDataDao.getFirstCategoryByFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<NatureData>> getAllCategory(String name) {
|
public LiveData<List<NatureData>> getAllCategory(String name) {
|
||||||
return natureDataDao.getAllCategoryLive(name);
|
return natureDataDao.getAllCategoryByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Boolean> getWallpaperLike(String source, String name) {
|
public LiveData<Boolean> getWallpaperLike(String source, String name) {
|
||||||
return natureDataDao.getWallpaperLike(source, name);
|
return natureDataDao.getWallpaperLikeBySourceAndName(source, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(NatureData imageEntry) {
|
public void update(NatureData imageEntry) {
|
||||||
|
|||||||
@ -1,114 +0,0 @@
|
|||||||
package com.nature.wallpaper.naturewallpaper.util;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
|
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class SetAndDownloadUtils {
|
|
||||||
public static final int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 111;
|
|
||||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
|
||||||
|
|
||||||
public void setAsWallpaper(Activity activity, String imageUrl,DownloadCallback callback) {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
||||||
startDownload(activity, imageUrl,callback);
|
|
||||||
} else {
|
|
||||||
if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
|
||||||
ActivityCompat.requestPermissions(activity,
|
|
||||||
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
REQUEST_CODE_WRITE_EXTERNAL_STORAGE);
|
|
||||||
} else {
|
|
||||||
startDownload(activity, imageUrl,callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startDownload(Activity activity, String imageUrl, DownloadCallback callback) {
|
|
||||||
callback.onDownloadStart();
|
|
||||||
|
|
||||||
executorService.submit(() -> {
|
|
||||||
Uri uri = downloadImage(activity, imageUrl);
|
|
||||||
|
|
||||||
activity.runOnUiThread(() -> {
|
|
||||||
if (uri != null) {
|
|
||||||
callback.onDownloadComplete(uri);
|
|
||||||
} else {
|
|
||||||
callback.onDownloadFailed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Uri downloadImage(Activity activity, String imageUrl) {
|
|
||||||
String displayName = UUID.randomUUID().toString() + ".jpg";
|
|
||||||
ContentValues contentValues = new ContentValues();
|
|
||||||
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, displayName);
|
|
||||||
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
||||||
contentValues.put(MediaStore.Images.Media.IS_PENDING, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri collectionUri;
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
||||||
collectionUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
|
||||||
} else {
|
|
||||||
collectionUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri imageUri = activity.getContentResolver().insert(collectionUri, contentValues);
|
|
||||||
|
|
||||||
if (imageUri != null) {
|
|
||||||
try {
|
|
||||||
OkHttpClient client = new OkHttpClient();
|
|
||||||
Request request = new Request.Builder().url(imageUrl).build();
|
|
||||||
Response response = client.newCall(request).execute();
|
|
||||||
if (response.isSuccessful()) {
|
|
||||||
InputStream inputStream = response.body().byteStream();
|
|
||||||
try (OutputStream outputStream = activity.getContentResolver().openOutputStream(imageUri)) {
|
|
||||||
if (outputStream != null) {
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
||||||
outputStream.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
||||||
contentValues.clear();
|
|
||||||
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0);
|
|
||||||
activity.getContentResolver().update(imageUri, contentValues, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return imageUri;
|
|
||||||
} catch (IOException e) {
|
|
||||||
activity.getContentResolver().delete(imageUri, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface DownloadCallback {
|
|
||||||
void onDownloadStart();
|
|
||||||
void onDownloadComplete(Uri uri);
|
|
||||||
void onDownloadFailed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,174 @@
|
|||||||
|
package com.nature.wallpaper.naturewallpaper.util;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class SetDownloadUtil {
|
||||||
|
public static final int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 111;
|
||||||
|
private static final int BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
|
private final ExecutorService executorService;
|
||||||
|
private final OkHttpClient httpClient;
|
||||||
|
|
||||||
|
public SetDownloadUtil() {
|
||||||
|
this.executorService = Executors.newSingleThreadExecutor();
|
||||||
|
this.httpClient = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAsWallpaper(Activity activity, String imageUrl, DownloadCallback callback) {
|
||||||
|
if (activity == null || imageUrl == null || callback == null) {
|
||||||
|
if (callback != null) callback.onDownloadFailed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
downloadWallpaperAsync(activity, imageUrl, callback);
|
||||||
|
} else if (hasWritePermission(activity)) {
|
||||||
|
downloadWallpaperAsync(activity, imageUrl, callback);
|
||||||
|
} else {
|
||||||
|
requestWritePermission(activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasWritePermission(Activity activity) {
|
||||||
|
return ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
== PackageManager.PERMISSION_GRANTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestWritePermission(Activity activity) {
|
||||||
|
ActivityCompat.requestPermissions(activity,
|
||||||
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
REQUEST_CODE_WRITE_EXTERNAL_STORAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadWallpaperAsync(Activity activity, String imageUrl, DownloadCallback callback) {
|
||||||
|
callback.onDownloadStart();
|
||||||
|
|
||||||
|
executorService.submit(() -> {
|
||||||
|
try {
|
||||||
|
Uri imageUri = downloadImage(activity, imageUrl);
|
||||||
|
notifyResultOnMainThread(activity, callback, imageUri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
notifyFailureOnMainThread(activity, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uri downloadImage(Activity activity, String imageUrl) throws IOException {
|
||||||
|
String fileName = generateUniqueFileName();
|
||||||
|
Uri imageUri = createMediaStoreEntry(activity, fileName);
|
||||||
|
|
||||||
|
if (imageUri == null) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
downloadToMediaStore(activity, imageUrl, imageUri);
|
||||||
|
markAsComplete(activity, imageUri);
|
||||||
|
return imageUri;
|
||||||
|
} catch (IOException e) {
|
||||||
|
cleanupFailedDownload(activity, imageUri);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateUniqueFileName() {
|
||||||
|
return UUID.randomUUID().toString() + ".jpg";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uri createMediaStoreEntry(Activity activity, String fileName) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
|
||||||
|
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
values.put(MediaStore.Images.Media.IS_PENDING, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri collectionUri = getMediaStoreCollectionUri();
|
||||||
|
return activity.getContentResolver().insert(collectionUri, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uri getMediaStoreCollectionUri() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
return MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
||||||
|
}
|
||||||
|
return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadToMediaStore(Activity activity, String imageUrl, Uri imageUri) throws IOException {
|
||||||
|
Request request = new Request.Builder().url(imageUrl).build();
|
||||||
|
try (Response response = httpClient.newCall(request).execute();
|
||||||
|
InputStream inputStream = response.body().byteStream();
|
||||||
|
OutputStream outputStream = activity.getContentResolver().openOutputStream(imageUri)) {
|
||||||
|
|
||||||
|
if (!response.isSuccessful() || outputStream == null) {
|
||||||
|
throw new IOException("Download failed: " + response.code());
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] buffer = new byte[BUFFER_SIZE];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void markAsComplete(Activity activity, Uri imageUri) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(MediaStore.Images.Media.IS_PENDING, 0);
|
||||||
|
activity.getContentResolver().update(imageUri, values, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanupFailedDownload(Activity activity, Uri imageUri) {
|
||||||
|
activity.getContentResolver().delete(imageUri, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyResultOnMainThread(Activity activity, DownloadCallback callback, Uri imageUri) {
|
||||||
|
activity.runOnUiThread(() -> {
|
||||||
|
if (imageUri != null) {
|
||||||
|
callback.onDownloadComplete(imageUri);
|
||||||
|
} else {
|
||||||
|
callback.onDownloadFailed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyFailureOnMainThread(Activity activity, DownloadCallback callback) {
|
||||||
|
activity.runOnUiThread(callback::onDownloadFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
if (!executorService.isShutdown()) {
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DownloadCallback {
|
||||||
|
void onDownloadStart();
|
||||||
|
void onDownloadComplete(Uri uri);
|
||||||
|
void onDownloadFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,7 +27,7 @@
|
|||||||
android:textSize="25sp"
|
android:textSize="25sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/black"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/image" />
|
app:layout_constraintTop_toBottomOf="@+id/image" />
|
||||||
|
|||||||
@ -13,18 +13,15 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="4dp">
|
android:padding="4dp">
|
||||||
|
|
||||||
<!-- 图片 -->
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image_view"
|
android:id="@+id/image_view"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="250dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
app:layout_constraintDimensionRatio="16:9"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<!-- 标题 -->
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title_text"
|
android:id="@+id/title_text"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@ -40,13 +37,12 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<!-- 收藏按钮 -->
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/favorite"
|
android:id="@+id/favorite"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/un_like"
|
android:src="@drawable/un_like"
|
||||||
android:layout_margin="4dp"
|
android:layout_margin="8dp"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
android:layout_width="250dp"
|
android:layout_width="250dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:id="@+id/set_wallpaper_dialog"
|
||||||
android:background="@drawable/rounded_control_bar_background">
|
android:background="@drawable/rounded_control_bar_background">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@ -2,4 +2,6 @@
|
|||||||
<string name="app_name">Nature Wallpaper</string>
|
<string name="app_name">Nature Wallpaper</string>
|
||||||
<!-- TODO: Remove or change this placeholder text -->
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
|
<string name="home">Home</string>
|
||||||
|
<string name="favorite">Favorite</string>
|
||||||
</resources>
|
</resources>
|
||||||
6
keystore.properties
Normal file
6
keystore.properties
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
app_name=Nature Wallpaper
|
||||||
|
package_name=com.nature.wallpaper.naturewallpaper
|
||||||
|
keystoreFile=app/NatureWallpaper.jks
|
||||||
|
key_alias=NatureWallpaperkey0
|
||||||
|
key_store_password=NatureWallpaper
|
||||||
|
key_password=NatureWallpaper
|
||||||
Loading…
Reference in New Issue
Block a user