diff --git a/src/app/src/main/java/.scannerwork/.sonar_lock b/src/app/src/main/java/.scannerwork/.sonar_lock new file mode 100644 index 0000000..e69de29 diff --git a/src/app/src/main/java/.scannerwork/Test.pdf b/src/app/src/main/java/.scannerwork/Test.pdf new file mode 100644 index 0000000..f39cb46 Binary files /dev/null and b/src/app/src/main/java/.scannerwork/Test.pdf differ diff --git a/src/app/src/main/java/.scannerwork/report-task.txt b/src/app/src/main/java/.scannerwork/report-task.txt new file mode 100644 index 0000000..46e54be --- /dev/null +++ b/src/app/src/main/java/.scannerwork/report-task.txt @@ -0,0 +1,6 @@ +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 diff --git a/src/app/src/main/java/com.zip b/src/app/src/main/java/com.zip new file mode 100644 index 0000000..628eb02 Binary files /dev/null and b/src/app/src/main/java/com.zip differ diff --git a/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapActivity.java b/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapActivity.java new file mode 100644 index 0000000..c68b193 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapActivity.java @@ -0,0 +1,88 @@ +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; + } + +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapActivityViewModel.java b/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapActivityViewModel.java new file mode 100644 index 0000000..8d4a31e --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapActivityViewModel.java @@ -0,0 +1,19 @@ +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 mText; + + public MapActivityViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is dashboard fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapPositioning.java b/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapPositioning.java new file mode 100644 index 0000000..d08612a --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/dashboard/MapPositioning.java @@ -0,0 +1,233 @@ +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 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 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() { + @Override + public void onSuccess(int i, WalkingResultObject walkingResultObject) { + if(walkingParam==null) + { + return ; + } + for(WalkingResultObject.Route route:walkingResultObject.result.routes) + { + List 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 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) { + + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/CameraPreview.java b/src/app/src/main/java/com/example/myapplication/ui/home/CameraPreview.java new file mode 100644 index 0000000..b56634f --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/CameraPreview.java @@ -0,0 +1,170 @@ +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(); + } + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognition.java b/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognition.java new file mode 100644 index 0000000..ed1982a --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognition.java @@ -0,0 +1,59 @@ +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; + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognitionActivity.java b/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognitionActivity.java new file mode 100644 index 0000000..2198ccc --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognitionActivity.java @@ -0,0 +1,119 @@ +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; + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognitionActivityViewModel.java b/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognitionActivityViewModel.java new file mode 100644 index 0000000..055a742 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/GarbageRecognitionActivityViewModel.java @@ -0,0 +1,19 @@ +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 mText; + + public GarbageRecognitionActivityViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is home fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/ImageUploadCallback.java b/src/app/src/main/java/com/example/myapplication/ui/home/ImageUploadCallback.java new file mode 100644 index 0000000..fee15bd --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/ImageUploadCallback.java @@ -0,0 +1,5 @@ +package com.example.myapplication.ui.home; + +public interface ImageUploadCallback { + void onResultChanged(String newResult); +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/ImageUploader.java b/src/app/src/main/java/com/example/myapplication/ui/home/ImageUploader.java new file mode 100644 index 0000000..6ec85f3 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/ImageUploader.java @@ -0,0 +1,118 @@ +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 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(); + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/home/ResultActivity.java b/src/app/src/main/java/com/example/myapplication/ui/home/ResultActivity.java new file mode 100644 index 0000000..2f4f3c9 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/home/ResultActivity.java @@ -0,0 +1,57 @@ +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); + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/index.java b/src/app/src/main/java/com/example/myapplication/ui/index.java new file mode 100644 index 0000000..7ad12ef --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/index.java @@ -0,0 +1,34 @@ +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); + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/ui/notifications/FeedbackUploader.java b/src/app/src/main/java/com/example/myapplication/ui/notifications/FeedbackUploader.java new file mode 100644 index 0000000..4db6055 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/notifications/FeedbackUploader.java @@ -0,0 +1,125 @@ +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 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(); + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedback.java b/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedback.java new file mode 100644 index 0000000..cf72e69 --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedback.java @@ -0,0 +1,100 @@ +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; + } + + + +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedbackActivity.java b/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedbackActivity.java new file mode 100644 index 0000000..847760c --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedbackActivity.java @@ -0,0 +1,124 @@ +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; + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedbackViewModel.java b/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedbackViewModel.java new file mode 100644 index 0000000..6aa646a --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/notifications/UserFeedbackViewModel.java @@ -0,0 +1,19 @@ +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 mText; + + public UserFeedbackViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is notifications fragment"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuiz.java b/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuiz.java new file mode 100644 index 0000000..00ceade --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuiz.java @@ -0,0 +1,98 @@ +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]); + } + + +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuizActivity.java b/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuizActivity.java new file mode 100644 index 0000000..f79499d --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuizActivity.java @@ -0,0 +1,94 @@ +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; + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuizViewModel.java b/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuizViewModel.java new file mode 100644 index 0000000..672a00e --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/quiz/GarbageQuizViewModel.java @@ -0,0 +1,19 @@ +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 mText; + + public GarbageQuizViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("This is new fragment");//根据自己喜欢放界面的测试文字 + } + + public LiveData getText() { + return mText; + } +} diff --git a/src/app/src/main/java/com/example/myapplication/ui/tools/Problem.java b/src/app/src/main/java/com/example/myapplication/ui/tools/Problem.java new file mode 100644 index 0000000..f4d652d --- /dev/null +++ b/src/app/src/main/java/com/example/myapplication/ui/tools/Problem.java @@ -0,0 +1,107 @@ +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 ArrayListquestion;//存储对应的问题 + + private ArrayList 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 + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/camera.png b/src/app/src/main/res/drawable/camera.png new file mode 100644 index 0000000..9e40feb Binary files /dev/null and b/src/app/src/main/res/drawable/camera.png differ diff --git a/src/app/src/main/res/drawable/capture_photo.jpg b/src/app/src/main/res/drawable/capture_photo.jpg new file mode 100644 index 0000000..10a3b94 Binary files /dev/null and b/src/app/src/main/res/drawable/capture_photo.jpg differ diff --git a/src/app/src/main/res/drawable/checkbox_rounded_corner.xml b/src/app/src/main/res/drawable/checkbox_rounded_corner.xml new file mode 100644 index 0000000..e7579c0 --- /dev/null +++ b/src/app/src/main/res/drawable/checkbox_rounded_corner.xml @@ -0,0 +1,4 @@ + + + + diff --git a/src/app/src/main/res/drawable/circle_button.xml b/src/app/src/main/res/drawable/circle_button.xml new file mode 100644 index 0000000..f188386 --- /dev/null +++ b/src/app/src/main/res/drawable/circle_button.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/garbage_quiz.png b/src/app/src/main/res/drawable/garbage_quiz.png new file mode 100644 index 0000000..1a4a97a Binary files /dev/null and b/src/app/src/main/res/drawable/garbage_quiz.png differ diff --git a/src/app/src/main/res/drawable/go.png b/src/app/src/main/res/drawable/go.png new file mode 100644 index 0000000..d6fef0e Binary files /dev/null and b/src/app/src/main/res/drawable/go.png differ diff --git a/src/app/src/main/res/drawable/groundimage.webp b/src/app/src/main/res/drawable/groundimage.webp new file mode 100644 index 0000000..333b74c Binary files /dev/null and b/src/app/src/main/res/drawable/groundimage.webp differ diff --git a/src/app/src/main/res/drawable/hazard_result.png b/src/app/src/main/res/drawable/hazard_result.png new file mode 100644 index 0000000..109f896 Binary files /dev/null and b/src/app/src/main/res/drawable/hazard_result.png differ diff --git a/src/app/src/main/res/drawable/ic.png b/src/app/src/main/res/drawable/ic.png new file mode 100644 index 0000000..a0bd926 Binary files /dev/null and b/src/app/src/main/res/drawable/ic.png differ diff --git a/src/app/src/main/res/drawable/kitchen_garbage.jpg b/src/app/src/main/res/drawable/kitchen_garbage.jpg new file mode 100644 index 0000000..2589c4b Binary files /dev/null and b/src/app/src/main/res/drawable/kitchen_garbage.jpg differ diff --git a/src/app/src/main/res/drawable/kitchen_result.png b/src/app/src/main/res/drawable/kitchen_result.png new file mode 100644 index 0000000..8e37162 Binary files /dev/null and b/src/app/src/main/res/drawable/kitchen_result.png differ diff --git a/src/app/src/main/res/drawable/launch_logo.png b/src/app/src/main/res/drawable/launch_logo.png new file mode 100644 index 0000000..eca105b Binary files /dev/null and b/src/app/src/main/res/drawable/launch_logo.png differ diff --git a/src/app/src/main/res/drawable/lrx.xml b/src/app/src/main/res/drawable/lrx.xml new file mode 100644 index 0000000..47029a5 --- /dev/null +++ b/src/app/src/main/res/drawable/lrx.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/my_location.png b/src/app/src/main/res/drawable/my_location.png new file mode 100644 index 0000000..f6fc8be Binary files /dev/null and b/src/app/src/main/res/drawable/my_location.png differ diff --git a/src/app/src/main/res/drawable/near_trash_bin.png b/src/app/src/main/res/drawable/near_trash_bin.png new file mode 100644 index 0000000..e769407 Binary files /dev/null and b/src/app/src/main/res/drawable/near_trash_bin.png differ diff --git a/src/app/src/main/res/drawable/next_question.png b/src/app/src/main/res/drawable/next_question.png new file mode 100644 index 0000000..bf7af18 Binary files /dev/null and b/src/app/src/main/res/drawable/next_question.png differ diff --git a/src/app/src/main/res/drawable/other_result.png b/src/app/src/main/res/drawable/other_result.png new file mode 100644 index 0000000..17f2cab Binary files /dev/null and b/src/app/src/main/res/drawable/other_result.png differ diff --git a/src/app/src/main/res/drawable/previous_question.png b/src/app/src/main/res/drawable/previous_question.png new file mode 100644 index 0000000..41d967f Binary files /dev/null and b/src/app/src/main/res/drawable/previous_question.png differ diff --git a/src/app/src/main/res/drawable/quiz_background.jpg b/src/app/src/main/res/drawable/quiz_background.jpg new file mode 100644 index 0000000..2dc9bc0 Binary files /dev/null and b/src/app/src/main/res/drawable/quiz_background.jpg differ diff --git a/src/app/src/main/res/drawable/recycle_result.png b/src/app/src/main/res/drawable/recycle_result.png new file mode 100644 index 0000000..8e6c280 Binary files /dev/null and b/src/app/src/main/res/drawable/recycle_result.png differ diff --git a/src/app/src/main/res/drawable/resultofhazardous.jpg b/src/app/src/main/res/drawable/resultofhazardous.jpg new file mode 100644 index 0000000..38f1cbc Binary files /dev/null and b/src/app/src/main/res/drawable/resultofhazardous.jpg differ diff --git a/src/app/src/main/res/drawable/resultofkitchen.png b/src/app/src/main/res/drawable/resultofkitchen.png new file mode 100644 index 0000000..4ec00e3 Binary files /dev/null and b/src/app/src/main/res/drawable/resultofkitchen.png differ diff --git a/src/app/src/main/res/drawable/resultofother.jpg b/src/app/src/main/res/drawable/resultofother.jpg new file mode 100644 index 0000000..75d7666 Binary files /dev/null and b/src/app/src/main/res/drawable/resultofother.jpg differ diff --git a/src/app/src/main/res/drawable/resultofrecycle.jpg b/src/app/src/main/res/drawable/resultofrecycle.jpg new file mode 100644 index 0000000..0acc2cb Binary files /dev/null and b/src/app/src/main/res/drawable/resultofrecycle.jpg differ diff --git a/src/app/src/main/res/drawable/text_underline.xml b/src/app/src/main/res/drawable/text_underline.xml new file mode 100644 index 0000000..677a190 --- /dev/null +++ b/src/app/src/main/res/drawable/text_underline.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/text_underline1.xml b/src/app/src/main/res/drawable/text_underline1.xml new file mode 100644 index 0000000..b3e724a --- /dev/null +++ b/src/app/src/main/res/drawable/text_underline1.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/text_underline2.xml b/src/app/src/main/res/drawable/text_underline2.xml new file mode 100644 index 0000000..5fad0f5 --- /dev/null +++ b/src/app/src/main/res/drawable/text_underline2.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/text_underline3.xml b/src/app/src/main/res/drawable/text_underline3.xml new file mode 100644 index 0000000..acf13e8 --- /dev/null +++ b/src/app/src/main/res/drawable/text_underline3.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/text_underline4.xml b/src/app/src/main/res/drawable/text_underline4.xml new file mode 100644 index 0000000..d18506b --- /dev/null +++ b/src/app/src/main/res/drawable/text_underline4.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/app/src/main/res/drawable/textarea.xml b/src/app/src/main/res/drawable/textarea.xml new file mode 100644 index 0000000..a1fa932 --- /dev/null +++ b/src/app/src/main/res/drawable/textarea.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/src/app/src/main/res/drawable/trash_bin_button.xml b/src/app/src/main/res/drawable/trash_bin_button.xml new file mode 100644 index 0000000..30da113 --- /dev/null +++ b/src/app/src/main/res/drawable/trash_bin_button.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/src/app/src/main/res/drawable/upload.png b/src/app/src/main/res/drawable/upload.png new file mode 100644 index 0000000..d1401db Binary files /dev/null and b/src/app/src/main/res/drawable/upload.png differ diff --git a/src/app/src/main/res/drawable/user_confirm.png b/src/app/src/main/res/drawable/user_confirm.png new file mode 100644 index 0000000..7d29d32 Binary files /dev/null and b/src/app/src/main/res/drawable/user_confirm.png differ diff --git a/src/app/src/main/res/font/hkzykt.ttf b/src/app/src/main/res/font/hkzykt.ttf new file mode 100644 index 0000000..b7d487d Binary files /dev/null and b/src/app/src/main/res/font/hkzykt.ttf differ diff --git a/src/app/src/main/res/font/tqkt.ttf b/src/app/src/main/res/font/tqkt.ttf new file mode 100644 index 0000000..036c586 Binary files /dev/null and b/src/app/src/main/res/font/tqkt.ttf differ diff --git a/src/app/src/main/res/font/wrxk.TTF b/src/app/src/main/res/font/wrxk.TTF new file mode 100644 index 0000000..ff0faca Binary files /dev/null and b/src/app/src/main/res/font/wrxk.TTF differ diff --git a/src/app/src/main/res/layout/capture.xml b/src/app/src/main/res/layout/capture.xml new file mode 100644 index 0000000..299ed0f --- /dev/null +++ b/src/app/src/main/res/layout/capture.xml @@ -0,0 +1,35 @@ + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/layout/confirm_photo.xml b/src/app/src/main/res/layout/confirm_photo.xml new file mode 100644 index 0000000..cedeb92 --- /dev/null +++ b/src/app/src/main/res/layout/confirm_photo.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/layout/face_layout.xml b/src/app/src/main/res/layout/face_layout.xml new file mode 100644 index 0000000..3d9ecaf --- /dev/null +++ b/src/app/src/main/res/layout/face_layout.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/app/src/main/res/layout/garbage_quiz.xml b/src/app/src/main/res/layout/garbage_quiz.xml new file mode 100644 index 0000000..d30aecf --- /dev/null +++ b/src/app/src/main/res/layout/garbage_quiz.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + +