diff --git a/CompleteApps/DistributedSearch/README_zh.md b/CompleteApps/DistributedSearch/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..feba14925009f003b06430e98b8c10179f943a2a --- /dev/null +++ b/CompleteApps/DistributedSearch/README_zh.md @@ -0,0 +1,38 @@ +# **分布式搜索** + +##### 简介 + +​ 本sample使用Java语言开发,通过搜索本地的图片,音频及视频文件,并加入到分布式文件系统中,实现文件快速共享。用户可以通过输入关键字搜索到分布式文件系统中的所有文件。 + +##### 使用说明 + +1. 搜索 + 输入框输入关键字,可以通过输入框后面的搜索按钮进行搜索,也可以通过选择类型进行对应类别的搜索。 +2. 结果显示 + 搜索完后,数据将以列表的形式显示在显示区域。 + 点击每行可以查看到文件的具体路径。 + 如果没有搜索到文件,则显示无搜索结果的界面。 +3. 分布式设备查看 + 点击主界面右下角的设备按钮,可以查看到当前已经加入到分布式系统的设备情况。 + +##### 约束与限制 + +1. 编译约束 + 已实名认证的开发者联盟账号 ,具体[参考](https://developer.huawei.com/consumer/cn/ ) + 开发工具:DevEcoStudio 2.2Beta1 下载地址 [HUAWEI DevEco Studio - HarmonyOS应用开发官网](https://developer.harmonyos.com/cn/develop/deveco-studio#download) + + •安装DevEco Studio + + 设置DevEco Studio开发环境,DevEco Studio开发环境需要连接到网络,以确保该正常使用。 + 可以根据以下两种情况配置开发环境: + 1).如果您可以直接访问Internet,则只需下载HarmonyOS SDK + 2).如果网络无法直接访问Internet,则可以通过代理服务器进行访问 • 生成密钥并申请证书 + + 具体环境搭建请[参考:](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/installation_process-0000001071425528) + 更多资料请登录鸿蒙应用开发[官网:](https://developer.harmonyos.com/cn/) + +2. 使用限制 + •该应用必须要有两部或以上同一组网内的手机 + •多手机必须登录同一用户 + •暂时只支持外部SD卡中的图片,音频以及视频文件的搜索 + diff --git a/CompleteApps/DistributedSearch/build.gradle b/CompleteApps/DistributedSearch/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..56c9d92e34dcdd4b49f1f32b44c143bf4d2e9f8d --- /dev/null +++ b/CompleteApps/DistributedSearch/build.gradle @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:2.4.4.2' + classpath 'com.huawei.ohos:decctest:1.2.4.0' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} diff --git a/CompleteApps/DistributedSearch/entry/build.gradle b/CompleteApps/DistributedSearch/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..26496d14c427327bf0267de59c603858c62db84b --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.huawei.ohos.hap' +apply plugin: 'com.huawei.ohos.decctest' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#ZH-CN_TOPIC_0000001154985555__section1112183053510 +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 4 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100' +} +decc { + supportType = ['html','xml'] +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/config.json b/CompleteApps/DistributedSearch/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..a72dae016bcd483b04d539f05461b6c9a2f227c8 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/config.json @@ -0,0 +1,107 @@ +{ + "app": { + "bundleName": "ohos.samples.distributedsearch", + "vendor": "sample", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.samples.distributedsearch", + "name": ".MyApplication", + "mainAbility": "ohos.samples.distributedsearch.MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "reqPermissions": [ + { + "name": "ohos.permission.DISTRIBUTED_DATASYNC", + "reason": "用于分布式数据交换", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" + }, + { + "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE" + }, + { + "name": "ohos.permission.READ_USER_STORAGE", + "reason": "用于读取用户存储信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.WRITE_USER_STORAGE", + "reason": "用于写取用户存储信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.READ_MEDIA", + "reason": "用于读取媒体文件信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.WRITE_MEDIA", + "reason": "用于保存媒体文件信息", + "usedScene": { + "ability": [ + "com.distributed.everything.slice.MainAbilitySlice" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_BUNDLE_INFO" + } + ], + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "name": "ohos.samples.distributedsearch.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ] + } +} \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MainAbility.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..cdbf6f77094433cc72054cdadead4b530ed8a1a8 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MainAbility.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch; + +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +import ohos.bundle.IBundleManager; +import ohos.samples.distributedsearch.slice.MainAbilitySlice; +import ohos.security.SystemPermission; + +import java.util.ArrayList; +import java.util.List; + +/** + * MainAbility + */ +public class MainAbility extends Ability { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setMainRoute(MainAbilitySlice.class.getName()); + + requestPermissions(); + } + + private void requestPermissions() { + String[] permissions = { + SystemPermission.DISTRIBUTED_DATASYNC, + SystemPermission.READ_USER_STORAGE, + SystemPermission.WRITE_USER_STORAGE + }; + List permissionsToProcess = new ArrayList<>(); + for (String permission : permissions) { + if (verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED + && canRequestPermission(permission)) { + permissionsToProcess.add(permission); + } + } + requestPermissionsFromUser(permissionsToProcess.toArray(new String[0]), 0); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MyApplication.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..36f8d0df7d39bf03b0b2d1582d2aaab188f4f664 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/MyApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ohos.samples.distributedsearch; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/data/DeviceData.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/data/DeviceData.java new file mode 100644 index 0000000000000000000000000000000000000000..78701fe68a6313c237b87c9e6663d998914f1609 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/data/DeviceData.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.data; + +import ohos.distributedschedule.interwork.DeviceInfo; + +/** + * The type Device data. + * + * @since 2021-04-27 + */ +public class DeviceData { + private boolean isChecked; + + private DeviceInfo deviceInfo; + + /** + * Instantiates a new Device data. + */ + public DeviceData() { + } + + /** + * Instantiates a new Device data. + * + * @param isChecked the is checked + * @param deviceInfo the device info + */ + public DeviceData(boolean isChecked, DeviceInfo deviceInfo) { + this.isChecked = isChecked; + this.deviceInfo = deviceInfo; + } + + public boolean isChecked() { + return isChecked; + } + + public void setChecked(boolean checked) { + isChecked = checked; + } + + public DeviceInfo getDeviceInfo() { + return deviceInfo; + } + + public void setDeviceInfo(DeviceInfo deviceInfo) { + this.deviceInfo = deviceInfo; + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ComponentViewHolder.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ComponentViewHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..6673b89d6ddfc6508310f62569b95db4c654b7db --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ComponentViewHolder.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * The type Comment view holder. + * + * @since 2021-04-27 + */ +public class ComponentViewHolder { + /** + * Layout + */ + private Component componentView; + + /** + * Subcomponents in componentview + */ + private final Map childComponentMap = new HashMap<>(); + + /** + * Instantiates a new Component view holder. + */ + public ComponentViewHolder() { + } + + /** + * Instantiates a new Component view holder. + * + * @param componentView the component view + */ + public ComponentViewHolder(Component componentView) { + this.componentView = componentView; + componentView.setTag(this); + } + + public Component getComponentView() { + return componentView; + } + + /** + * Obtain the corresponding component according to the resource ID + * + * @param resId resId + * @return Component + */ + public Component getChildComponent(int resId) { + Component view = childComponentMap.get(resId); + if (view == null) { + view = componentView.findComponentById(resId); + childComponentMap.put(resId, view); + } + return view; + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/DeviceDataProvider.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/DeviceDataProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..fd56e748dd12a9a7865b1f80f8a76496955083e2 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/DeviceDataProvider.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.Component; +import ohos.agp.components.Image; +import ohos.agp.components.Text; +import ohos.app.Context; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.data.DeviceData; + +import java.util.List; + +/** + * The type Device data provider. + * + * @since 2021-04-27 + */ +public class DeviceDataProvider extends ListComponentProvider { + + /** + * Instantiates a new Device data provider. + * + * @param context the context + * @param listBean the list bean + * @param resourceId the resource id + */ + public DeviceDataProvider(Context context, List listBean, int resourceId) { + super(context, listBean, resourceId); + } + + @Override + public void onItemDataBind(ComponentViewHolder componentViewHolder, DeviceData deviceData, int position) { + + // 1 Set the name of the device + Text deviceText = (Text) componentViewHolder.getChildComponent(ResourceTable.Id_item_image_title); + deviceText.setText(deviceData.getDeviceInfo().getDeviceName()); + Text infoText = (Text) componentViewHolder.getChildComponent(ResourceTable.Id_item_image_info); + infoText.setText(deviceData.getDeviceInfo().getDeviceId()); + + // 2 Set icon for device + setDeviceImg(componentViewHolder, deviceData); + } + + private void setDeviceImg(ComponentViewHolder componentViewHolder, DeviceData deviceData) { + int imageTypeId = -1; + switch (deviceData.getDeviceInfo().getDeviceType()) { + case SMART_PHONE: + imageTypeId = ResourceTable.Media_dv_phone; + break; + case SMART_PAD: + imageTypeId = ResourceTable.Media_dv_pad; + break; + case SMART_WATCH: + imageTypeId = ResourceTable.Media_dv_watch; + break; + default: + break; + } + if (imageTypeId != -1) { + Image image = (Image) componentViewHolder.getChildComponent(ResourceTable.Id_item_type); + image.setPixelMap(imageTypeId); + } + } + + @Override + public void onItemClick(Component component, DeviceData checkDeviceData, int position) { + for (DeviceData deviceData : listBean) { + deviceData.setChecked(false); + } + listBean.get(position).setChecked(true); + + // Notify data changes + notifyDataChanged(); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileItemViewHolder.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileItemViewHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..f153cd155aca5d1973679a9d8d5f09bbf6c23a77 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileItemViewHolder.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +/** + * FileItemViewHolder file item view + */ +public class FileItemViewHolder { + private String filename; + private String devicename; + private int iconId; + private String filepath; + + /** + * create FileItemViewHolder + * + * @param filename file name + * @param devicename device name + * @param icon icon id + */ + public FileItemViewHolder(String filename, String devicename, int icon) { + this.iconId = icon; + this.filename = filename; + this.devicename = devicename; + } + + /** + * create FileItemViewHolder + * + * @param filename file name + * @param filepath file path + * @param devicename device name + * @param icon icon id + */ + public FileItemViewHolder(String filename, String filepath, String devicename, int icon) { + this.iconId = icon; + this.filename = filename; + this.devicename = devicename; + this.filepath = filepath; + } + + public void setFilename(String name) { + filename = name; + } + + public String getFilename() { + return filename; + } + + public void setDevicename(String device) { + devicename = device; + } + + public String getDevicename() { + return devicename; + } + + public void setIconId(int icon) { + iconId = icon; + } + + public int getIconId() { + return iconId; + } + + public void setFilepath(String path) { + filepath = path; + } + + public String getFilepath() { + return filepath; + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileListProvider.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileListProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..e2f4b8ab014745f70f941d8c48cc3acd663e9dd9 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/FileListProvider.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.BaseItemProvider; +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.Image; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.Text; +import ohos.app.Context; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.utils.LogUtil; + +import java.util.List; + +/** + * the file list provider + * + * @param the type parameter + */ +public class FileListProvider extends BaseItemProvider { + private final static String TAG = "FileListProvider"; + private final Context mContext; + private final List mList; + + /** + * create FileListProvider + * + * @param context the context + * @param listBean the list bean + */ + public FileListProvider(Context context, List listBean) { + mContext = context; + mList = listBean; + } + + @Override + public int getCount() { + return mList == null ? 0 : mList.size(); + } + + @Override + public T getItem(int idx) { + return (mList == null || mList.size() == 0) ? null : mList.get(idx); + } + + @Override + public long getItemId(int idx) { + return idx; + } + + @Override + public Component getComponent(int idx, Component component, ComponentContainer componentContainer) { + FileItemViewHolder holder; + + if (component == null) { + component = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_file_item, null, false); + } + + holder = (FileItemViewHolder)mList.get(idx); + if (holder == null) { + LogUtil.error(TAG, "FileItemViewHolder[]" + idx + " is null"); + return component; + } + + Image icon = (Image)component.findComponentById(ResourceTable.Id_imageIcon); + icon.setPixelMap(holder.getIconId()); + + Text name = (Text)component.findComponentById(ResourceTable.Id_filename); + name.setText(holder.getFilename()); + Text devName = (Text)component.findComponentById(ResourceTable.Id_deviceinfo); + devName.setText(mContext.getString(ResourceTable.String_file_source_label) + ": " + holder.getDevicename()); + + return component; + } + + /** + * Set the binding event of item, and the subclass overrides as needed + * + * @param component component + * @param item item + * @param position position + */ + protected void onItemClick(Component component, T item, int position) { + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ListComponentProvider.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ListComponentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..278d1d270228063b350fb8e01145eff91534a444 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/provider/ListComponentProvider.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.provider; + +import ohos.agp.components.BaseItemProvider; +import ohos.agp.components.Component; +import ohos.agp.components.ComponentContainer; +import ohos.agp.components.LayoutScatter; +import ohos.app.Context; + +import java.util.List; + +/** + * The type List component provider. + * + * @param the type parameter + * @since 2021-04-27 + */ +public abstract class ListComponentProvider extends BaseItemProvider { + protected Context context; + + /** + * Item data + */ + protected List listBean; + + /** + * Layout resource id + */ + protected int resourceId; + + /** + * Instantiates a new List component provider. + * + * @param context the context + * @param listBean the list bean + * @param resourceId the resource id + */ + public ListComponentProvider(Context context, List listBean, int resourceId) { + this.context = context; + this.listBean = listBean; + this.resourceId = resourceId; + } + + /** + * Set the data of the view subcomponent + * + * @param componentViewHolder componentViewHolder + * @param item item + * @param position position + */ + protected abstract void onItemDataBind(ComponentViewHolder componentViewHolder, T item, int position); + + @Override + public int getCount() { + return listBean.size(); + } + + @Override + public T getItem(int idx) { + return listBean.get(idx); + } + + @Override + public long getItemId(int idx) { + return idx; + } + + @Override + public Component getComponent(int position, Component component, ComponentContainer componentContainer) { + ComponentViewHolder viewHolder; + if (component == null) { + component = LayoutScatter.getInstance(context).parse(resourceId, null, false); + viewHolder = new ComponentViewHolder(component); + component.setTag(viewHolder); + } else { + viewHolder = (ComponentViewHolder) component.getTag(); + } + if (viewHolder != null) { + T item = listBean.get(position); + + // Set the data of the view subcomponent + onItemDataBind(viewHolder, item, position); + + // Set binding event of item + viewHolder.getComponentView() + .setClickedListener(componentView -> onItemClick(componentView, item, position)); + } + return component; + } + + /** + * Set the binding event of item, and the subclass overrides as needed + * + * @param component component + * @param item item + * @param position position + */ + protected void onItemClick(Component component, T item, int position) { + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/slice/MainAbilitySlice.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/slice/MainAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..c1de11b04713e9abe0d496998ed5d19dd2761e69 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/slice/MainAbilitySlice.java @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.slice; + +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.agp.components.Button; +import ohos.agp.components.Component; +import ohos.agp.components.Image; +import ohos.agp.components.ListContainer; +import ohos.agp.components.RadioButton; +import ohos.agp.components.RadioContainer; +import ohos.agp.components.Text; +import ohos.agp.components.TextField; +import ohos.agp.utils.Color; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.provider.FileItemViewHolder; +import ohos.samples.distributedsearch.provider.FileListProvider; +import ohos.samples.distributedsearch.ui.DeviceSelectDialog; +import ohos.samples.distributedsearch.ui.PopupDialog; +import ohos.samples.distributedsearch.utils.DistributedFile; +import ohos.samples.distributedsearch.utils.WidgetHelper; + +import java.util.ArrayList; +import java.util.List; + +/** + * MainAbilitySlice + */ +public class MainAbilitySlice extends AbilitySlice { + private static final int BUTTON_COORD_X = 350; + private static final int BUTTON_COORD_Y = 700; + private static final int DEVICE_COORD_X = 320; + private static final int DEVICE_COORD_Y = 700; + + private static final int MSG_SHOW_TIME = 2000; + + private String mSearchKey = ""; + private TextField mTextField; + private int mFileType = DistributedFile.FILE_TYPE_IMAGE; + + private RadioButton mButtonImage; + private RadioButton mButtonAudio; + private RadioButton mButtonVideo; + private RadioButton mButtonText; + private RadioButton mButtonFileAll; + FileListProvider fileProvider; + private final ArrayList mFileList = new ArrayList<>(); + private ListContainer listview; + private Text result; + private Image mButton; + private Button mDevice; + private DistributedFile mDistributedFile; + private RadioContainer mRadioContainer; + private Image searchImage; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setUIContent(ResourceTable.Layout_ability_everything); + + mDistributedFile = new DistributedFile(this); + mDistributedFile.start(); + + initUi(); + setEventListener(); + } + + @Override + public void onActive() { + super.onActive(); + } + + @Override + public void onForeground(Intent intent) { + super.onForeground(intent); + } + + private void initUi() { + listview = (ListContainer)this.findComponentById(ResourceTable.Id_listview); + fileProvider = new FileListProvider(this, mFileList); + listview.setItemProvider(fileProvider); + + listview.setVisibility(Component.HIDE); + + result = (Text) findComponentById(ResourceTable.Id_result_info); + result.setVisibility(Component.VISIBLE); + + mRadioContainer = (RadioContainer)findComponentById(ResourceTable.Id_radio_container); + + mButtonImage = (RadioButton) this.findComponentById(ResourceTable.Id_sel_image); + mButtonAudio = (RadioButton) this.findComponentById(ResourceTable.Id_sel_audio); + mButtonVideo = (RadioButton) this.findComponentById(ResourceTable.Id_sel_video); + mButtonText = (RadioButton) this.findComponentById(ResourceTable.Id_sel_text); + mButtonFileAll = (RadioButton) this.findComponentById(ResourceTable.Id_sel_all); + mRadioContainer.mark(0); + mButtonImage.setClickable(false); + + mTextField = (TextField)this.findComponentById(ResourceTable.Id_textEntry); + mTextField.setTextColor(Color.BLACK); + searchImage = (Image)this.findComponentById(ResourceTable.Id_searchButton); + + mButton = (Image)findComponentById(ResourceTable.Id_AnimaBttn); + mDevice = (Button)findComponentById(ResourceTable.Id_deviceBttn); + + mButton.setPosition(BUTTON_COORD_X, BUTTON_COORD_Y); + mDevice.setPosition(DEVICE_COORD_X, DEVICE_COORD_Y); + mButton.setVisibility(Component.VISIBLE); + mDevice.setVisibility(Component.HIDE); + } + + private void setEventListener() { + setListViewEvent(); + setRadioContainerEvent(); + + searchImage.setClickedListener(component -> { + mSearchKey = mTextField.getText(); + if (!availableKey(mSearchKey)) { + WidgetHelper.showTips(this, getString(ResourceTable.String_input_notice_msg), MSG_SHOW_TIME); + return; + } + + setListFile(); + }); + + mButton.setClickedListener(component -> { + mButton.setVisibility(Component.HIDE); + if (mDevice != null) { + mDevice.setVisibility(Component.VISIBLE); + mDevice.setFocusable(Component.FOCUS_ENABLE); + } + }); + + mDevice.setClickedListener(component -> { + + mDevice.setVisibility(Component.HIDE); + if (mButton != null) { + mButton.setVisibility(Component.VISIBLE); + mButton.setFocusable(Component.FOCUS_ENABLE); + } + DeviceSelectDialog mDialog = new DeviceSelectDialog(this); + mDialog.show(); + }); + } + + private void setListViewEvent() { + listview.setItemClickedListener((container, component, position, id) -> { + FileItemViewHolder item = (FileItemViewHolder) listview.getItemProvider().getItem(position); + if (item != null && item.getFilepath() != null) { + WidgetHelper.showTips(this, + getString(ResourceTable.String_file_path_label) + ": " + + item.getFilepath() + "/" + item.getFilename(), MSG_SHOW_TIME); + } + }); + listview.setItemLongClickedListener((container, component, position, id) -> { + FileItemViewHolder item = (FileItemViewHolder) listview.getItemProvider().getItem(position); + if (item != null) { + PopupDialog mDialog = new PopupDialog(this); + mDialog.show(); + } + return true; + }); + } + + private void setRadioContainerEvent() { + mRadioContainer.setMarkChangedListener((radioContainer, idx) -> { + RadioButton[] mRadioButton = { + mButtonImage, + mButtonAudio, + mButtonVideo, + mButtonText, + mButtonFileAll + }; + + if (mFileType == idx) { + return; + } + + if (mRadioButton[mFileType] != null) { + mRadioButton[mFileType].setTextColor(Color.GRAY); + mRadioButton[mFileType].setClickable(true); + } + mFileType = idx; + mRadioButton[mFileType].setClickable(false); + + mSearchKey = mTextField.getText(); + if (availableKey(mSearchKey)) { + setListFile(); + } + }); + } + + private boolean getFileViewList() { + List list; + if (!mDistributedFile.hasCheckResult()) { + return false; + } + list = mDistributedFile.getFile(mFileType); + if (list == null || list.size() == 0) { + return false; + } + + getFileList(list, mSearchKey); + + return mFileList.size() > 0; + } + + private void getFileList(List list, String key) { + mFileList.clear(); + for (String filename : list) { + String device; + String name; + String path = null; + + int idx = filename.lastIndexOf('/'); + if (idx < 0) { + name = filename; + } else { + name = filename.substring(idx + 1); + path = filename.substring(0, idx + 1); + } + idx = name.indexOf('+'); + if (idx < 0) { + device = getString(ResourceTable.String_local_device_name); + } else { + device = name.substring(0, idx); + if (DistributedFile.isLocalDevice(this, device, 0)) { + device = getString(ResourceTable.String_local_device_name); + } + name = name.substring(idx + 1); + } + + if (filename.contains(key)) { + int ico = ResourceTable.Media_icon_file; + int type = mDistributedFile.checkFileType(name); + + if (type == DistributedFile.FILE_TYPE_IMAGE) { + ico = ResourceTable.Media_icon_img; + } else if (type == DistributedFile.FILE_TYPE_AUDIO) { + ico = ResourceTable.Media_icon_music; + } else if (type == DistributedFile.FILE_TYPE_VIDEO) { + ico = ResourceTable.Media_icon_video; + } + + FileItemViewHolder viewHolder = new FileItemViewHolder(name, path, device, ico); + mFileList.add(viewHolder); + } + } + } + + private boolean availableKey(String key) { + if (key == null || key.length() == 0) { + return false; + } + return !key.contains(" "); + } + + private void setListFile() { + if (getFileViewList()) { + result.setVisibility(Component.HIDE); + listview.setVisibility(Component.VISIBLE); + fileProvider.notifyDataChanged(); + } else { + result.setVisibility(Component.VISIBLE); + listview.setVisibility(Component.HIDE); + } + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/DeviceSelectDialog.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/DeviceSelectDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..3ad49692cb82f752d318952fcd8bfd479f82f52f --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/DeviceSelectDialog.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.ui; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +import ohos.aafwk.ability.AbilitySlice; +import ohos.agp.components.Component; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.ListContainer; +import ohos.agp.components.Text; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.CommonDialog; +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.distributedschedule.interwork.DeviceManager; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.data.DeviceData; +import ohos.samples.distributedsearch.provider.DeviceDataProvider; +import ohos.samples.distributedsearch.utils.LogUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * The type Device select dialog. + * + * @since 2021-04-27 + */ +public class DeviceSelectDialog extends CommonDialog { + private static final String TAG = DeviceSelectDialog.class.getSimpleName(); + + private static final int CORNER_RADIUS = 10; + + private final AbilitySlice context; + + private DeviceInfo checkedDevice; + + /** + * Instantiates a new Device select dialog. + * + * @param context the context + */ + public DeviceSelectDialog(AbilitySlice context) { + super(context); + this.context = context; + } + + @Override + protected void onCreate() { + super.onCreate(); + List deviceList = initDeviceData(); + Component rootView = + LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dialog_layout_device, null, false); + ListContainer listContainer = + (ListContainer) rootView.findComponentById(ResourceTable.Id_list_container_device); + setItemProvider(listContainer, deviceList); + configChoiceButton(rootView); + configStyle(rootView); + } + + private List initDeviceData() { + LogUtil.info(TAG, "begin to initDeviceData"); + List deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); + List deviceList = new ArrayList<>(); + for (DeviceInfo deviceInfo : deviceInfoList) { + deviceList.add(new DeviceData(false, deviceInfo)); + } + if (deviceInfoList.size() > 0) { + checkedDevice = deviceInfoList.get(0); + } + LogUtil.info(TAG, "get " + deviceInfoList.size() + " devices"); + return deviceList; + } + + private void setItemProvider(ListContainer listContainer, List deviceList) { + LogUtil.info(TAG, "begin to setItemProvider"); + DeviceDataProvider deviceDataProvider = + new DeviceDataProvider(context, deviceList, ResourceTable.Layout_dialog_device_item); + listContainer.setItemProvider(deviceDataProvider); + } + + private void configChoiceButton(Component rootView) { + LogUtil.info(TAG, "begin to configChoiceButton"); + Text operateYes = (Text) rootView.findComponentById(ResourceTable.Id_operate_yes); + operateYes.setClickedListener(component -> destroy()); + Text operateNo = (Text) rootView.findComponentById(ResourceTable.Id_operate_no); + operateNo.setClickedListener(component -> destroy()); + } + + private void configStyle(Component rootView) { + LogUtil.info(TAG, "begin to configStyle"); + setSize(MATCH_PARENT, MATCH_CONTENT); + setAlignment(LayoutAlignment.BOTTOM); + setCornerRadius(CORNER_RADIUS); + setAutoClosable(true); + setContentCustomComponent(rootView); + setTransparent(true); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/PopupDialog.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/PopupDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..f269fb8140251ce1f7a1c25be868af7aadafc98e --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/ui/PopupDialog.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.ui; + +import ohos.agp.components.Component; +import ohos.agp.components.LayoutScatter; +import ohos.agp.components.Text; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.CommonDialog; +import ohos.app.Context; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.samples.distributedsearch.utils.LogUtil; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +/** + * PopupDialog + */ +public class PopupDialog extends CommonDialog { + private static final String TAG = "PopupDialog"; + private static final int CORNER_RADIUS = 40; + private final Context mContext; + + /** + * create PopupDialog + * + * @param context the context + */ + public PopupDialog(Context context) { + super(context); + mContext = context; + } + + @Override + protected void onCreate() { + super.onCreate(); + Component rootView = + LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_dialog_delete, null, false); + configChoiceButton(rootView); + configStyle(rootView); + } + + private void configChoiceButton(Component rootView) { + LogUtil.info(TAG, "begin to configChoiceButton"); + Text operateYes = (Text) rootView.findComponentById(ResourceTable.Id_operate_yes); + operateYes.setClickedListener(component -> { + destroy(); + }); + Text operateNo = (Text) rootView.findComponentById(ResourceTable.Id_operate_no); + operateNo.setClickedListener(component -> destroy()); + } + + private void configStyle(Component rootView) { + LogUtil.info(TAG, "begin to configStyle"); + setSize(MATCH_PARENT, MATCH_CONTENT); + setAlignment(LayoutAlignment.CENTER); + setCornerRadius(CORNER_RADIUS); + setAutoClosable(true); + setContentCustomComponent(rootView); + setTransparent(true); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DistributedFile.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DistributedFile.java new file mode 100644 index 0000000000000000000000000000000000000000..69842e98520752e750c6c03fb4644e1f4a1695a5 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/DistributedFile.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import ohos.aafwk.ability.DataAbilityHelper; +import ohos.aafwk.ability.DataAbilityRemoteException; +import ohos.app.Context; +import ohos.data.distributed.common.KvManagerConfig; +import ohos.data.distributed.common.KvManagerFactory; +import ohos.data.resultset.ResultSet; +import ohos.media.photokit.metadata.AVStorage; +import ohos.samples.distributedsearch.ResourceTable; +import ohos.utils.net.Uri; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Distributed File manager + */ +public class DistributedFile extends Thread { + private static final String TAG = DistributedFile.class.getSimpleName(); + + public static final int FILE_TYPE_IMAGE = 0; + public static final int FILE_TYPE_AUDIO = 1; + public static final int FILE_TYPE_VIDEO = 2; + public static final int FILE_TYPE_TEXT = 3; + public static final int FILE_TYPE_FILE = 4; + public static final int FILE_TYPE_UNKNOWN = 0xFF; + + private static final int CACHE_SIZE = 8 * 1024; + private static final int END_OF_FILE = -1; + + private final String[] mImageType = {"jpg", "bmp", "jpeg", "png"}; + private final String[] mAudioType = {"mp3","wav", "flac"}; + private final String[] mVideoType = {"mp4","mjpeg"}; + private final String[] mTextType = {"xml","xlsx", "doc", "docx", "pdf", "txt"}; + + private final Context mContext; + private boolean isCheckResult = false; + + private final ArrayList localList = new ArrayList<>(); + private final ArrayList distributedList = new ArrayList<>(); + + /** + * create DistributedFile + * + * @param context the context + */ + public DistributedFile(Context context) { + mContext = context; + } + + @Override + public void run() { + initDistributedFiles(); + getDistributedFiles(); + isCheckResult = true; + } + + /** + * check the list has been searched over + * + * @return true or false + */ + public boolean hasCheckResult() { + return isCheckResult; + } + + /** + * get the file list + * + * @param type file type + * @return file list + */ + public List getFile(int type) { + if (distributedList.size() > 0) { + return getFileList(distributedList, type); + } else { + return getFileList(localList, type); + } + } + + private List getFileList(List array, int type) { + if (type == FILE_TYPE_FILE || array.size() == 0) { + return array; + } + + ArrayList list = new ArrayList<>(); + + for (String filename : array) { + if (isTypeFile(filename, type)) { + list.add(filename); + } + } + + return list; + } + + private boolean isTypeFile(String file, int type) { + if (type == FILE_TYPE_FILE) { + return true; + } + if (type == FILE_TYPE_IMAGE) { + return isDestFile(file, mImageType); + } + if (type == FILE_TYPE_AUDIO) { + return isDestFile(file, mAudioType); + } + if (type == FILE_TYPE_VIDEO) { + return isDestFile(file, mVideoType); + } + if (type == FILE_TYPE_TEXT) { + return isDestFile(file, mTextType); + } + + return false; + } + + private boolean isDestFile(String file, String[] des) { + int idx = file.lastIndexOf('.'); + if (idx < 0) { + return false; + } + String suffix = file.substring(idx + 1); + + for (String de : des) { + if (de.equals(suffix)) { + return true; + } + } + + return false; + } + + private void initDistributedFiles() { + searchFiles(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI); + searchFiles(AVStorage.Audio.Media.EXTERNAL_DATA_ABILITY_URI); + searchFiles(AVStorage.Video.Media.EXTERNAL_DATA_ABILITY_URI); + } + + private void searchFiles(Uri uri) { + DataAbilityHelper helper = DataAbilityHelper.creator(mContext); + + String[] projections = new String[]{AVStorage.AVBaseColumns.ID, + AVStorage.AVBaseColumns.DISPLAY_NAME, AVStorage.AVBaseColumns.DATA}; + try { + ResultSet resultSet = helper.query(uri, projections, null); + if (resultSet == null) { + LogUtil.info(TAG, "resultSet == null"); + return; + } + + while (resultSet.goToNextRow()) { + int mediaId = resultSet.getInt(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.ID)); + String fullPath = resultSet.getString(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.DATA)); + String fileName = fullPath.substring(fullPath.lastIndexOf(File.separator) + 1); + Uri tmpUri = Uri.appendEncodedPathToUri(uri, "" + mediaId); + writeToDistributedDir(mContext, helper, fileName, tmpUri); + localList.add(fileName); + } + } catch (DataAbilityRemoteException e) { + LogUtil.error(TAG, "query Files failed."); + } + } + + private void writeToDistributedDir(Context context, DataAbilityHelper helper, String fileName, Uri uri) { + if (context.getDistributedDir() == null) { + WidgetHelper.showOneSecondTips(context, context.getString(ResourceTable.String_distributed_exception_info)); + return; + } + + String deviceName = KvManagerFactory.getInstance() + .createKvManager(new KvManagerConfig(context)) + .getLocalDeviceInfo().getName(); + String uniqueFileName = deviceName + "+" + fileName; + String distributedFilePath = context.getDistributedDir().getPath() + '/' + uniqueFileName; + + writeFile(distributedFilePath, helper, uri); + } + + private void writeFile(String filename, DataAbilityHelper helper, Uri uri) { + InputStream inputStream = null; + OutputStream outputStream = null; + + try { + FileDescriptor fileDescriptor = helper.openFile(uri, "r"); + File file = new File(filename); + inputStream = new FileInputStream(fileDescriptor); + outputStream = new FileOutputStream(file); + + byte[] buffer = new byte[CACHE_SIZE]; + int count; + while ((count = inputStream.read(buffer)) != END_OF_FILE) { + outputStream.write(buffer, 0, count); + } + } catch (DataAbilityRemoteException | IOException e) { + LogUtil.error(TAG, "writeToDistributedDir exception : " + e); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + if (outputStream != null) { + outputStream.close(); + } + } catch (IOException e) { + LogUtil.error(TAG, "close stream io exception"); + } + } + } + + private void getDistributedFiles() { + if (mContext.getDistributedDir() == null) { + WidgetHelper.showOneSecondTips(mContext, mContext.getString(ResourceTable.String_distributed_exception_info)); + return; + } + File file = new File(mContext.getDistributedDir().getPath()); + File[] files = file.listFiles(); + if (files == null) { + LogUtil.error(TAG, "no distributed files!"); + return; + } + + for (File eachFile : files) { + distributedList.add(eachFile.getPath()); + } + } + + /** + * check file type + * + * @param filename file name + * @return file type + */ + public int checkFileType(String filename) { + if (isDestFile(filename, mImageType)) { + return FILE_TYPE_IMAGE; + } + if (isDestFile(filename, mAudioType)) { + return FILE_TYPE_AUDIO; + } + if (isDestFile(filename, mVideoType)) { + return FILE_TYPE_VIDEO; + } + if (isDestFile(filename, mTextType)) { + return FILE_TYPE_TEXT; + } + + return FILE_TYPE_UNKNOWN; + } + + /** + * Check wether is the local device + * params: context: ability context + * info device name or id + * type: info type, 0 -- name, 1 -- id + * @return true or false. + */ + public static boolean isLocalDevice(Context context, String info, int type) { + String result; + if (type == 0) { + result = KvManagerFactory.getInstance() + .createKvManager(new KvManagerConfig(context)) + .getLocalDeviceInfo().getName(); + } else if (type == 1) { + result = KvManagerFactory.getInstance() + .createKvManager(new KvManagerConfig(context)) + .getLocalDeviceInfo().getId(); + } else { + return false; + } + LogUtil.info(TAG, "info : "+info+",result : "+result); + return info.equals(result); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/LogUtil.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/LogUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..9b1514e8bcfe1fb0d2a0d1eb254fdaa13bfb73cc --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/LogUtil.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import ohos.distributedschedule.interwork.DeviceInfo; +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; + +import java.util.Locale; + +/** + * Log util function + * + * @since 2019-10-15 + */ +public class LogUtil { + private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, ""); + + private static final String LOG_FORMAT = "%{public}s: %{public}s"; + + private static final String NULL_STR = "null"; + + private LogUtil() { + /* Do nothing */ + } + + /** + * print device info to log + * + * @param className The prefix to log + * @param device The device into to print + * @param msg log message + */ + public static void printDevice(String className, DeviceInfo device, String msg) { + if (device == null) { + HiLog.error(LABEL_LOG, LOG_FORMAT, className, "DeviceInfo is null"); + } else { + HiLog.info(LABEL_LOG, + "%{public}s: %{public}s: { deviceId: %{public}s, deviceName: %{public}s, deviceType: %{public}s }", + className, msg, device.getDeviceId(), device.getDeviceName(), device.getDeviceType()); + } + } + + /** + * Print debug log + * + * @param className class name + * @param msg log message + */ + public static void debug(String className, String msg) { + HiLog.debug(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print debug log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void debug(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.debug(LABEL_LOG, LOG_FORMAT, classType == null ? NULL_STR : classType.getSimpleName(), buffMsg); + } + + /** + * Print info log + * + * @param className class name + * @param msg log message + */ + public static void info(String className, String msg) { + HiLog.info(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print info log + * + * @param className class name + * @param format format + * @param args args + */ + public static void info(String className, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.info(LABEL_LOG, LOG_FORMAT, className, buffMsg); + } + + /** + * Print info log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void info(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.info(LABEL_LOG, LOG_FORMAT, classType == null ? NULL_STR : classType.getSimpleName(), buffMsg); + } + + /** + * Print warn log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void warn(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.warn(LABEL_LOG, LOG_FORMAT, classType == null ? NULL_STR : classType.getSimpleName(), buffMsg); + } + + /** + * Print error log + * + * @param className class name + * @param msg log message + */ + public static void warn(String className, String msg) { + HiLog.warn(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print error log + * + * @param className class name + * @param msg log message + */ + public static void error(String className, String msg) { + HiLog.error(LABEL_LOG, LOG_FORMAT, className, msg); + } + + /** + * Print error log + * + * @param classType class name + * @param format format + * @param args args + */ + public static void error(Class classType, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.error(LABEL_LOG, LOG_FORMAT, classType == null ? NULL_STR : classType.getSimpleName(), buffMsg); + } + + /** + * Print error log + * + * @param tag log tag + * @param format format + * @param args args + */ + public static void error(String tag, final String format, Object... args) { + String buffMsg = String.format(Locale.ROOT, format, args); + HiLog.error(LABEL_LOG, LOG_FORMAT, tag, buffMsg); + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetHelper.java b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..076e9e15b428951457e46d6c62cbb24943e29855 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/java/ohos/samples/distributedsearch/utils/WidgetHelper.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ohos.samples.distributedsearch.utils; + +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT; +import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT; + +import ohos.agp.components.*; +import ohos.agp.utils.LayoutAlignment; +import ohos.agp.window.dialog.ToastDialog; +import ohos.app.Context; +import ohos.global.resource.NotExistException; +import ohos.global.resource.ResourceManager; +import ohos.global.resource.WrongTypeException; +import ohos.samples.distributedsearch.ResourceTable; + +import java.io.IOException; + +/** + * The type Widget helper. + * + * @since 2021-04-27 + */ +public class WidgetHelper { + private static final String TAG = WidgetHelper.class.getSimpleName(); + + private static final int ONE_SECOND = 1000; + + private WidgetHelper() { + } + + /** + * Show tips. + * + * @param context the context + * @param msgId the msg id + */ + public static void showTips(Context context, int msgId) { + String msg = getStringByResourceId(context, msgId); + showOneSecondTips(context, msg); + } + + /** + * Show tips. + * + * @param context the context + * @param msg the msg + * @param durationTime the duration time + */ + public static void showTips(Context context, String msg, int durationTime) { + Component rootView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_widget_helper, + null, false); + Text text = (Text)rootView.findComponentById(ResourceTable.Id_helperText); + text.setText(msg); + + ToastDialog toastDialog = new ToastDialog(context); + toastDialog.setSize(MATCH_PARENT, MATCH_CONTENT); + toastDialog.setDuration(durationTime); + toastDialog.setAutoClosable(true); + toastDialog.setTransparent(true); + toastDialog.setAlignment(LayoutAlignment.CENTER); + toastDialog.setComponent(rootView); + toastDialog.show(); + } + + /** + * Show one second tips. + * + * @param context the context + * @param msg the msg + */ + public static void showOneSecondTips(Context context, String msg) { + showTips(context, msg, ONE_SECOND); + } + + /** + * Gets string by resource id. + * + * @param context the context + * @param id the id + * @return the string by resource id + */ + public static String getStringByResourceId(Context context, int id) { + if (context == null) { + LogUtil.info(TAG, "Context is null, getString failed"); + return ""; + } + ResourceManager resMgr = context.getResourceManager(); + if (resMgr == null) { + LogUtil.info(TAG, "ResourceManager is null, getString failed"); + return ""; + } + + String value = ""; + try { + value = resMgr.getElement(id).getString(); + } catch (NotExistException | WrongTypeException | IOException e) { + LogUtil.info(TAG, "get string value from resource manager failed"); + } + return value; + } +} diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/animation/animator_value.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/animation/animator_value.xml new file mode 100644 index 0000000000000000000000000000000000000000..8cd1f0a0f4428e709e7a8b963e2c5a9f11d38751 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/animation/animator_value.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/element/colors.json b/CompleteApps/DistributedSearch/entry/src/main/resources/base/element/colors.json new file mode 100644 index 0000000000000000000000000000000000000000..2ee40bdd48dd9e9add158d97f9efcea24ce975f8 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/element/colors.json @@ -0,0 +1,20 @@ +{ + "color": [ + { + "name": "news_type_text_off", + "value": "#55000000" + }, + { + "name": "news_type_text_on", + "value": "#afaafa" + }, + { + "name": "white", + "value": "#ffffff" + }, + { + "name": "half_transparent", + "value": "#55000000" + } + ] +} \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/element/string.json b/CompleteApps/DistributedSearch/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..06fccf1a5099eab602330a845a939489ca235005 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/element/string.json @@ -0,0 +1,88 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "DistributedSearch" + }, + { + "name": "mainability_description", + "value": "Java_Empty Ability" + }, + { + "name": "mainability_HelloWorld", + "value": "Hello World" + }, + { + "name": "button_distributed_device", + "value": "Dev" + }, + { + "name": "button_add_distributed", + "value": "Join distributed file system" + }, + { + "name": "image_label", + "value": "Image" + }, + { + "name": "audio_label", + "value": "Audio" + }, + { + "name": "video_label", + "value": "Video" + }, + { + "name": "text_label", + "value": "File" + }, + { + "name": "all_label", + "value": "All" + }, + { + "name": "result_info_label", + "value": "No results" + }, + { + "name": "cancel_label", + "value": "Cancel" + }, + { + "name": "confirm_label", + "value": "Confirm" + }, + { + "name": "input_notice_msg", + "value": "Please enter a valid search keyword" + }, + { + "name": "file_path_label", + "value": "File path" + }, + { + "name": "local_device_name", + "value": "Local" + }, + { + "name": "distributed_exception_info", + "value": "Note: distributed file exception!" + }, + { + "name": "file_source_label", + "value": "File source" + }, + { + "name": "delete_file_info", + "value": "Are you sure to delete this file?" + }, + { + "name": "delete_file_warn", + "value": "The file cannot be recovered after deletion" + }, + { + "name": "delete_label", + "value": "Delete" + } + ] +} \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_ability_main.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_ability_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_ability_main.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_button.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_button.xml new file mode 100644 index 0000000000000000000000000000000000000000..145a81f31feb3cd47c6308b6cc612daec74d1adf --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_button.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_text_field.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_text_field.xml new file mode 100644 index 0000000000000000000000000000000000000000..212bec9ce754f3ae457cd0fc5a65fa3a01e8bc90 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_text_field.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_white_radius_10.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_white_radius_10.xml new file mode 100644 index 0000000000000000000000000000000000000000..2c7cd3be6666f7865de9f5a13cc05d57ee3dc43a --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_white_radius_10.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_widget.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_widget.xml new file mode 100644 index 0000000000000000000000000000000000000000..3ba60a0c37f9c7a189bd55dd5a17b10ca29d288b --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/background_widget.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/ele_cursor_bubble.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/ele_cursor_bubble.xml new file mode 100644 index 0000000000000000000000000000000000000000..5a39be4ad709ee2a20355be1d81c23d957427975 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/graphic/ele_cursor_bubble.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/CompleteApps/DistributedSearch/entry/src/main/resources/base/layout/ability_everything.xml b/CompleteApps/DistributedSearch/entry/src/main/resources/base/layout/ability_everything.xml new file mode 100644 index 0000000000000000000000000000000000000000..4add09685f64e813ce4640a732663caeab077f43 --- /dev/null +++ b/CompleteApps/DistributedSearch/entry/src/main/resources/base/layout/ability_everything.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +