album icons: improved app icon fetch, added download icon
This commit is contained in:
parent
a83b9200e2
commit
d460f7c8ef
9 changed files with 266 additions and 34 deletions
|
@ -2,10 +2,17 @@ package deckers.thibault.aves.channelhandlers;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
|
||||||
|
@ -21,6 +28,20 @@ public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
|
||||||
@Override
|
@Override
|
||||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
|
case "getAppNames": {
|
||||||
|
result.success(getAppNames());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "getAppIcon": {
|
||||||
|
String packageName = call.argument("packageName");
|
||||||
|
Integer size = call.argument("size");
|
||||||
|
if (packageName == null || size == null) {
|
||||||
|
result.error("getAppIcon-args", "failed because of missing arguments", null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getAppIcon(packageName, size, result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "edit": {
|
case "edit": {
|
||||||
String title = call.argument("title");
|
String title = call.argument("title");
|
||||||
Uri uri = Uri.parse(call.argument("uri"));
|
Uri uri = Uri.parse(call.argument("uri"));
|
||||||
|
@ -65,6 +86,28 @@ public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getAppNames() {
|
||||||
|
Map<String, String> nameMap = new HashMap<>();
|
||||||
|
Intent intent = new Intent(Intent.ACTION_MAIN, null);
|
||||||
|
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||||
|
PackageManager packageManager = context.getPackageManager();
|
||||||
|
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
|
||||||
|
for (ResolveInfo resolveInfo : resolveInfoList) {
|
||||||
|
ApplicationInfo applicationInfo = resolveInfo.activityInfo.applicationInfo;
|
||||||
|
boolean isSystemPackage = (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
|
||||||
|
if (!isSystemPackage) {
|
||||||
|
String appName = String.valueOf(packageManager.getApplicationLabel(applicationInfo));
|
||||||
|
nameMap.put(appName, applicationInfo.packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getAppIcon(String packageName, int size, MethodChannel.Result result) {
|
||||||
|
new AppIconDecodeTask().execute(new AppIconDecodeTask.Params(context, packageName, size, result));
|
||||||
|
}
|
||||||
|
|
||||||
private void edit(String title, Uri uri, String mimeType) {
|
private void edit(String title, Uri uri, String mimeType) {
|
||||||
Intent intent = new Intent(Intent.ACTION_EDIT);
|
Intent intent = new Intent(Intent.ACTION_EDIT);
|
||||||
intent.setDataAndType(uri, mimeType);
|
intent.setDataAndType(uri, mimeType);
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
package deckers.thibault.aves.channelhandlers;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.Key;
|
||||||
|
import com.bumptech.glide.request.FutureTarget;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
import com.bumptech.glide.signature.ObjectKey;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
import deckers.thibault.aves.utils.Utils;
|
||||||
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
|
||||||
|
import static com.bumptech.glide.request.RequestOptions.centerCropTransform;
|
||||||
|
|
||||||
|
public class AppIconDecodeTask extends AsyncTask<AppIconDecodeTask.Params, Void, AppIconDecodeTask.Result> {
|
||||||
|
private static final String LOG_TAG = Utils.createLogTag(AppIconDecodeTask.class);
|
||||||
|
|
||||||
|
static class Params {
|
||||||
|
Context context;
|
||||||
|
String packageName;
|
||||||
|
int size;
|
||||||
|
MethodChannel.Result result;
|
||||||
|
|
||||||
|
Params(Context context, String packageName, int size, MethodChannel.Result result) {
|
||||||
|
this.context = context;
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.size = size;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Result {
|
||||||
|
Params params;
|
||||||
|
byte[] data;
|
||||||
|
|
||||||
|
Result(Params params, byte[] data) {
|
||||||
|
this.params = params;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result doInBackground(Params... params) {
|
||||||
|
Params p = params[0];
|
||||||
|
Context context = p.context;
|
||||||
|
String packageName = p.packageName;
|
||||||
|
int size = p.size;
|
||||||
|
|
||||||
|
byte[] data = null;
|
||||||
|
if (!this.isCancelled()) {
|
||||||
|
try {
|
||||||
|
int iconResourceId = context.getPackageManager().getApplicationInfo(packageName, 0).icon;
|
||||||
|
Uri uri = new Uri.Builder()
|
||||||
|
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
|
||||||
|
.authority(packageName)
|
||||||
|
.path(String.valueOf(iconResourceId))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// add signature to ignore cache for images which got modified but kept the same URI
|
||||||
|
Key signature = new ObjectKey(packageName + size);
|
||||||
|
RequestOptions options = new RequestOptions()
|
||||||
|
.signature(signature)
|
||||||
|
.override(size, size);
|
||||||
|
|
||||||
|
FutureTarget<Bitmap> target = Glide.with(context)
|
||||||
|
.asBitmap()
|
||||||
|
.apply(options)
|
||||||
|
.apply(centerCropTransform())
|
||||||
|
.load(uri)
|
||||||
|
.signature(signature)
|
||||||
|
.submit(size, size);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Bitmap bmp = target.get();
|
||||||
|
if (bmp != null) {
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||||
|
data = stream.toByteArray();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.d(LOG_TAG, "getAppIcon with packageName=" + packageName + " interrupted");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Glide.with(context).clear(target);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d(LOG_TAG, "getAppIcon with packageName=" + packageName + " cancelled");
|
||||||
|
}
|
||||||
|
return new Result(p, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Result result) {
|
||||||
|
MethodChannel.Result r = result.params.result;
|
||||||
|
if (result.data != null) {
|
||||||
|
r.success(result.data);
|
||||||
|
} else {
|
||||||
|
r.error("getAppIcon-null", "failed to get icon for packageName=" + result.params.packageName, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" viewBox="0 0 256 256"><path fill="#FFE812" d="M256 236c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20V20C0 8.954 8.954 0 20 0h216c11.046 0 20 8.954 20 20v216z"/><path d="M128 36C70.562 36 24 72.713 24 118c0 29.279 19.466 54.97 48.748 69.477-1.593 5.494-10.237 35.344-10.581 37.689 0 0-.207 1.762.934 2.434s2.483.15 2.483.15c3.272-.457 37.943-24.811 43.944-29.04 5.995.849 12.168 1.29 18.472 1.29 57.438 0 104-36.712 104-82 0-45.287-46.562-82-104-82z"/><path fill="#FFE812" d="M70.5 146.625c-3.309 0-6-2.57-6-5.73V105.25h-9.362c-3.247 0-5.888-2.636-5.888-5.875s2.642-5.875 5.888-5.875h30.724c3.247 0 5.888 2.636 5.888 5.875s-2.642 5.875-5.888 5.875H76.5v35.645c0 3.16-2.691 5.73-6 5.73zM123.112 146.547c-2.502 0-4.416-1.016-4.993-2.65l-2.971-7.778-18.296-.001-2.973 7.783c-.575 1.631-2.488 2.646-4.99 2.646a9.155 9.155 0 0 1-3.814-.828c-1.654-.763-3.244-2.861-1.422-8.52l14.352-37.776c1.011-2.873 4.082-5.833 7.99-5.922 3.919.088 6.99 3.049 8.003 5.928l14.346 37.759c1.826 5.672.236 7.771-1.418 8.532a9.176 9.176 0 0 1-3.814.827c-.001 0 0 0 0 0zm-11.119-21.056L106 108.466l-5.993 17.025h11.986zM138 145.75c-3.171 0-5.75-2.468-5.75-5.5V99.5c0-3.309 2.748-6 6.125-6s6.125 2.691 6.125 6v35.25h12.75c3.171 0 5.75 2.468 5.75 5.5s-2.579 5.5-5.75 5.5H138zM171.334 146.547c-3.309 0-6-2.691-6-6V99.5c0-3.309 2.691-6 6-6s6 2.691 6 6v12.896l16.74-16.74c.861-.861 2.044-1.335 3.328-1.335 1.498 0 3.002.646 4.129 1.772 1.051 1.05 1.678 2.401 1.764 3.804.087 1.415-.384 2.712-1.324 3.653l-13.673 13.671 14.769 19.566a5.951 5.951 0 0 1 1.152 4.445 5.956 5.956 0 0 1-2.328 3.957 5.94 5.94 0 0 1-3.609 1.211 5.953 5.953 0 0 1-4.793-2.385l-14.071-18.644-2.082 2.082v13.091a6.01 6.01 0 0 1-6.002 6.003z"/></svg>
|
|
Before Width: | Height: | Size: 1.7 KiB |
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 240 240">
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="b" x1="0.6667" y1="0.1667" x2="0.4167" y2="0.75">
|
|
||||||
<stop stop-color="#37aee2" offset="0"/>
|
|
||||||
<stop stop-color="#1e96c8" offset="1"/>
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient id="w" x1="0.6597" y1="0.4369" x2="0.8512" y2="0.8024">
|
|
||||||
<stop stop-color="#eff7fc" offset="0"/>
|
|
||||||
<stop stop-color="#fff" offset="1"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<circle cx="120" cy="120" r="120" fill="url(#b)"/>
|
|
||||||
<path fill="#c8daea" d="m98 175c-3.8876 0-3.227-1.4679-4.5678-5.1695L82 132.2059 170 80"/>
|
|
||||||
<path fill="#a9c9dd" d="m98 175c3 0 4.3255-1.372 6-3l16-15.558-19.958-12.035"/>
|
|
||||||
<path fill="url(#w)" d="m100.04 144.41 48.36 35.729c5.5185 3.0449 9.5014 1.4684 10.876-5.1235l19.685-92.763c2.0154-8.0802-3.0801-11.745-8.3594-9.3482l-115.59 44.571c-7.8901 3.1647-7.8441 7.5666-1.4382 9.528l29.663 9.2583 68.673-43.325c3.2419-1.9659 6.2173-0.90899 3.7752 1.2584"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1,016 B |
|
@ -7,6 +7,7 @@ import 'package:aves/utils/android_file_utils.dart';
|
||||||
import 'package:aves/widgets/album/all_collection_drawer.dart';
|
import 'package:aves/widgets/album/all_collection_drawer.dart';
|
||||||
import 'package:aves/widgets/album/all_collection_page.dart';
|
import 'package:aves/widgets/album/all_collection_page.dart';
|
||||||
import 'package:aves/widgets/common/fake_app_bar.dart';
|
import 'package:aves/widgets/common/fake_app_bar.dart';
|
||||||
|
import 'package:aves/widgets/common/icons.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
@ -14,6 +15,7 @@ import 'package:permission_handler/permission_handler.dart';
|
||||||
void main() async {
|
void main() async {
|
||||||
await settings.init();
|
await settings.init();
|
||||||
await androidFileUtils.init();
|
await androidFileUtils.init();
|
||||||
|
await IconUtils.init();
|
||||||
runApp(AvesApp());
|
runApp(AvesApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,34 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class AndroidAppService {
|
class AndroidAppService {
|
||||||
static const platform = const MethodChannel('deckers.thibault/aves/app');
|
static const platform = const MethodChannel('deckers.thibault/aves/app');
|
||||||
|
|
||||||
|
static Future<Map> getAppNames() async {
|
||||||
|
try {
|
||||||
|
final result = await platform.invokeMethod('getAppNames');
|
||||||
|
return result as Map;
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
debugPrint('getAppNames failed with exception=${e.message}');
|
||||||
|
}
|
||||||
|
return Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Uint8List> getAppIcon(String packageName, int size) async {
|
||||||
|
try {
|
||||||
|
final result = await platform.invokeMethod('getAppIcon', <String, dynamic>{
|
||||||
|
'packageName': packageName,
|
||||||
|
'size': size,
|
||||||
|
});
|
||||||
|
return result as Uint8List;
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
debugPrint('getAppIcon failed with exception=${e.message}');
|
||||||
|
}
|
||||||
|
return Uint8List(0);
|
||||||
|
}
|
||||||
|
|
||||||
static edit(String uri, String mimeType) async {
|
static edit(String uri, String mimeType) async {
|
||||||
try {
|
try {
|
||||||
await platform.invokeMethod('edit', <String, dynamic>{
|
await platform.invokeMethod('edit', <String, dynamic>{
|
||||||
|
|
|
@ -5,16 +5,15 @@ final AndroidFileUtils androidFileUtils = AndroidFileUtils._private();
|
||||||
typedef void AndroidFileUtilsCallback(String key, dynamic oldValue, dynamic newValue);
|
typedef void AndroidFileUtilsCallback(String key, dynamic oldValue, dynamic newValue);
|
||||||
|
|
||||||
class AndroidFileUtils {
|
class AndroidFileUtils {
|
||||||
String dcimPath;
|
String dcimPath, downloadPath, picturesPath;
|
||||||
String picturesPath;
|
|
||||||
|
|
||||||
AndroidFileUtils._private();
|
AndroidFileUtils._private();
|
||||||
|
|
||||||
init() async {
|
init() async {
|
||||||
// TODO TLAD find storage root
|
// path_provider getExternalStorageDirectory() gives '/storage/emulated/0/Android/data/deckers.thibault.aves/files'
|
||||||
// getExternalStorageDirectory() gives '/storage/emulated/0/Android/data/deckers.thibault.aves/files'
|
|
||||||
final ext = '/storage/emulated/0';
|
final ext = '/storage/emulated/0';
|
||||||
dcimPath = join(ext, 'DCIM');
|
dcimPath = join(ext, 'DCIM');
|
||||||
|
downloadPath = join(ext, 'Download');
|
||||||
picturesPath = join(ext, 'Pictures');
|
picturesPath = join(ext, 'Pictures');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +21,5 @@ class AndroidFileUtils {
|
||||||
|
|
||||||
bool isScreenshotsPath(String path) => path != null && path.startsWith(dcimPath) && path.endsWith('Screenshots');
|
bool isScreenshotsPath(String path) => path != null && path.startsWith(dcimPath) && path.endsWith('Screenshots');
|
||||||
|
|
||||||
bool isKakaoTalkPath(String path) => path != null && path.startsWith(picturesPath) && path.endsWith('KakaoTalk');
|
bool isDownloadPath(String path) => path == downloadPath;
|
||||||
|
|
||||||
bool isTelegramPath(String path) => path != null && path.startsWith(picturesPath) && path.endsWith('Telegram');
|
|
||||||
}
|
}
|
||||||
|
|
49
lib/widgets/common/app_icon.dart
Normal file
49
lib/widgets/common/app_icon.dart
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:aves/utils/android_app_service.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:transparent_image/transparent_image.dart';
|
||||||
|
|
||||||
|
class AppIcon extends StatefulWidget {
|
||||||
|
final String packageName;
|
||||||
|
final double size;
|
||||||
|
final double devicePixelRatio;
|
||||||
|
|
||||||
|
const AppIcon({
|
||||||
|
Key key,
|
||||||
|
@required this.packageName,
|
||||||
|
@required this.size,
|
||||||
|
@required this.devicePixelRatio,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => AppIconState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppIconState extends State<AppIcon> {
|
||||||
|
Future<Uint8List> _byteLoader;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
final dim = (widget.size * widget.devicePixelRatio).round();
|
||||||
|
_byteLoader = AndroidAppService.getAppIcon(widget.packageName, dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FutureBuilder(
|
||||||
|
future: _byteLoader,
|
||||||
|
builder: (futureContext, AsyncSnapshot<Uint8List> snapshot) {
|
||||||
|
final bytes = (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) ? snapshot.data : kTransparentImage;
|
||||||
|
return bytes.length > 0
|
||||||
|
? Image.memory(
|
||||||
|
bytes,
|
||||||
|
width: widget.size,
|
||||||
|
height: widget.size,
|
||||||
|
)
|
||||||
|
: SizedBox.shrink();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
import 'package:aves/model/image_entry.dart';
|
import 'package:aves/model/image_entry.dart';
|
||||||
|
import 'package:aves/utils/android_app_service.dart';
|
||||||
import 'package:aves/utils/android_file_utils.dart';
|
import 'package:aves/utils/android_file_utils.dart';
|
||||||
|
import 'package:aves/widgets/common/app_icon.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:path/path.dart';
|
||||||
|
|
||||||
class VideoIcon extends StatelessWidget {
|
class VideoIcon extends StatelessWidget {
|
||||||
final ImageEntry entry;
|
final ImageEntry entry;
|
||||||
|
@ -84,15 +86,34 @@ class OverlayIcon extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class IconUtils {
|
class IconUtils {
|
||||||
|
static Map appNameMap;
|
||||||
|
|
||||||
|
static init() async {
|
||||||
|
appNameMap = await AndroidAppService.getAppNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Widget _buildAlbumIcon(Widget child) => Material(
|
||||||
|
type: MaterialType.circle,
|
||||||
|
elevation: 3,
|
||||||
|
color: Colors.transparent,
|
||||||
|
shadowColor: Colors.black,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
|
|
||||||
static Widget getAlbumIcon(BuildContext context, String albumDirectory) {
|
static Widget getAlbumIcon(BuildContext context, String albumDirectory) {
|
||||||
if (androidFileUtils.isCameraPath(albumDirectory)) {
|
if (albumDirectory == null) return null;
|
||||||
return Icon(Icons.photo_camera);
|
if (androidFileUtils.isCameraPath(albumDirectory)) return _buildAlbumIcon(Icon(Icons.photo_camera));
|
||||||
} else if (androidFileUtils.isScreenshotsPath(albumDirectory)) {
|
if (androidFileUtils.isScreenshotsPath(albumDirectory)) return _buildAlbumIcon(Icon(Icons.smartphone));
|
||||||
return Icon(Icons.smartphone);
|
if (androidFileUtils.isDownloadPath(albumDirectory)) return _buildAlbumIcon(Icon(Icons.file_download));
|
||||||
} else if (androidFileUtils.isKakaoTalkPath(albumDirectory)) {
|
|
||||||
return SvgPicture.asset('assets/kakaotalk.svg', width: IconTheme.of(context).size);
|
final parts = albumDirectory.split(separator);
|
||||||
} else if (androidFileUtils.isTelegramPath(albumDirectory)) {
|
if (albumDirectory.startsWith(androidFileUtils.picturesPath) && appNameMap.keys.contains(parts.last)) {
|
||||||
return SvgPicture.asset('assets/telegram.svg', width: IconTheme.of(context).size);
|
final packageName = appNameMap[parts.last];
|
||||||
|
return _buildAlbumIcon(AppIcon(
|
||||||
|
packageName: packageName,
|
||||||
|
size: IconTheme.of(context).size,
|
||||||
|
devicePixelRatio: MediaQuery.of(context).devicePixelRatio,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue