Compare commits

..

No commits in common. 'main' and 'develop' have entirely different histories.

@ -1,34 +1,2 @@
# 垃圾分类识别系统
系统简介:
垃圾识别: 系统能够对用户提供的垃圾图片进行分析和处理,快速而精准地判定垃圾的种类,并将识别结果反馈给用户。
垃圾桶定位: 系统获取用户当前位置及人工标注的附近垃圾桶位置信息,并计算路径,帮助用户找到最近的垃圾桶。
用户反馈: 系统设有用户反馈功能。用户可以提交垃圾分类的疑问、问题和反馈。这些数据后续会进行筛选和分析,用于进一步优化系统的识别算法和流程。
垃圾分类知识竞答: 系统提供给用户有关垃圾分类的选择题或判断题,用户可以进行作答,帮助用户提升垃圾分类的相关知识
配置环境:
Android版本
minSDK 26
TargetSDK 33
python环境
python 3.7.6
torchvision 0.13.1
tensorflow 1.14.0
pytorch 1.12.1
mysql版本 8.10
# garbage

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 MiB

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

@ -1,6 +1,5 @@
plugins {
id 'com.android.application'
id "org.sonarqube" version "3.5.0.2730"
}
android {
@ -9,7 +8,7 @@ android {
defaultConfig {
applicationId "com.example.myapplication"
minSdk 26
minSdk 24
targetSdk 33
versionCode 1
versionName "1.0"
@ -30,41 +29,18 @@ android {
buildFeatures {
viewBinding true
}
sourceSets{
main {
//jnilibsso
jniLibs.srcDirs = ['libs']
assets.srcDirs+=['src/main/com.example.myapplication/raw']
}
}
}
dependencies {
// implementation 'com.tencent.map:tencent-map-vector-sdk:4.3.5'
// implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:8.7.5.1'
implementation 'com.github.JediBurrell:customFloatingActionButton:-SNAPSHOT'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.tencent.map:tencent-map-nav-sdk:5.4.6.0'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'
implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'
implementation files('libs\\tencent-mapsdk-android-official-release.5.2.1.18c8cd09.jar')
implementation files('libs\\poi-3.12-android-a.jar')
implementation files('libs\\poi-ooxml-schemas-3.12-20150511-a.jar')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -4,5 +4,5 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Fri Sep 29 04:34:54 CST 2023
sdk.dir=F\:\\AndroidSDK\\AndroidSDK
#Mon Sep 25 09:53:48 CST 2023
sdk.dir=E\:\\Android_SDK

@ -1,39 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 通过GPS得到精确位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 通过网络得到粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 访问网络,某些位置信息需要从网络服务器获取 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 访问WiFi状态需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 修改WiFi状态发起WiFi扫描, 需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 访问网络状态, 检测网络的可用性,需要网络运营商相关信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 访问网络的变化, 需要某些信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 蓝牙扫描权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 前台service权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- 后台定位权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!-- A-GPS辅助定位权限方便GPS快速准确定位 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:requestLegacyExternalStorage="true"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@ -42,39 +11,15 @@
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
<meta-data android:name="TencentMapSDK" android:value="3P5BZ-UWDK3-K5U34-RN5YR-3VQC6-XYBYX"/>
<activity android:name=".ui.index"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BottomNavigiationActivity"
android:exported="true"
android:label="@string/title_activity_bottom_navigiation">
</activity>
<activity android:name=".ui.home.CameraPreview"
android:exported="true"
android:launchMode="standard"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.home.ResultActivity"
android:exported="true"
android:launchMode="standard"
></activity>
</application>
</manifest>

@ -1,6 +0,0 @@
projectKey=Test
serverUrl=http://localhost:9000
serverVersion=9.9.0.65466
dashboardUrl=http://localhost:9000/dashboard?id=Test
ceTaskId=AYu0FgJhk-ulwfDUJI5I
ceTaskUrl=http://localhost:9000/api/ce/task?id=AYu0FgJhk-ulwfDUJI5I

Binary file not shown.

@ -3,7 +3,6 @@ package com.example.myapplication;
import android.media.Image;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@ -12,7 +11,6 @@ import android.widget.ImageButton;
import com.example.myapplication.ui.Buttonfragments.RecycleGarbageFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
@ -21,7 +19,6 @@ import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.example.myapplication.databinding.BottomNavigiationBinding;
import com.google.android.material.bottomnavigation.LabelVisibilityMode;
import java.util.List;
@ -31,16 +28,18 @@ public class BottomNavigiationActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// Log.d("wc","create");
super.onCreate(savedInstanceState);
binding = BottomNavigiationBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
this.getSupportActionBar().hide();
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications,R.id.navigation_quiz)
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
.build();
navView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_bottom_navigiation);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(binding.navView, navController);
}
}

@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment;
import com.example.myapplication.R;
public class HazardGarbageFragment extends Fragment {//有害垃圾介绍
public class HazardGarbageFragment extends Fragment {
public HazardGarbageFragment() {
// Required empty public constructor

@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment;
import com.example.myapplication.R;
public class KitchenGarbageFragment extends Fragment {//厨余垃圾介绍
public class KitchenGarbageFragment extends Fragment {
public KitchenGarbageFragment() {
// Required empty public constructor

@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment;
import com.example.myapplication.R;
public class OtherGarbageFragment extends Fragment {//其他垃圾介绍
public class OtherGarbageFragment extends Fragment {
public OtherGarbageFragment() {
// Required empty public constructor

@ -9,11 +9,12 @@ import androidx.fragment.app.Fragment;
import com.example.myapplication.R;
public class RecycleGarbageFragment extends Fragment {//可回收垃圾介绍
public class RecycleGarbageFragment extends Fragment {
public RecycleGarbageFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

@ -1,88 +0,0 @@
package com.example.myapplication.ui.dashboard;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentDashboardBinding;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.tencent.lbssearch.TencentSearch;
import com.tencent.lbssearch.httpresponse.HttpResponseListener;
import com.tencent.lbssearch.object.param.WalkingParam;
import com.tencent.lbssearch.object.result.WalkingResultObject;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
import com.tencent.tencentmap.mapsdk.maps.TencentMapInitializer;
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
public class MapActivity extends Fragment {
private TextureMapView mapView;
private FloatingActionButton currentPositioning;
private FloatingActionButton nearbyTrashBinChoose;
private FloatingActionButton navigation;
private FragmentDashboardBinding binding;
private MapPositioning controller;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
MapActivityViewModel dashboardViewModel = new ViewModelProvider(this).get(MapActivityViewModel.class);
TencentMapInitializer.setAgreePrivacy(true);
binding = FragmentDashboardBinding.inflate(inflater, container, false);
View root = binding.getRoot();
mapView = root.findViewById(R.id.mapview);
currentPositioning = root.findViewById(R.id.Get_Current_Location);
nearbyTrashBinChoose = root.findViewById(R.id.check_nearby_trash_cans);
navigation = root.findViewById(R.id.navigiation);
controller = new MapPositioning(mapView, binding,getActivity());
currentPositioning.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controller.onClickCurrentPositioning();
}
});
nearbyTrashBinChoose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controller.onClickNearbyTrashBinChoose();
}
});
navigation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
controller.onClickNavigation();
}
});
controller.startLocationUpdates();
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
controller.stopLocationUpdates();
mapView.onDestroy();
binding = null;
}
}

@ -1,19 +0,0 @@
package com.example.myapplication.ui.dashboard;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class MapActivityViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public MapActivityViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is dashboard fragment");
}
public LiveData<String> getText() {
return mText;
}
}

@ -1,233 +0,0 @@
package com.example.myapplication.ui.dashboard;
import android.graphics.Color;
import android.view.View;
import android.widget.Toast;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewModelProvider;
import com.example.myapplication.databinding.FragmentDashboardBinding;
import com.tencent.lbssearch.TencentSearch;
import com.tencent.lbssearch.httpresponse.HttpResponseListener;
import com.tencent.lbssearch.object.param.WalkingParam;
import com.tencent.lbssearch.object.result.WalkingResultObject;
import com.tencent.map.geolocation.TencentLocationManager;
import com.tencent.map.geolocation.TencentLocationRequest;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdate;
import com.tencent.tencentmap.mapsdk.maps.CameraUpdateFactory;
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
import com.tencent.tencentmap.mapsdk.maps.TextureMapView;
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
import com.tencent.tencentmap.mapsdk.maps.model.LatLngBounds;
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
import com.tencent.tencentmap.mapsdk.maps.model.PolylineOptions;
import java.util.ArrayList;
import java.util.List;
public class MapPositioning {
private TextureMapView mapView;
private TencentMap tencentMap;
private FragmentDashboardBinding binding;
private List<LatLng> TrashBin;
private FragmentActivity fragmentActivity;
static double currentLatitude;
static double currentLongitude;
TencentSearch tencentSearch;
WalkingParam walkingParam;
LatLng chooseTrashBin;
public float calculateDistance(LatLng start, LatLng end) {//计算所有标记垃圾桶与当前位置的距离
double earthRadius = 6371;
double lat1 = Math.toRadians(start.getLatitude());
double lon1 = Math.toRadians(start.getLongitude());
double lat2 = Math.toRadians(end.getLatitude());
double lon2 = Math.toRadians(end.getLongitude());
double deltaLat = lat2 - lat1;
double deltaLon = lon2 - lon1;
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
+ Math.cos(lat1) * Math.cos(lat2)
* Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (float) (earthRadius * c);
}
private HttpResponseListener<WalkingResultObject> httpResponseListener;
public MapPositioning(TextureMapView mapView, FragmentDashboardBinding binding,FragmentActivity activity) {//初始化,
this.mapView = mapView;
this.binding = binding;
tencentMap = mapView.getMap();
tencentMap.setMyLocationEnabled(true);
tencentMap.enableMultipleInfowindow(true);
fragmentActivity=activity;
TrashBin=new ArrayList<>();
TrashBin.add(new LatLng(39.111981,117.350131));//添加垃圾桶位置信息
TrashBin.add(new LatLng(39.112578,117.349414));
TrashBin.add(new LatLng(39.112062,117.349687));
TrashBin.add(new LatLng(39.1162,117.350954));
TrashBin.add(new LatLng(39.115949,117.351535));
TrashBin.add(new LatLng(39.115614,117.351487));
TrashBin.add(new LatLng(39.115767,117.351119));
tencentSearch=new TencentSearch(mapView.getContext());
httpResponseListener = new HttpResponseListener<WalkingResultObject>() {
@Override
public void onSuccess(int i, WalkingResultObject walkingResultObject) {
if(walkingParam==null)
{
return ;
}
for(WalkingResultObject.Route route:walkingResultObject.result.routes)
{
List<LatLng> polyline = route.polyline;
tencentMap.addPolyline(new PolylineOptions().addAll(polyline).width(5f).color(Color.RED));
}
}
@Override
public void onFailure(int i, String s, Throwable throwable) {
}
};
tencentMap.setOnMarkerClickListener(new TencentMap.OnMarkerClickListener() {//根据当前上一次的点击事件,判断是否为双击事件,如果是双击事件就进行导航
private long lastClickTime;
@Override
public boolean onMarkerClick(Marker marker) {
long clicktime=System.currentTimeMillis();
if(clicktime-lastClickTime<1000)
{
LatLng now = marker.getPosition();
walkingParam=new WalkingParam(new LatLng(currentLatitude,currentLongitude),now);
tencentSearch.getRoutePlan(walkingParam, httpResponseListener);
}
lastClickTime=clicktime;
return true;
}
});
}
public void onClickCurrentPositioning() {//发送请求,获取当前位置信息
String message = "当前位置:纬度:" + currentLatitude + ",经度:" + currentLongitude;
Toast.makeText(mapView.getContext(), message, Toast.LENGTH_SHORT).show();
tencentMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(currentLatitude,currentLongitude)));
}
public void onClickNearbyTrashBinChoose() {//显示附近的垃圾桶位置信息
long st=System.currentTimeMillis();
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for(LatLng trashBin:TrashBin)
{
tencentMap.addMarker(new MarkerOptions(trashBin));
}
builder.include(new LatLng(currentLatitude,currentLongitude));
for(LatLng trashBin:TrashBin)
{
builder.include(trashBin);
}
LatLngBounds bounds = builder.build();
int padding=100;
CameraUpdate cameraUpdate=CameraUpdateFactory.newLatLngBounds(bounds,padding);
tencentMap.moveCamera(cameraUpdate);
long ed=System.currentTimeMillis();
System.out.println(ed);
}
public void onClickNavigation() {//进行导航功能
double shortestDistance=Double.MAX_VALUE;
LatLng now = new LatLng(currentLatitude, currentLongitude);
for(LatLng trashBin:TrashBin)//获取所有垃圾桶位置信息并计算距离
{
double distance=calculateDistance(now,trashBin);
if(distance<shortestDistance)
{
shortestDistance=distance;
chooseTrashBin=trashBin;
}
}
walkingParam = new WalkingParam(now,chooseTrashBin);
tencentSearch.getRoutePlan(walkingParam,httpResponseListener);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(now);
builder.include(chooseTrashBin);
LatLngBounds bounds = builder.build();
int padding=100;
CameraUpdate cameraUpdate=CameraUpdateFactory.newLatLngBounds(bounds,padding);
tencentMap.moveCamera(cameraUpdate);
}
public void startLocationUpdates() {//更新地图位置信息
TencentLocationManager mLocationManager=TencentLocationManager.getInstance(fragmentActivity,null);
mLocationManager.setCoordinateType(TencentLocationManager.COORDINATE_TYPE_GCJ02);
TencentLocationRequest request= TencentLocationRequest.create();
request.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA);
MyLocationListener myLocationListener=new MyLocationListener(tencentMap,fragmentActivity);
request.setInterval(3000);
mLocationManager.requestLocationUpdates(request,myLocationListener,TencentLocationRequest.REQUEST_LEVEL_GEO);
}
public void stopLocationUpdates() {//停止地图位置信息控制
TencentLocationManager mLocationManager=TencentLocationManager.getInstance(fragmentActivity,null);
MyLocationListener myLocationListener=new MyLocationListener(tencentMap,fragmentActivity);
mLocationManager.removeUpdates(myLocationListener);
}
}

@ -1,133 +0,0 @@
package com.example.myapplication.ui.dashboard;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.fragment.app.FragmentActivity;
import com.tencent.map.geolocation.TencentLocation;
import com.tencent.map.geolocation.TencentLocationListener;
import com.tencent.tencentmap.mapsdk.maps.TencentMap;
import com.tencent.tencentmap.mapsdk.maps.TencentMapNavi;
import com.tencent.tencentmap.mapsdk.maps.model.LatLng;
import com.tencent.tencentmap.mapsdk.maps.model.Marker;
import com.tencent.tencentmap.mapsdk.maps.model.MarkerOptions;
public class MyLocationListener implements TencentLocationListener, SensorEventListener {
private final int TIME_SENSOR = 10;
private TencentMap tencentMap;
private Marker marker;
private FragmentActivity activity;
private long lastTime;
private static float mAngle;
private Sensor orientationSensor;
private SensorManager sensorManager;
public MyLocationListener(TencentMap tencentMap, FragmentActivity activity) {
this.tencentMap = tencentMap;
this.activity = activity;
this.lastTime = System.currentTimeMillis();
sensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sensorManager.registerListener(this, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onLocationChanged(TencentLocation location, int error, String reason) {//发送请求
if (error == TencentLocation.ERROR_OK) {
// 定位成功
double latitude = location.getLatitude();
double longitude = location.getLongitude();
MapPositioning.currentLatitude=latitude;
MapPositioning.currentLongitude=longitude;
Log.d("latitude", "onLocationChanged: "+latitude);
Log.d("longitude","onLocationChanged"+longitude);
LatLng latLng = new LatLng(latitude, longitude);
if (marker != null) {
marker.remove(); // 清除之前的标记
}
marker = tencentMap.addMarker(new MarkerOptions(latLng));
marker.setRotation(mAngle);// 自定义标记图标
} else {
// 处理定位失败的情况
Toast.makeText(activity, "定位失败:" + reason, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onStatusUpdate(String name, int status, String desc) {
// 处理位置提供者状态变化的情况
}
@Override
public void onGnssInfoChanged(Object o) {
}
@Override
public void onNmeaMsgChanged(String s) {
}
public static int getScreenRotationOnPhone(Context context) {//获取手机的角度信息
final Display display = ((WindowManager) context
.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return -90;
}
return 0;
}
@Override
public void onSensorChanged(SensorEvent event) {//获取当前手机的方向
if (System.currentTimeMillis() - lastTime < TIME_SENSOR) {
return;
}
switch (event.sensor.getType()) {
case Sensor.TYPE_ORIENTATION: {
float x = event.values[0];
x += getScreenRotationOnPhone(activity);
x %= 360.0F;
if (x > 180.0F)
x -= 360.0F;
else if (x < -180.0F)
x += 360.0F;
if (Math.abs(mAngle - x) < 3.0f) {
break;
}
mAngle = Float.isNaN(x) ? 0 : x;
if (marker != null) {
marker.setRotation(mAngle);
}
lastTime = System.currentTimeMillis();
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}

@ -1,170 +0,0 @@
package com.example.myapplication.ui.home;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.myapplication.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
public class CameraPreview extends AppCompatActivity {
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_PERMISSION_CAMERA = 2;
private ImageView imageView;
private File photoFile;
private String fileName;
public int flag;
FloatingActionButton capture,upload;
Bitmap bitmap;
private final static int RESULT_RECOGNITON=114514;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capture);
this.getSupportActionBar().hide();
imageView = findViewById(R.id.show_photo);
capture=findViewById(R.id.recapture);
upload=findViewById(R.id.transmit);
capture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
checkCameraPermission();
}
});
upload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ImageUploader.setImageUploadCallback(new ImageUploadCallback() {//上传图片
public void onResultChanged(String result) {
int resultType = 0;
Log.d("resultss",result);
if ("可回收垃圾".equals(result)) {
resultType = 1;
} else if ("湿垃圾".equals(result)) {
resultType = 2;
} else if ("非生活垃圾".equals(result)||"干垃圾".equals(result)) {
resultType = 3;
}
else {
resultType=4;
}
Intent intent = new Intent(CameraPreview.this, ResultActivity.class);
intent.putExtra("result", resultType);
intent.putExtra("photoUrl", photoFile.getAbsolutePath());
startActivity(intent);
}
});
ImageUploader.imageUpload(photoFile.getAbsolutePath());
}
});
checkCameraPermission();
}
private void checkCameraPermission() {//检查相机权限
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CAMERA);
} else {
dispatchTakePictureIntent();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {//当接受相机返回结果
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CAMERA) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
} else {
Toast.makeText(this, "Camera permission denied.", Toast.LENGTH_SHORT).show();
}
}
}
private File createImageFile() throws IOException {
fileName= UUID.randomUUID().toString();
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(fileName, ".jpg", storageDir);
return imageFile;
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this, "com.example.myapplication.fileprovider", photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(photoFile);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
// 照片已成功保存到指定文件,将其添加到系统相册
galleryAddPic();
// 显示拍摄的照片
setPic();
}
else
{
finish();
}
}
private void setPic() {//显示对应的照片
// 获取保存的图片文件
if (photoFile != null) {
// 解析图片文件为 Bitmap
bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
// 设置到 ImageView 上显示
imageView.setImageBitmap(bitmap);
ByteArrayOutputStream stream =new ByteArrayOutputStream();
byte[] bytes = stream.toByteArray();
}
}
}

@ -1,59 +0,0 @@
package com.example.myapplication.ui.home;
import androidx.fragment.app.FragmentManager;
import com.example.myapplication.R;
import com.example.myapplication.ui.Buttonfragments.HazardGarbageFragment;
import com.example.myapplication.ui.Buttonfragments.KitchenGarbageFragment;
import com.example.myapplication.ui.Buttonfragments.OtherGarbageFragment;
import com.example.myapplication.ui.Buttonfragments.RecycleGarbageFragment;
public class GarbageRecognition {
private static GarbageRecognition instance;
private GarbageRecognitionActivity fragment;
private GarbageRecognition() {}
public static GarbageRecognition getInstance() {
if (instance == null) {
instance = new GarbageRecognition();
}
return instance;
}
public void setFragment(GarbageRecognitionActivity fragment) {
this.fragment = fragment;
}
public void onRecyclableGarbageButtonClick() {//转化到可回收垃圾的介绍界面
FragmentManager fragmentManager = fragment.getParentFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_container, new RecycleGarbageFragment()).commit();
fragment.clearTextUnderLineColor(fragment.flag);
fragment.setTextUnderLineColor("可回收垃圾", fragment.recycleText);
fragment.flag = 0;
}
public void onKitchenGarbageButtonClick() {//转化到厨余垃圾界面
FragmentManager fragmentManager = fragment.getParentFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_container, new KitchenGarbageFragment()).commit();
fragment.clearTextUnderLineColor(fragment.flag);
fragment.setTextUnderLineColor("厨余垃圾", fragment.kitchenText);
fragment.flag = 1;
}
public void onOtherGarbageButtonClick() {//转缓到其他垃圾的介绍界面
FragmentManager fragmentManager = fragment.getParentFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_container, new OtherGarbageFragment()).commit();
fragment.clearTextUnderLineColor(fragment.flag);
fragment.setTextUnderLineColor("其他垃圾", fragment.otherGarbageText);
fragment.flag = 2;
}
public void onHazardGarbageButtonClick() {//转化到有害垃圾的界面
FragmentManager fragmentManager = fragment.getParentFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_container, new HazardGarbageFragment()).commit();
fragment.clearTextUnderLineColor(fragment.flag);
fragment.setTextUnderLineColor("有害垃圾", fragment.hazardText);
fragment.flag = 3;
}
}

@ -1,119 +0,0 @@
package com.example.myapplication.ui.home;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentHomeBinding;
public class GarbageRecognitionActivity extends Fragment {
private ImageButton recyclableGarbageButton;
private ImageButton kitchenGarbageButton;
private ImageButton otherGarbageButton;
private ImageButton hazardGarbageButton;
private FragmentHomeBinding binding;
private ImageButton captureButton;
public TextView recycleText;
public TextView kitchenText;
public TextView otherGarbageText;
public TextView hazardText;
private SpannableString spannableString;
public int flag=0;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
recyclableGarbageButton = root.findViewById(R.id.recycle);
kitchenGarbageButton = root.findViewById(R.id.kitchen_garbage);
otherGarbageButton = root.findViewById(R.id.other_garbage);
hazardGarbageButton = root.findViewById(R.id.hazardous_waste);
captureButton = root.findViewById(R.id.capture);
recycleText = root.findViewById(R.id.recycle_text);
kitchenText = root.findViewById(R.id.kitchen_text);
otherGarbageText = root.findViewById(R.id.other_garbage_text);
hazardText = root.findViewById(R.id.hazardous_waste_text);
recyclableGarbageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GarbageRecognition.getInstance().setFragment(GarbageRecognitionActivity.this);
GarbageRecognition.getInstance().onRecyclableGarbageButtonClick();
}
});
kitchenGarbageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GarbageRecognition.getInstance().setFragment(GarbageRecognitionActivity.this);
GarbageRecognition.getInstance().onKitchenGarbageButtonClick();
}
});
otherGarbageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GarbageRecognition.getInstance().setFragment(GarbageRecognitionActivity.this);
GarbageRecognition.getInstance().onOtherGarbageButtonClick();
}
});
hazardGarbageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GarbageRecognition.getInstance().setFragment(GarbageRecognitionActivity.this);
GarbageRecognition.getInstance().onHazardGarbageButtonClick();
}
});
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), CameraPreview.class);
startActivity(intent);
}
});
recyclableGarbageButton.performClick();
return root;
}
public void setTextUnderLineColor(String text,TextView curText)//设置文本下划线,提示用户目前查看的是哪一个垃圾分类介绍信息
{
clearTextUnderLineColor(flag);
spannableString = new SpannableString(text);
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString.setSpan(underlineSpan,0,text.length(),0);
ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.rgb(3,169,244));
spannableString.setSpan(colorSpan,0,text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
curText.setText(spannableString);
}
public void clearTextUnderLineColor(int flag)//清空之前选中的按钮选项
{
switch (flag)
{
case 0:
recycleText.setText("可回收垃圾");
case 1:
kitchenText.setText("厨余垃圾");
case 2:
otherGarbageText.setText("其他垃圾");
case 3:
hazardText.setText("有害垃圾");
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -1,19 +0,0 @@
package com.example.myapplication.ui.home;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class GarbageRecognitionActivityViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public GarbageRecognitionActivityViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is home fragment");
}
public LiveData<String> getText() {
return mText;
}
}

@ -1,5 +0,0 @@
package com.example.myapplication.ui.home;
public interface ImageUploadCallback {
void onResultChanged(String newResult);
}

@ -1,118 +0,0 @@
package com.example.myapplication.ui.home;
import android.util.Log;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ImageUploader {
private static String result;
private static ImageUploadCallback callback;
public static void setImageUploadCallback(ImageUploadCallback cb) {
callback = cb;
}
private static void notifyCallback() {
Log.d("aaaaaaa", "notifyCallback: ");
if (callback != null) {
callback.onResultChanged(result);
}
}
// 在获取到上传结果时调用该方法
private static void setResult(String newResult) {
result = newResult;
notifyCallback();
}
public static void imageUpload(String imagePath) {//前后端交互代码
ExecutorService executorService = Executors.newFixedThreadPool(1);
Future<Void> uploadTask = executorService.submit(() -> {
try {
String uploadUrl = "http://192.168.203.243:5000/upload_image"; // 替换为你的Flask服务器URL
File imageFile = new File(imagePath);
if (!imageFile.exists()) {
System.out.println("Image file not found.");
return null;
}
URL url = new URL(uploadUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法为POST
connection.setRequestMethod("POST");
connection.setDoOutput(true);
// 构建请求体
String boundary = "*****";
String lineEnd = "\r\n";
String twoHyphens = "--";
String charset = "UTF-8";
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + imageFile.getName() + "\"" + lineEnd);
dos.writeBytes("Content-Type: image/jpeg" + lineEnd);
dos.writeBytes(lineEnd);
FileInputStream fileInputStream = new FileInputStream(imageFile);
int bytesAvailable = fileInputStream.available();
int maxBufferSize = 1024;
int bufferSize = Math.min(bytesAvailable, maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
Log.d("s1", "3 ");
// 发送请求并获取响应
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 请求成功
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line=reader.readLine();
Log.d("s1", line);
setResult(line);
inputStream.close();
} else {
Log.d("s1", "2 ");
// 请求失败
System.out.println("HTTP POST request failed with response code: " + responseCode);
}
fileInputStream.close();
dos.flush();
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
// 等待上传任务完成
try {
uploadTask.get();
} catch (Exception e) {
e.printStackTrace();
}
// 关闭线程池
executorService.shutdown();
}
}

@ -1,57 +0,0 @@
package com.example.myapplication.ui.home;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.myapplication.R;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
public class ResultActivity extends AppCompatActivity {
private ImageView photo;
@Override
protected void onCreate(Bundle savedInstanceState) {//在后端发送数据后,跳转到对应的结果界面
super.onCreate(savedInstanceState);
this.getSupportActionBar().hide();
int resultType=getIntent().getIntExtra("result",1);
String photoFile =getIntent().getStringExtra("photoUrl") ;
Bitmap bitmap = BitmapFactory.decodeFile(photoFile);
switch (resultType)
{
case 1:
setContentView(R.layout.sonofrecycle_garbage);
break;
case 2:
setContentView(R.layout.sonofkitchen_garbage);
break;
case 3:
setContentView(R.layout.sonofother_garbage);
break;
case 4:
setContentView(R.layout.sonofhazard_garbage);
break;
}
photo=findViewById(R.id.picture);
photo.setImageBitmap(bitmap);
}
}

@ -1,34 +0,0 @@
package com.example.myapplication.ui;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapplication.BottomNavigiationActivity;
import com.example.myapplication.R;
import com.example.myapplication.ui.home.GarbageRecognitionActivity;
public class index extends AppCompatActivity {
private static final long SPLASH_DELAY = 800; // 延迟时间,单位为毫秒,启动界面
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getSupportActionBar().hide();
// 设置启动页布局文件
setContentView(R.layout.launch_screen);
// 延迟跳转到主界面
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(index.this, BottomNavigiationActivity.class);
startActivity(intent);
finish(); // 销毁当前活动,防止用户返回到启动页
}
}, SPLASH_DELAY);
}
}

