V1.0.0(1)完成版

This commit is contained in:
lihongwei 2025-02-27 11:02:45 +08:00
parent f009d97e6f
commit 31bc40bdee
26 changed files with 163 additions and 127 deletions

BIN
app/CoolWallpaper.jks Normal file

Binary file not shown.

View File

@ -23,13 +23,13 @@
android:name=".activity.DetailActivity"
android:exported="false" />
<activity
android:name=".activity.WelcomeActivity"
android:name=".activity.MainActivity"
android:exported="false" />
<activity
android:name=".activity.SubListActivity"
android:exported="false" />
<activity
android:name=".activity.MainActivity"
android:name=".activity.WelcomeActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -6,6 +6,7 @@ import android.app.WallpaperManager;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@ -27,6 +28,7 @@ import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.wallpaper.coolwallpaper.R;
import com.wallpaper.coolwallpaper.callback.DownloadCallback;
import com.wallpaper.coolwallpaper.database.CoolEntity;
import com.wallpaper.coolwallpaper.databinding.ActivityDetailBinding;
import com.wallpaper.coolwallpaper.util.SetAndDownloadUtils;
@ -36,7 +38,7 @@ import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DetailActivity extends AppCompatActivity {
public class DetailActivity extends AppCompatActivity implements DownloadCallback {
private ActivityDetailBinding binding;
private String original;
private String source;
@ -71,15 +73,17 @@ public class DetailActivity extends AppCompatActivity {
source = coolEntity.getSource();
name = coolEntity.getName();
} else {
Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
finish();
}
setAndDownloadUtils = new SetAndDownloadUtils();
roomUtils = new RoomUtils(this);
handler = new Handler(Looper.getMainLooper());
executorService = Executors.newSingleThreadExecutor();
setAndDownloadUtils = new SetAndDownloadUtils( binding.progressBar, binding.view);
}
private void initEvent() {
@ -93,11 +97,11 @@ public class DetailActivity extends AppCompatActivity {
executorService.submit(() -> roomUtils.update(coolEntity));
});
binding.set.setOnClickListener(v -> showCustomBottomSheetDialog());
binding.set.setOnClickListener(v -> showCustomBottomSheet());
binding.downPicture.setOnClickListener(v -> {
binding.down.setOnClickListener(v -> {
showProgress();
setAndDownloadUtils.setAsWallpaper(DetailActivity.this, source);
setAndDownloadUtils.setAsWallpaper(this, source,this);
});
loadImage();
@ -109,67 +113,77 @@ public class DetailActivity extends AppCompatActivity {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setAndDownloadUtils.setAsWallpaper(this, source);
setAndDownloadUtils.setAsWallpaper(this, source,this);
} else {
Toast.makeText(this, "Write permission to external storage is denied", Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
}
private void showCustomBottomSheetDialog() {
private void showCustomBottomSheet() {
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
View dialogView = LayoutInflater.from(this).inflate(R.layout.detail_dialog, null);
View bottomSheetView = LayoutInflater.from(this).inflate(R.layout.detail_dialog, null);
dialogView.findViewById(R.id.both).setOnClickListener(v -> {
handleWallpaperAction(bitmap, WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
bottomSheetView.findViewById(R.id.both).setOnClickListener(v -> {
disableButtons(bottomSheetView);
applyWallpaper(bitmap, WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK, bottomSheetDialog);
bottomSheetDialog.dismiss();
});
dialogView.findViewById(R.id.lock).setOnClickListener(v -> {
handleWallpaperAction(bitmap, WallpaperManager.FLAG_LOCK);
bottomSheetView.findViewById(R.id.lock).setOnClickListener(v -> {
disableButtons(bottomSheetView);
applyWallpaper(bitmap, WallpaperManager.FLAG_LOCK, bottomSheetDialog);
bottomSheetDialog.dismiss();
});
dialogView.findViewById(R.id.desktop).setOnClickListener(v -> {
handleWallpaperAction(bitmap, WallpaperManager.FLAG_SYSTEM);
bottomSheetView.findViewById(R.id.desktop).setOnClickListener(v -> {
disableButtons(bottomSheetView);
applyWallpaper(bitmap, WallpaperManager.FLAG_SYSTEM, bottomSheetDialog);
bottomSheetDialog.dismiss();
});
bottomSheetDialog.setContentView(dialogView);
bottomSheetDialog.setContentView(bottomSheetView);
bottomSheetDialog.show();
}
private void handleWallpaperAction(Bitmap bitmap, int flag) {
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();
executorService.submit(() -> {
boolean isSuccess = false;
boolean success = false;
try {
isSuccess = setWallpaper(bitmap, flag);
success = setWallpaperImage(bitmap, flag);
} catch (Exception e) {
e.printStackTrace();
} finally {
boolean finalIsSuccess = isSuccess;
boolean finalSuccess = success;
handler.post(() -> {
hideProgress();
binding.set.setEnabled(true);
if (finalIsSuccess) {
Toast.makeText(getApplicationContext(), "Wallpaper setting is successful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Wallpaper setting failed", Toast.LENGTH_SHORT).show();
}
bottomSheetDialog.findViewById(R.id.both).setEnabled(true);
bottomSheetDialog.findViewById(R.id.lock).setEnabled(true);
bottomSheetDialog.findViewById(R.id.desktop).setEnabled(true);
String message = finalSuccess ? "Wallpaper set successfully" : "Failed to set wallpaper";
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
});
}
});
}
private boolean setWallpaper(Bitmap bitmap, int flag) {
WallpaperManager wm = WallpaperManager.getInstance(getApplicationContext());
private boolean setWallpaperImage(Bitmap bitmap, int flag) {
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
binding.imageView.setDrawingCacheEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
wm.setBitmap(bitmap, null, true, flag);
wallpaperManager.setBitmap(bitmap, null, true, flag);
} else {
wm.setBitmap(bitmap);
wallpaperManager.setBitmap(bitmap);
}
return true;
} catch (IOException e) {
@ -180,6 +194,7 @@ public class DetailActivity extends AppCompatActivity {
}
}
private void loadImage() {
Glide.with(this)
.asBitmap()
@ -223,15 +238,32 @@ public class DetailActivity extends AppCompatActivity {
}
private void hideProgress() {
if (binding != null) {
binding.progressBar.setVisibility(View.GONE);
binding.view.setVisibility(View.GONE);
}
}
private void showProgress() {
binding.progressBar.setVisibility(View.VISIBLE);
binding.view.setVisibility(View.VISIBLE);
}
@Override
public void onDownloadStart() {
showProgress();
}
@Override
public void onDownloadComplete(Uri uri) {
hideProgress();
}
@Override
public void onDownloadFailed() {
hideProgress();
}
@Override
protected void onDestroy() {
super.onDestroy();

View File

@ -82,7 +82,7 @@ public class MainActivity extends AppCompatActivity {
private void setTab(TabLayoutBinding tabLayoutBinding, int position) {
int iconResId = getIconResource(position, false);
int textColorResId = R.color.gray;
int textColorResId = R.color.black;
switch (position) {
case 0:

View File

@ -17,9 +17,8 @@ import com.wallpaper.coolwallpaper.R;
import com.wallpaper.coolwallpaper.databinding.ActivityWelcomeBinding;
public class WelcomeActivity extends AppCompatActivity {
private ActivityWelcomeBinding binding;
private static final long TOTAL_TIME = 1000;
private static final long TOTAL_TIME = 3000;
private CountDownTimer countDownTimer;
@Override

View File

@ -46,7 +46,7 @@ public class SubListAdapter extends RecyclerView.Adapter<SubListAdapter.ViewHold
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
CoolEntity coolEntity = categoryList.get(position);
holder.bind(coolEntity);
holder.bindItemData(coolEntity);
}
@Override
@ -54,41 +54,40 @@ public class SubListAdapter extends RecyclerView.Adapter<SubListAdapter.ViewHold
return categoryList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
static class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView itemImage;
private final TextView itemTitle;
ViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageview);
textView = itemView.findViewById(R.id.category_title);
ViewHolder(View view) {
super(view);
itemImage = view.findViewById(R.id.imageview);
itemTitle = view.findViewById(R.id.category_title);
}
void bind(CoolEntity coolEntity) {
String imageEntryOriginal = coolEntity.getOriginal();
void bindItemData(CoolEntity coolEntity) {
String imageUrl = coolEntity.getOriginal();
textView.setText(coolEntity.getName());
loadImage(imageEntryOriginal);
setClickListeners(coolEntity);
itemTitle.setText(coolEntity.getName());
loadImageFromUrl(imageUrl);
setItemClickListener(coolEntity);
}
private void loadImage(String imageEntryOriginal) {
Glide.with(context)
.load(imageEntryOriginal)
private void loadImageFromUrl(String imageUrl) {
Glide.with(itemImage.getContext())
.load(imageUrl)
.transform(new RoundedCorners(32))
.error(R.mipmap.placeholder)
.placeholder(R.mipmap.placeholder)
.into(imageView);
.into(itemImage);
}
private void setClickListeners(final CoolEntity coolEntity) {
imageView.setOnClickListener(v -> {
Intent intent = new Intent(activity, SubListActivity.class);
private void setItemClickListener(final CoolEntity coolEntity) {
itemImage.setOnClickListener(v -> {
Intent intent = new Intent(v.getContext(), SubListActivity.class);
intent.putExtra("name", coolEntity.getName());
activity.startActivity(intent);
v.getContext().startActivity(intent);
});
}
}
}

View File

@ -15,7 +15,6 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.wallpaper.coolwallpaper.R;
import com.wallpaper.coolwallpaper.activity.DetailActivity;
import com.wallpaper.coolwallpaper.activity.SubListActivity;
import com.wallpaper.coolwallpaper.database.AppDatabase;
import com.wallpaper.coolwallpaper.database.CoolEntity;
@ -50,7 +49,7 @@ public class WallpaperAdapter extends RecyclerView.Adapter<WallpaperAdapter.View
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
CoolEntity coolEntity = coolEntities.get(position);
holder.bind(coolEntity);
holder.bindData(coolEntity);
}
@Override
@ -59,63 +58,63 @@ public class WallpaperAdapter extends RecyclerView.Adapter<WallpaperAdapter.View
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
ImageView favoriteButton;
private final ImageView itemImageView;
private final ImageView likeButton;
ViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.image_view);
favoriteButton = itemView.findViewById(R.id.favorite);
ViewHolder(View view) {
super(view);
itemImageView = view.findViewById(R.id.image_view);
likeButton = view.findViewById(R.id.favorite);
}
void bind(CoolEntity coolEntity) {
String imageEntryOriginal = coolEntity.getOriginal();
void bindData(CoolEntity coolEntity) {
String imageUrl = coolEntity.getOriginal();
loadImage(imageEntryOriginal);
setFavoriteButton(coolEntity);
setClickListeners(coolEntity);
displayImage(imageUrl);
updateFavoriteButton(coolEntity);
setupItemClickListeners(coolEntity);
}
private void loadImage(String imageEntryOriginal) {
Glide.with(context)
.load(imageEntryOriginal)
private void displayImage(String imageUrl) {
Glide.with(itemImageView.getContext())
.load(imageUrl)
.transform(new RoundedCorners(32))
.error(R.mipmap.placeholder)
.placeholder(R.mipmap.placeholder)
.into(imageView);
.into(itemImageView);
}
private void setFavoriteButton(CoolEntity coolEntity) {
favoriteButton.setImageResource(coolEntity.getLike()
private void updateFavoriteButton(CoolEntity coolEntity) {
likeButton.setImageResource(coolEntity.getLike()
? R.drawable.like
: R.drawable.un_like);
}
private void setClickListeners(CoolEntity coolEntity) {
imageView.setOnClickListener(v -> {
Intent intent = new Intent(activity, DetailActivity.class);
private void setupItemClickListeners(CoolEntity coolEntity) {
itemImageView.setOnClickListener(v -> {
Intent intent = new Intent(v.getContext(), DetailActivity.class);
intent.putExtra("cool", coolEntity);
activity.startActivity(intent);
v.getContext().startActivity(intent);
});
favoriteButton.setOnClickListener(v -> toggleFavorite(coolEntity));
likeButton.setOnClickListener(v -> handleFavoriteToggle(coolEntity));
}
private void toggleFavorite(CoolEntity coolEntity) {
boolean newStatus = !coolEntity.getLike();
coolEntity.setLike(newStatus);
private void handleFavoriteToggle(CoolEntity coolEntity) {
boolean updatedStatus = !coolEntity.getLike();
coolEntity.setLike(updatedStatus);
updateImageInDatabase(coolEntity);
saveImageDataToDatabase(coolEntity);
notifyItemChanged(getAdapterPosition());
}
private void updateImageInDatabase(CoolEntity coolEntity) {
private void saveImageDataToDatabase(CoolEntity coolEntity) {
executor.execute(() -> {
AppDatabase.getInstance(context)
AppDatabase.getInstance(itemImageView.getContext())
.imageEntryDao()
.update(coolEntity);
});
}
}
}

View File

@ -0,0 +1,9 @@
package com.wallpaper.coolwallpaper.callback;
import android.net.Uri;
public interface DownloadCallback {
void onDownloadStart();
void onDownloadComplete(Uri uri);
void onDownloadFailed();
}

View File

@ -14,9 +14,12 @@ import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.wallpaper.coolwallpaper.callback.DownloadCallback;
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;
@ -26,18 +29,11 @@ import okhttp3.Response;
public class SetAndDownloadUtils {
public static final int REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 111;
private final ProgressBar progressBar;
private final ImageView overlayView;
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
public SetAndDownloadUtils(ProgressBar progressBar, ImageView overlayView) {
this.progressBar = progressBar;
this.overlayView = overlayView;
}
public void setAsWallpaper(Activity activity, String imageUrl) {
public void setAsWallpaper(Activity activity, String imageUrl,DownloadCallback callback) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
startDownload(activity, imageUrl);
startDownload(activity, imageUrl,callback);
} else {
if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
@ -45,32 +41,29 @@ public class SetAndDownloadUtils {
new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_WRITE_EXTERNAL_STORAGE);
} else {
startDownload(activity, imageUrl);
startDownload(activity, imageUrl,callback);
}
}
}
private void startDownload(Activity activity, String imageUrl) {
progressBar.setVisibility(View.VISIBLE);
overlayView.setVisibility(View.VISIBLE);
private void startDownload(Activity activity, String imageUrl, DownloadCallback callback) {
callback.onDownloadStart();
executorService.submit(() -> {
Uri uri = downloadImage(activity, imageUrl);
activity.runOnUiThread(() -> {
progressBar.setVisibility(View.GONE);
overlayView.setVisibility(View.GONE);
activity.runOnUiThread(() -> {
if (uri != null) {
Toast.makeText(activity, "Wallpaper downloaded", Toast.LENGTH_SHORT).show();
callback.onDownloadComplete(uri);
} else {
Toast.makeText(activity, "Wallpaper download failure", Toast.LENGTH_SHORT).show();
callback.onDownloadFailed();
}
});
});
}
private Uri downloadImage(Activity activity, String imageUrl) {
String displayName = System.currentTimeMillis() + ".jpg";
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");

View File

@ -5,5 +5,5 @@
android:viewportHeight="1024">
<path
android:pathData="M396.9,780.4a42.5,42.5 0,0 0,0 -60.2L231.4,554.7h647.3c23.5,0 42.7,-19.2 42.7,-42.7s-19.2,-42.7 -42.7,-42.7H231l165.5,-165.5a42.5,42.5 0,1 0,-60.2 -60.2l-238.5,238.5a42.5,42.5 0,0 0,0 60.2l238.9,238.1c16.2,16.6 43.5,16.6 60.2,0z"
android:fillColor="#858EBD"/>
android:fillColor="@color/white"/>
</vector>

View File

@ -18,15 +18,15 @@
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginTop="64dp"
android:src="@drawable/back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/like"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="32dp"
android:src="@drawable/un_like"
@ -34,7 +34,7 @@
app:layout_constraintEnd_toEndOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/down_picture"
android:id="@+id/down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
@ -53,18 +53,21 @@
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:layout_width="60dp"
android:layout_height="60dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:src="@drawable/download" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/set"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginBottom="32dp"
android:src="@drawable/apply"
android:padding="5dp"
android:background="@drawable/rounded_rectangle_gradient"
app:layout_constraintBottom_toTopOf="@+id/like"
app:layout_constraintEnd_toEndOf="@+id/like" />

View File

@ -5,6 +5,7 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/blue_black"
tools:context=".activity.WelcomeActivity">
<ImageView
@ -26,6 +27,7 @@
android:textSize="25sp"
android:textStyle="bold"
android:gravity="center"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image" />

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/rounded_rectangle_gradient">
<TextView

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 228 KiB

6
keystore.properties Normal file
View File

@ -0,0 +1,6 @@
app_name=Cool Wallpaper
package_name=com.wallpaper.coolwallpaper
keystoreFile=app/CoolWallpaper.jks
key_alias=CoolWallpaperkey0
key_store_password=CoolWallpaper
key_password=CoolWallpaper