@ -1,125 +0,0 @@
package com.example.myapplication.ui.notifications;
import android.util.Log;
import android.widget.Toast;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FeedbackUploader {//反馈信息与后端进行交互
public static void submitFeedback(UserFeedbackActivity userFeedbackActivity, String imagePath,String additionalString) {
ExecutorService executorService = Executors.newFixedThreadPool(1);
Toast toast = new Toast(userFeedbackActivity.getActivity());
Future<Void> uploadTask = executorService.submit(() -> {
try {
Log.d("s2","t1");
String uploadImageUrl = "http://192.168.203.243:5000/upload_image"; // 替换为图片上传的URL
String uploadStringUrl = "http://192.168.203.243:5000/upload_text"; // 替换为字符串上传的URL
Log.d("s2","t2");
File imageFile = new File(imagePath);
if (!imageFile.exists()) {
Log.d("s2","t3");
System.out.println("Image file not found.");
return null;
}
Log.d("s2","t1");
// 发送图片
URL imageUrl = new URL(uploadImageUrl);
HttpURLConnection imageConnection = (HttpURLConnection) imageUrl.openConnection();
imageConnection.setRequestMethod("POST");
imageConnection.setDoOutput(true);
// 构建请求体
String boundary = "*****";
String lineEnd = "\r\n";
String twoHyphens = "--";
imageConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream imageDos = new DataOutputStream(imageConnection.getOutputStream());
imageDos.writeBytes(twoHyphens + boundary + lineEnd);
imageDos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + imageFile.getName() + "\"" + lineEnd);
imageDos.writeBytes("Content-Type: image/jpeg" + lineEnd);
imageDos.writeBytes(lineEnd);
FileInputStream imageInputStream = new FileInputStream(imageFile);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = imageInputStream.read(buffer)) != -1) {
imageDos.write(buffer, 0, bytesRead);
}
imageDos.writeBytes(lineEnd);
imageDos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
Log.d("s2","t1");
// 发送图片请求并获取响应
int imageResponseCode = imageConnection.getResponseCode();
if (imageResponseCode == HttpURLConnection.HTTP_OK) {
// 图片上传成功
// System.out.println("Image uploaded successfully.");
InputStream inputStream = imageConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
line=reader.readLine();
inputStream.close();
Log.d("s2","t2");
// 发送字符串
URL urlString = new URL(uploadStringUrl);
HttpURLConnection stringConnection = (HttpURLConnection) urlString.openConnection();
stringConnection.setRequestMethod("POST");
stringConnection.setDoOutput(true);
stringConnection.setRequestProperty("Content-Type", "text/plain");
OutputStream stringOs = stringConnection.getOutputStream();
stringOs.write(additionalString.getBytes("UTF-8"));
stringOs.flush();
stringOs.close();
// 获取字符串上传响应
int stringResponseCode = stringConnection.getResponseCode();
if (stringResponseCode == HttpURLConnection.HTTP_OK) {
Log.d("s2","t3");
// 字符串上传成功
InputStream inputStream2 = stringConnection.getInputStream();
BufferedReader reader2 = new BufferedReader(new InputStreamReader(inputStream2));
while ((line = reader2.readLine()) != null) {
System.out.println(line);
}
inputStream2.close();
toast.setText("图片上传成功!");
} else {
toast.setText("图片上传失败");
// 字符串上传失败
System.out.println("String upload failed with response code: " + stringResponseCode);
}
} else {
// 图片上传失败
toast.setText("图片上传失败");
System.out.println("Image upload failed with response code: " + imageResponseCode);
}
imageInputStream.close();
imageDos.flush();
imageDos.close();
} catch (Exception e) {
e.printStackTrace();
}finally {
toast.show();
}
return null;
});
// 等待上传任务完成
try {
uploadTask.get();
} catch (Exception e) {
e.printStackTrace();
}
// 关闭线程池
executorService.shutdown();
}
}

@ -1,100 +0,0 @@
package com.example.myapplication.ui.notifications;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
public class UserFeedback {
public UserFeedbackActivity userFeedbackActivity;
public UserFeedback(UserFeedbackActivity userFeedbackActivity) {
this.userFeedbackActivity = userFeedbackActivity;
}
public void resetAll()//清空所有按钮内容
{
userFeedbackActivity.editText.setText("");
userFeedbackActivity.userExperience.setChecked(false);
userFeedbackActivity.positiveRecommendation.setChecked(false);
userFeedbackActivity.otherIssues.setChecked(false);
userFeedbackActivity.classificationExpansion.setChecked(false);
userFeedbackActivity.functionalRecommendations.setChecked(false);
userFeedbackActivity.identifyDeviations.setChecked(false);
}
public String getRealPathFromURI(Uri contentUri) {//获取对应图片的URI
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = userFeedbackActivity.getContext().getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
cursor.close();
return path;
}
public void submitFeedback(Uri uri)//提交反馈
{
String feedback=recordFeedback();
FeedbackUploader.submitFeedback(userFeedbackActivity,getRealPathFromURI(uri),feedback);
}
public String recordFeedback()//格式化字符串方便与服务端进行通信格式为100011|文本信息,前面六位依次对应用户体验、识别偏差、功能建议、分类扩充、其他问题、好评推荐,|是分隔符,然后是文本数据即用户提交的数据
{
StringBuilder sb = new StringBuilder();
if(userFeedbackActivity.positiveRecommendation.isChecked())
{
sb.append('1');
}
else
{
sb.append('0');
}
if(userFeedbackActivity.otherIssues.isChecked())
{
sb.append('1');
}
else
{
sb.append('0');
}
if(userFeedbackActivity.classificationExpansion.isChecked())
{
sb.append('1');
}
else
{
sb.append('0');
}
if(userFeedbackActivity.functionalRecommendations.isChecked())
{
sb.append('1');
}
else
{
sb.append('0');
}
if(userFeedbackActivity.identifyDeviations.isChecked())
{
sb.append('1');
}
else
{
sb.append('0');
}
if(userFeedbackActivity.userExperience.isChecked())
{
sb.append('1');
}
else
{
sb.append('0');
}
String contentEditText=userFeedbackActivity.editText.getText().toString();
sb.append('|');
return sb.toString()+contentEditText;
}
}

@ -1,124 +0,0 @@
package com.example.myapplication.ui.notifications;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentNotificationsBinding;
import com.example.myapplication.ui.home.ImageUploader;
import com.google.android.material.checkbox.MaterialCheckBox;
public class UserFeedbackActivity extends Fragment {
private FragmentNotificationsBinding binding;
private ImageButton buttonSelectImage;
public EditText editText;
private Button submit,reset;
private UserFeedback userFeedback;
private Uri uri;
public MaterialCheckBox userExperience,identifyDeviations,functionalRecommendations,classificationExpansion,otherIssues,positiveRecommendation;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
UserFeedbackViewModel notificationsViewModel =
new ViewModelProvider(this).get(UserFeedbackViewModel.class);
userFeedback = new UserFeedback(this);
binding = FragmentNotificationsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
editText = root.findViewById(R.id.input_feedback);
buttonSelectImage = root.findViewById(R.id.btn_select_image);
userExperience=root.findViewById(R.id.user_experience);
identifyDeviations=root.findViewById(R.id.identify_deviations);
functionalRecommendations = root.findViewById(R.id.functional_recommendations);
classificationExpansion = root.findViewById(R.id.classification_expansion);
otherIssues = root.findViewById(R.id.other_issues);
positiveRecommendation = root.findViewById(R.id.positive_recommendation);
submit = root.findViewById(R.id.submit);
reset = root.findViewById(R.id.reset);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
editText.setCursorVisible(false);
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
if(editable != null&& editable.toString().length()>0)
{
editText.setCursorVisible(true);
editText.setGravity(Gravity.START);
}
else
{
editText.setGravity(Gravity.CENTER);
}
}
});
buttonSelectImage.setOnClickListener(new View.OnClickListener() {//跳转到相册界面
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_PICK,null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent,2);
}
});
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
userFeedback.submitFeedback(uri);
}
});
reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
userFeedback.resetAll();
}
});
return root;
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {//获取用户选择的相册的图片
if(resultCode==-1)
{
if(data!=null)
{
uri = data.getData();
buttonSelectImage.setImageURI(uri);
}
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -1,19 +0,0 @@
package com.example.myapplication.ui.notifications;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class UserFeedbackViewModel extends ViewModel {
private final MutableLiveData<String> mText;
public UserFeedbackViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is notifications fragment");
}
public LiveData<String> getText() {
return mText;
}
}

@ -1,98 +0,0 @@
package com.example.myapplication.ui.quiz;
import android.graphics.Color;
import android.media.session.MediaSession;
import android.widget.MultiAutoCompleteTextView;
import android.widget.Toast;
import androidx.fragment.app.FragmentActivity;
import com.example.myapplication.R;
import com.example.myapplication.ui.tools.Problem;
import java.io.FileInputStream;
import java.io.IOException;
public class GarbageQuiz {
private Problem problemTool,analysisTool;//问题分析和分析分析的类对象
private GarbageQuizActivity fragment;//对应的界面
GarbageQuiz(GarbageQuizActivity fragmentActivity) throws IOException {
this.fragment=fragmentActivity;
problemTool = new Problem(fragment.getResources().openRawResource(R.raw.question));
analysisTool = new Problem(fragment.getResources().openRawResource(R.raw.answer));
}
void clearOptionColor()//清空之前活动的选项
{
fragment.aButton.setTextColor(Color.BLACK);
fragment.bButton.setTextColor(Color.BLACK);
fragment.cButton.setTextColor(Color.BLACK);
fragment.dButton.setTextColor(Color.BLACK);
}
public void chooseAOption()//选中A选项下面依次是选B、C、D选中后清空之前的选项文本颜色对应的选项文本颜色变为绿色
{
String answer = analysisTool.getAnswer(problemTool.getNow());
fragment.analysisTextView.setText(answer);
clearOptionColor();
fragment.aButton.setTextColor(Color.rgb(177,247,206));
}
public void chooseBOption()
{
String answer = analysisTool.getAnswer(problemTool.getNow());
fragment.analysisTextView.setText(answer);
clearOptionColor();
fragment.bButton.setTextColor(Color.rgb(177,247,206));
}
public void chooseCOption()
{
String answer = analysisTool.getAnswer(problemTool.getNow());
fragment.analysisTextView.setText(answer);
clearOptionColor();
fragment.cButton.setTextColor(Color.rgb(177,247,206));
}
public void chooseDOption()
{
String answer = analysisTool.getAnswer(problemTool.getNow());
fragment.analysisTextView.setText(answer);
clearOptionColor();
fragment.dButton.setTextColor(Color.rgb(177,247,206));
}
public void getLastQuestion()//获取前一个问题,如果是第一个问题,提示用户
{
clearOptionColor();
fragment.analysisTextView.setText("");
String[] strings = problemTool.getPreQuestion();
if (strings == null) {
Toast.makeText(this.fragment.getActivity(), "这已经是第一个问题啦", Toast.LENGTH_SHORT).show();
return;
}
fragment.question.setText(strings[0]);
fragment.aButton.setText(strings[1]);
fragment.bButton.setText(strings[2]);
fragment.cButton.setText(strings[3]);
fragment.dButton.setText(strings[4]);
}
public void getNextQuestion()//获取后一个问题,假如是最后一个问题,提示用户
{
clearOptionColor();
fragment.analysisTextView.setText("");
String[] strings = problemTool.getNextQuestion();
if (strings == null) {
Toast.makeText(this.fragment.getActivity(), "这已经是最后一个问题啦", Toast.LENGTH_SHORT).show();
return;
}
fragment.question.setText(strings[0]);
fragment.aButton.setText(strings[1]);
fragment.bButton.setText(strings[2]);
fragment.cButton.setText(strings[3]);
fragment.dButton.setText(strings[4]);
}
}

@ -1,94 +0,0 @@
package com.example.myapplication.ui.quiz;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.example.myapplication.R;
import com.example.myapplication.databinding.GarbageQuizBinding;
import com.example.myapplication.ui.home.GarbageRecognition;
import com.example.myapplication.ui.home.GarbageRecognitionActivityViewModel;
import com.example.myapplication.ui.notifications.UserFeedbackViewModel;
import java.io.IOException;
public class GarbageQuizActivity extends Fragment {
private GarbageQuizBinding binding;
public Button aButton,bButton,cButton,dButton;
private ImageButton preQuestionButton,nextQuestionButton;
private GarbageQuiz garbageQuiz;
public TextView question,analysisTextView;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
com.example.myapplication.ui.newthing.GarbageQuizViewModel notificationsViewModel =
new ViewModelProvider(this).get(com.example.myapplication.ui.newthing.GarbageQuizViewModel.class);
binding = GarbageQuizBinding.inflate(inflater,container,false);
View root = binding.getRoot();
aButton = root.findViewById(R.id.a_option);
bButton = root.findViewById(R.id.b_option);
cButton = root.findViewById(R.id.c_option);
dButton = root.findViewById(R.id.d_option);
question = root.findViewById(R.id.question);
analysisTextView = root.findViewById(R.id.analysisTextView);
preQuestionButton = root.findViewById(R.id.pre_question);
nextQuestionButton = root.findViewById(R.id.next_question);
try {
garbageQuiz =new GarbageQuiz(this);
} catch (IOException e) {
throw new RuntimeException(e);
}
aButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
garbageQuiz.chooseAOption();
}
});
bButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
garbageQuiz.chooseBOption();
}
});
cButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
garbageQuiz.chooseCOption();
}
});
dButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
garbageQuiz.chooseDOption();
}
});
preQuestionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
garbageQuiz.getLastQuestion();
}
});
nextQuestionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
garbageQuiz.getNextQuestion();
}
});
nextQuestionButton.performClick();
return root;
}
}

@ -1,19 +0,0 @@
package com.example.myapplication.ui.newthing;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class GarbageQuizViewModel extends ViewModel {
private MutableLiveData<String> mText;
public GarbageQuizViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is new fragment");//根据自己喜欢放界面的测试文字
}
public LiveData<String> getText() {
return mText;
}
}

@ -1,107 +0,0 @@
package com.example.myapplication.ui.tools;
import android.util.Log;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Problem {
private XSSFWorkbook workbook;
private int start;
private int end;
private int sz;
private int now=-1;
private boolean flag=true;
private ArrayList<String []>question;//存储对应的问题
private ArrayList<Integer> rowNum;//存储目前问题对应的xlsx行数
Sheet sheet;
public int getNow()
{
return rowNum.get(now);
}
public Problem(InputStream file) throws IOException {//打开res库中的xlsx读取对应的图库和解析
rowNum = new ArrayList<>();
try
{
workbook = new XSSFWorkbook(file);
sheet = workbook.getSheetAt(0);
sz = sheet.getPhysicalNumberOfRows();
Random random = new Random();
int randomNumber = random.nextInt(sz);
question = new ArrayList<>();
start=end=randomNumber;
int i;
int tmp=sz;
for(i=start;tmp!=0;tmp--,i++)
{
rowNum.add(i%sz);
Row row = sheet.getRow((i)%sz);
Cell cell = row.getCell(1);
if(cell != null)
{
String cellValue = cell.getStringCellValue();
cellValue=cellValue.replace(""," ");
String[] split = cellValue.split(" ");
question.add(split);
}
}
}catch (Exception e)
{
e.printStackTrace();
System.out.println("读取文件失败");
}
}
public void close() throws IOException {
workbook.close();
}
public String[] getPreQuestion()//获取前一个问题
{
if(now-1>=0)return question.get(--now);
else return null;
}
public String[] getNextQuestion()//获取后一个问题
{
if(now+1<question.size())return question.get(++now);
return null;
}
public String getAnswer(int row)//获取对应行的解析
{
Row nrow = sheet.getRow(row);
Cell cell = nrow.getCell(1);
Cell cell1 = nrow.getCell(2);
if(cell != null)
{
String cellValue = cell.getStringCellValue();
if(cell1 != null)
{
cellValue+=":";
cellValue+=cell1.getStringCellValue();
}
return cellValue;
}
return null;
}
}

@ -1 +0,0 @@
sonar-scanner.bat -D"sonar.projectKey=tsq" -D"sonar.sources=User" -D"sonar.host.url=http://localhost:9000" -D"sonar.login=sqp_cfe53f4667e9c83129469f7a698d2f74f5ef73ad"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

@ -1,4 +0,0 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="@color/blue" />
<item android:color="@color/grey"/>
</selector>

@ -1,28 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false">
<shape android:shape="rectangle" >
<!-- 填充的颜色 -->
<solid android:color="@color/white"></solid>
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="1dip" />
<!-- stroke 设置边框显示 -->
<!-- paddingButton里面的文字与Button边界的间隔 -->
<padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" />
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="rectangle" >
<!-- 填充的颜色 -->
<solid android:color="@color/grey"></solid>
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="1dip" />
<!-- stroke 设置边框显示 -->
<!-- paddingButton里面的文字与Button边界的间隔 -->
<padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" />
</shape>
<color android:color="@color/grey" /> <!-- 点击时的背景颜色 -->
</item>
<item>
<color android:color="#FFFFFF" /> <!-- 默认状态下的背景颜色 -->
</item>
</selector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

@ -1,4 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="23dp"/> <!-- 设置圆角半径,根据需要调整数值 -->
<solid android:color="@color/white"></solid>
</shape>

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle" >
<!-- 填充的颜色 -->
<solid android:color="@color/grey"></solid>
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="10dip" />
<!-- paddingButton里面的文字与Button边界的间隔 -->
<padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" />
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle" >
<!-- 填充的颜色 -->
<solid android:color="@color/blue"></solid>
<!-- 设置按钮的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="10dip" />
<!-- stroke 设置边框显示 -->
<stroke
android:dashGap="0dp"
android:width="1dp"
android:color="@color/grey" />
<!-- paddingButton里面的文字与Button边界的间隔 -->
<padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" />
</shape>
</item>
</selector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="-4dp"
android:right="-4dp"
android:top="-4dp">
<shape>
<stroke
android:width="3dp"
android:color="#078EFA" />
</shape>
</item>
</layer-list>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="-4dp"
android:right="-4dp"
android:top="-4dp">
<shape>
<stroke
android:width="3dp"
android:color="#F68D2C" />
</shape>
</item>
</layer-list>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="-4dp"
android:right="-4dp"
android:top="-4dp">
<shape android:layout_height="match_parent">
<stroke
android:width="3dp"
android:color="#3C927D" />
</shape>
</item>
</layer-list>

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="-4dp"
android:right="-4dp"
android:top="-4dp">
<shape>
<stroke
android:width="3dp"
android:color="#D92D25" />
</shape>
</item>
</layer-list>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save