Wyczyść kod; dodaj komentarze w niektórych miejscach; usuń obsługiwanie sytuacji braku internetu w Popup

This commit is contained in:
Kacper Dudzic 2020-02-27 00:15:31 +01:00
parent fb34c8286a
commit 0b65e9fe38
20 changed files with 102 additions and 265 deletions

View File

@ -4,7 +4,6 @@
<uses-permission-sdk-23 android:name="android.permission.CAMERA" /> <uses-permission-sdk-23 android:name="android.permission.CAMERA" />
<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application <application
@ -37,7 +36,6 @@
android:theme="@style/NoBar"> android:theme="@style/NoBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@ -4,7 +4,7 @@ import java.io.IOException;
public class CheckInternet { public class CheckInternet {
//https://stackoverflow.com/a/27312494/12566206 //rozwiązanie zaczerpnięte z https://stackoverflow.com/a/27312494/12566206
public boolean isOnline() { public boolean isOnline() {
Runtime runtime = Runtime.getRuntime(); Runtime runtime = Runtime.getRuntime();
try { try {
@ -12,8 +12,8 @@ public class CheckInternet {
int exitValue = ipProcess.waitFor(); int exitValue = ipProcess.waitFor();
return (exitValue == 0); return (exitValue == 0);
} }
catch (IOException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //próba odczytywania danych z internetu, gdy w międzyczasie utraciliśmy połączenie
catch (InterruptedException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } //czymś przerwano wątkowi
return false; return false;
} }
} }

View File

@ -2,12 +2,8 @@ package com.example.lookifyv2;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
@ -35,7 +31,6 @@ import java.util.ArrayList;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import static org.opencv.imgproc.Imgproc.ADAPTIVE_THRESH_MEAN_C;
import static org.opencv.imgproc.Imgproc.THRESH_BINARY; import static org.opencv.imgproc.Imgproc.THRESH_BINARY;
public class Decode extends AppCompatActivity { public class Decode extends AppCompatActivity {
@ -45,11 +40,9 @@ public class Decode extends AppCompatActivity {
String filePath; String filePath;
Mat matPic; Mat matPic;
Mat matPicG;
Mat matPicGB;
Mat matPicGBT;
//OpenCV domyślnie uruchamia się po onCreate co powoduje problemy - zapobiegamy więc temu //OpenCV domyślnie uruchamia się po onCreate co powoduje problemy - zapobiegamy więc temu, zapewniając, by metoda wykorzystująca OpenCV
//uruchamiała się dopiero po jego pomyślnym załadowaniu
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override @Override
public void onManagerConnected(int status) { public void onManagerConnected(int status) {
@ -75,6 +68,7 @@ public class Decode extends AppCompatActivity {
public void decodePic() { public void decodePic() {
//Obsługa sytuacji, w której nie ma dostępu do internetu
CheckInternet check = new CheckInternet(); CheckInternet check = new CheckInternet();
if(!check.isOnline()){ if(!check.isOnline()){
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
@ -104,16 +98,15 @@ public class Decode extends AppCompatActivity {
//Usuwanie "noise'u" przy jednoczesnym zachowywaniu ostrych krawędzi za pomocą bilateralnego filtru //Usuwanie "noise'u" przy jednoczesnym zachowywaniu ostrych krawędzi za pomocą bilateralnego filtru
Imgproc.bilateralFilter(matPicG, matPicGB, 5, 75, 75); Imgproc.bilateralFilter(matPicG, matPicGB, 5, 75, 75);
//Zwiększanie kontrastu za pomocą thresholdu(wartości adaptywnego zaczerpnięte z https://stackoverflow.com/questions/31289895/threshold-image-using-opencv-java) //Zwiększanie kontrastu za pomocą thresholdu
//Imgproc.adaptiveThreshold(matPicGB, matPicGBT, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, 40);
Imgproc.threshold(matPicGB, matPicGBT, 100, 255, THRESH_BINARY); Imgproc.threshold(matPicGB, matPicGBT, 100, 255, THRESH_BINARY);
Bitmap bMap = Bitmap.createBitmap(matPicGBT.width(), matPicGBT.height(), Bitmap.Config.ARGB_8888); //przygotowywanie mapy bitowej, którą przeskanuje ZXing w poszukiwaniu kodu
Bitmap bMap = Bitmap.createBitmap(matPicGBT.width(), matPicGBT.height(), Bitmap.Config.ARGB_8888); //zwykła mapa wbudowana w jave/android studio
Utils.matToBitmap(matPicGBT, bMap); Utils.matToBitmap(matPicGBT, bMap);
int[] intArray = new int[bMap.getWidth() * bMap.getHeight()]; int[] intArray = new int[bMap.getWidth() * bMap.getHeight()];
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight()); bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray); LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray); //zamienia różne formaty map na jedną spójną postać; pozwala wykonać nastepny krok
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
//Zwiększanie efektywności wykrywania kodów //Zwiększanie efektywności wykrywania kodów
@ -140,7 +133,7 @@ public class Decode extends AppCompatActivity {
hints.put(DecodeHintType.TRY_HARDER, true); hints.put(DecodeHintType.TRY_HARDER, true);
int reminder = 0; int reminder = 0;
//Szukanie kodu na wczytanym zdjęciu //Szukanie kodu na wczytanym zdjęciu i podejmowanie odpowiednich działań w zależności od tego, czy został znaleziony, czy nie
MultiFormatReader reader = new MultiFormatReader(); MultiFormatReader reader = new MultiFormatReader();
String contents = null; String contents = null;
try { try {
@ -155,10 +148,8 @@ public class Decode extends AppCompatActivity {
finish(); finish();
} }
if(reminder == 0) { if(reminder == 0) {
Toast.makeText(this, "Zidentyfikowany kod: " + contents, Toast.makeText(this, "Zidentyfikowany kod: " + contents,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
Intent intent_Results = new Intent(this, Results.class); Intent intent_Results = new Intent(this, Results.class);
intent_Results.putExtra("decodedcode", contents); intent_Results.putExtra("decodedcode", contents);
startActivity(intent_Results); startActivity(intent_Results);
@ -166,7 +157,7 @@ public class Decode extends AppCompatActivity {
} }
} }
//Druga część potrzebna do ładowania OpenCV w odpowiednim momencie //Druga część potrzebna do ładowania OpenCV w odpowiednim momencie, czyli gdy aplikacja była zminimalizowana, a teraz zostaje z powrotem zmaksymalizowana
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();

View File

@ -11,7 +11,6 @@ import android.widget.TextView;
public class DecodeFail extends AppCompatActivity { public class DecodeFail extends AppCompatActivity {
private Button button_tryagain;
String status; String status;
@Override @Override
@ -22,11 +21,12 @@ public class DecodeFail extends AppCompatActivity {
assert getSupportActionBar() != null; assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//Pobieranie informacji o rodzaju błędu od Decode i wyświetlanie odpowiedniego komunikatu w zależności od tego rodzaju
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
status = extras.getString("status"); status = extras.getString("status");
showMessage(status); showMessage(status);
button_tryagain = findViewById(R.id.try_again_button); Button button_tryagain = findViewById(R.id.try_again_button);
button_tryagain.getBackground().setColorFilter(0xFF67BAFF, PorterDuff.Mode.MULTIPLY); button_tryagain.getBackground().setColorFilter(0xFF67BAFF, PorterDuff.Mode.MULTIPLY);
button_tryagain.setOnClickListener(new View.OnClickListener() { button_tryagain.setOnClickListener(new View.OnClickListener() {
@Override @Override

View File

@ -1,7 +1,6 @@
package com.example.lookifyv2; package com.example.lookifyv2;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -9,7 +8,6 @@ import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
@ -120,6 +118,8 @@ public class Favourites extends AppCompatActivity {
asyncTask.execute(); asyncTask.execute();
} }
//z preferencji odczytywane kody obserwowanych produktów, jeśli nie ma żadnego wyświetlana jest odpowiednia wiadomość
//następnie pozycje kodów na liscie products ustalane i za ich pomocą odpowiednie elementy tej listy kopiowane do nowej listy z obserwowanymi
private void getFavourites() { private void getFavourites() {
SharedPreferences pref = MyApplication.getInstance().getSharedPreferences("Favourites", 0); SharedPreferences pref = MyApplication.getInstance().getSharedPreferences("Favourites", 0);
Map<String, ?> codes = pref.getAll(); Map<String, ?> codes = pref.getAll();

View File

@ -17,18 +17,15 @@ import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.ViewHolder>{ public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.ViewHolder>{
private Context context; private Context context;
private List<Product> products; private List<Product> products;
public FavouritesAdapter(Context context, List<Product> products) { FavouritesAdapter(Context context, List<Product> products) {
this.context = context; this.context = context;
this.products = products; this.products = products;
} }
@ -92,6 +89,8 @@ public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.Vi
this.pos=pos; this.pos=pos;
} }
//Pierwszy case to usuwanie produktu z obserwowanych. By odświeżyć widok po usunięciu zamykane
// ona i powiązane z nią activity, a ona sama uruchamiana ponownie
@Override @Override
public boolean onMenuItemClick(MenuItem menuItem) { public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) { switch (menuItem.getItemId()) {
@ -102,7 +101,8 @@ public class FavouritesAdapter extends RecyclerView.Adapter<FavouritesAdapter.Vi
editor.apply(); editor.apply();
Intent intent_Favourites = new Intent(context, Favourites.class); Intent intent_Favourites = new Intent(context, Favourites.class);
intent_Favourites.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent_Favourites.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //niszczy i powiązane activity, dzięki czemu przy kolejnym
//uruchomieniu favourites nie widać już usuniętych kafelków
context.startActivity(intent_Favourites); context.startActivity(intent_Favourites);
Toast.makeText(context, "Produkt \"" + products.get(pos).getproductName() + "\" został usunięty z Obserwowanych.", Toast.makeText(context, "Produkt \"" + products.get(pos).getproductName() + "\" został usunięty z Obserwowanych.",

View File

@ -2,7 +2,8 @@ package com.example.lookifyv2;
import android.app.Application; import android.app.Application;
//https://stackoverflow.com/a/12405879/12566206 //Umożliwia uzyskanie globalnego kontekstu aplikacji klasom, które nie activity. Obiekt Application tworzony jest
//przed powstaniem jakiegokolwiek obiektu activity i trwa przez cały cykl życia aplikacji. Rozwiązanie z https://stackoverflow.com/a/12405879/12566206
public class MyApplication extends Application { public class MyApplication extends Application {
private static MyApplication instance; private static MyApplication instance;

View File

@ -1,14 +1,12 @@
package com.example.lookifyv2; package com.example.lookifyv2;
import android.os.Bundle;
import android.text.Html;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.text.Html;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
public class Popup extends AppCompatActivity { public class Popup extends AppCompatActivity {
@ -21,23 +19,6 @@ public class Popup extends AppCompatActivity {
assert getSupportActionBar() != null; assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
CheckInternet check = new CheckInternet();
if(!check.isOnline()){
TextView nointernetmessage = findViewById(R.id.popupnointernetmessage);
nointernetmessage.setVisibility(View.VISIBLE);
Button button_refresh;
button_refresh = findViewById(R.id.popuprefresh_button);
button_refresh.getBackground().setColorFilter(0xFF67BAFF, PorterDuff.Mode.MULTIPLY);
button_refresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
recreate();
}
});
button_refresh.setVisibility(View.VISIBLE);
}
ImageView productImage = findViewById(R.id.productimagedet); ImageView productImage = findViewById(R.id.productimagedet);
TextView productCode = findViewById(R.id.productcodedet); TextView productCode = findViewById(R.id.productcodedet);
TextView productName = findViewById(R.id.productnamedet); TextView productName = findViewById(R.id.productnamedet);
@ -49,6 +30,7 @@ public class Popup extends AppCompatActivity {
Bundle bundle = this.getIntent().getExtras(); Bundle bundle = this.getIntent().getExtras();
//do załadowania obrazka używana jest zewnętrzna biblioteka Glide
Glide.with(this).load((String) bundle.getSerializable("productimage")).into(productImage); Glide.with(this).load((String) bundle.getSerializable("productimage")).into(productImage);
productCode.setText(Html.fromHtml("<b>" + "Kod produktu:" + "</b> " + bundle.getSerializable("productcode"))); productCode.setText(Html.fromHtml("<b>" + "Kod produktu:" + "</b> " + bundle.getSerializable("productcode")));

View File

@ -1,16 +1,8 @@
package com.example.lookifyv2; package com.example.lookifyv2;
import androidx.appcompat.app.AppCompatActivity; //klasa stworzona na podstawie podobnej z http://androidbash.com/connecting-android-app-to-a-database-using-php-and-mysql/
//jest po prostu obiektem produktu ze wszystkimi jego danymi i metodami te dane zwracającymi
import android.os.Bundle; public class Product{
public class Product extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product);
}
private int id; private int id;
private String imageLink; private String imageLink;
@ -24,10 +16,8 @@ public class Product extends AppCompatActivity {
private String productType; private String productType;
private String productSex; private String productSex;
Product(int id, String productCode, String productName, String imageLink, String productPrice, String productRetailer,
public Product(int id, String productCode, String productName, String imageLink, String productPrice, String productRetailer,
String productColour, String productStyle, String productCollection, String productType, String productSex) { String productColour, String productStyle, String productCollection, String productType, String productSex) {
this.id = id; this.id = id;
this.imageLink = imageLink; this.imageLink = imageLink;
this.productPrice = productPrice; this.productPrice = productPrice;
@ -44,73 +34,16 @@ public class Product extends AppCompatActivity {
public int getId() { public int getId() {
return id; return id;
} }
public void setId(int id) { String getImageLink() { return imageLink; }
this.id = id; String getproductPrice() { return productPrice; }
} String getproductCode() {
public String getImageLink() {
return imageLink;
}
public void setImageLink(String imageLink) {
this.imageLink = imageLink;
}
public String getproductPrice() {
return productPrice;
}
public void setproductPrice(String productPrice) {
this.productPrice = productPrice;
}
public String getproductCode() {
return productCode; return productCode;
} }
public void setproductCode(String productCode) { String getproductName() { return productName; }
this.productCode = productCode; String getproductRetailer() { return productRetailer; }
} String getproductColour() { return productColour; }
String getproductStyle() { return productStyle; }
public String getproductName() { String getproductCollection() { return productCollection; }
return productName; String getproductType() { return productType; }
} String getproductSex() { return productSex; }
public void setproductName(String productName) {
this.productName = productName;
}
public String getproductRetailer() {
return productRetailer;
}
public void setproductRetailer(String productRetailer) { this.productRetailer = productRetailer; }
public String getproductColour() {
return productColour;
}
public void setproductColour(String productColour) {
this.productColour = productColour;
}
public String getproductStyle() {
return productStyle;
}
public void setproductStyle(String productStyle) {
this.productStyle = productStyle;
}
public String getproductCollection() {
return productCollection;
}
public void setproductCollection(String productCollection) { this.productCollection = productCollection; }
public String getproductType() {
return productType;
}
public void setproductType(String productType) {
this.productType = productType;
}
public String getproductSex() {
return productSex;
}
public void setproductSex(String productSex) {
this.productSex = productSex;
}
} }

View File

@ -1,7 +1,5 @@
package com.example.lookifyv2; package com.example.lookifyv2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
@ -30,14 +28,14 @@ public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ViewHo
private Context context; private Context context;
private List<Product> products; private List<Product> products;
public ProductsAdapter(Context context, List<Product> products) { ProductsAdapter(Context context, List<Product> products) {
this.context = context; this.context = context;
this.products = products; this.products = products;
} }
//viewholder przechowuje dane viewów, by nie musieć za każdym razem ich pojedynczo wypełniać
@Override @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card,parent,false); View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card,parent,false);
return new ViewHolder(itemView); return new ViewHolder(itemView);
@ -59,12 +57,12 @@ public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ViewHo
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public ImageView imageView; ImageView imageView;
public TextView productName; TextView productName;
public TextView productPrice; TextView productPrice;
public TextView productRetailer; TextView productRetailer;
public ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
imageView = itemView.findViewById(R.id.productimage); imageView = itemView.findViewById(R.id.productimage);
imageView.setOnClickListener(this); imageView.setOnClickListener(this);
@ -90,10 +88,11 @@ public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.ViewHo
class MenuClickListener implements PopupMenu.OnMenuItemClickListener { class MenuClickListener implements PopupMenu.OnMenuItemClickListener {
Integer pos; Integer pos;
public MenuClickListener(int pos) { MenuClickListener(int pos) {
this.pos=pos; this.pos=pos;
} }
//Zasadniczo dzieje się tutaj to samo, co w przypadku przycisków w Results
@Override @Override
public boolean onMenuItemClick(MenuItem menuItem) { public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) { switch (menuItem.getItemId()) {

View File

@ -1,16 +1,11 @@
package com.example.lookifyv2; package com.example.lookifyv2;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.os.Bundle;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
@ -18,12 +13,11 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
@ -42,13 +36,11 @@ import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
//klasa napisana z pomocą tutorialu z http://androidbash.com/connecting-android-app-to-a-database-using-php-and-mysql/
public class Results extends AppCompatActivity { public class Results extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private List<Product> products; private List<Product> products;
private List<Product> productstop6; private List<Product> productstop6;
private RecyclerView recyclerView;
private GridLayoutManager gridLayout;
private ProductsAdapter adapter; private ProductsAdapter adapter;
String decodedCode; String decodedCode;
Button button_favourite; Button button_favourite;
@ -62,15 +54,15 @@ public class Results extends AppCompatActivity {
assert getSupportActionBar() != null; assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
recyclerView = findViewById(R.id.recyclerview); RecyclerView recyclerView = findViewById(R.id.recyclerview);
products = new ArrayList<>(); products = new ArrayList<>();
productstop6 = new ArrayList<>(); productstop6 = new ArrayList<>();
getProductsFromDB(); getProductsFromDB(); //ładuje wszystkie produktu z bazy do listy products, a następnie najbardziej podobne 6 do productstop6
gridLayout = new GridLayoutManager(this, 2); GridLayoutManager gridLayout = new GridLayoutManager(this, 2); //recyclerview do implementacji potrzebuje managera, spancount to w praktyce wielkość kafelków
recyclerView.setLayoutManager(gridLayout); recyclerView.setLayoutManager(gridLayout);
adapter = new ProductsAdapter(this, productstop6); adapter = new ProductsAdapter(this, productstop6); //adapter ładuje dane z jakiegoś datasetu aplikacji do kafelków
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
} }
@ -80,7 +72,7 @@ public class Results extends AppCompatActivity {
@Override @Override
protected Void doInBackground(Void... Void) { protected Void doInBackground(Void... Void) {
OkHttpClient client = new OkHttpClient(); OkHttpClient client = new OkHttpClient(); //zewnętrzna biblioteka wykorzystana do nawiązania połączenia
Request request = new Request.Builder().url("http://192.168.0.87/products.php?id=0").build(); Request request = new Request.Builder().url("http://192.168.0.87/products.php?id=0").build();
try { try {
Response response = client.newCall(request).execute(); Response response = client.newCall(request).execute();
@ -109,14 +101,15 @@ public class Results extends AppCompatActivity {
return null; return null;
} }
//dopiero po utworzeniu listy wszystkich produktów po stronie aplikacji wykonywane dalsze operacje, stąd onPostExecute
@Override @Override
protected void onPostExecute(Void aVoid) { protected void onPostExecute(Void aVoid) {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged(); //w praktyce informuje adapter, by odświeżył view którym zarząda, bo zmieniły się dane
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
decodedCode = extras.getString("decodedcode"); decodedCode = extras.getString("decodedcode");
//ustalana jest lokacja zeskanowanego kodu w bazie; jeśli go tam nie ma to następuje przeniesienie do ekranu błędu
int foundPosition = -1; int foundPosition = -1;
for(int i = 0; i < products.size(); i++){ for(int i = 0; i < products.size(); i++){
if(decodedCode.equals(products.get(i).getproductCode())){ if(decodedCode.equals(products.get(i).getproductCode())){
@ -160,7 +153,7 @@ public class Results extends AppCompatActivity {
} }
}); });
getRecommendedProducts(finalFoundPosition); getRecommendedProducts(finalFoundPosition); //zapełniane jest productstop6
} }
}; };
asyncTask.execute(); asyncTask.execute();
@ -185,6 +178,8 @@ public class Results extends AppCompatActivity {
startActivity(intent_Details); startActivity(intent_Details);
} }
//do zapisywania obserwowanych produktów wykorzystany został niekonwencjonalnie depozyt preferencji użytkownika
//sprawdzana jest obecność kodu w depozycie i podejmowana odpowiednia akcja: albo dodanie go, albo wyświetlenie informacji, że już jest dodany
public void addFavourite(Context context, int position){ public void addFavourite(Context context, int position){
SharedPreferences pref = MyApplication.getInstance().getSharedPreferences("Favourites", 0); SharedPreferences pref = MyApplication.getInstance().getSharedPreferences("Favourites", 0);
SharedPreferences.Editor editor = pref.edit(); SharedPreferences.Editor editor = pref.edit();
@ -201,12 +196,13 @@ public class Results extends AppCompatActivity {
} }
if(checker == 0){ if(checker == 0){
editor.putBoolean(products.get(position).getproductCode(), true); editor.putBoolean(products.get(position).getproductCode(), true);
editor.apply(); //commit? editor.apply();
Toast.makeText(context, "Produkt \"" + products.get(position).getproductName() + "\" został dodany do Obserwowanych.", Toast.makeText(context, "Produkt \"" + products.get(position).getproductName() + "\" został dodany do Obserwowanych.",
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
} }
} }
//Prostu algorytm jest wykorzystywany, by stworzyć ranking produktów podobne do tego zeskanowanego. Można znacznie rozbudować.
private void getRecommendedProducts(int foundpos){ private void getRecommendedProducts(int foundpos){
HashMap<Integer, Integer> ranking = new HashMap<>(); HashMap<Integer, Integer> ranking = new HashMap<>();
for(int i = 0; i < products.size(); i++) { for(int i = 0; i < products.size(); i++) {
@ -229,6 +225,8 @@ public class Results extends AppCompatActivity {
} }
} }
//Odpowiednia informacja wyświetlana jest, jeśli nie znaleziono podobnych produktów.
//Do sortowania rankingu wykorzystywana jest zewnętrzna biblioteka Guava.
if(ranking.size() == 0){ if(ranking.size() == 0){
TextView noproductsmessage = findViewById(R.id.noproductsmessage); TextView noproductsmessage = findViewById(R.id.noproductsmessage);
noproductsmessage.setVisibility(View.VISIBLE); noproductsmessage.setVisibility(View.VISIBLE);
@ -236,12 +234,12 @@ public class Results extends AppCompatActivity {
else{ else{
Ordering<Map.Entry<Integer, Integer>> byMapValues = new Ordering<Map.Entry<Integer, Integer>>() { Ordering<Map.Entry<Integer, Integer>> byMapValues = new Ordering<Map.Entry<Integer, Integer>>() {
@Override @Override
public int compare(Map.Entry<Integer, Integer> left, Map.Entry<Integer, Integer> right) { public int compare(Map.Entry<Integer, Integer> left, Map.Entry<Integer, Integer> right) { //ustalany jest sposób sortowania
return left.getValue().compareTo(right.getValue()); return left.getValue().compareTo(right.getValue());
} }
}; };
List<Map.Entry<Integer, Integer>> rankinglist = Lists.newArrayList(ranking.entrySet()); //tworzona jest lista z zawartością mapy,
List<Map.Entry<Integer, Integer>> rankinglist = Lists.newArrayList(ranking.entrySet()); //by móc użyć metody sort (ze zdefiniowanym sposobem sortowania)
Collections.sort(rankinglist, byMapValues.reverse()); Collections.sort(rankinglist, byMapValues.reverse());
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {

View File

@ -13,7 +13,6 @@ import java.io.File;
//klasa napisana z pomocą tutorialu dostępnego na https://androidkennel.org/android-camera-access-tutorial/ //klasa napisana z pomocą tutorialu dostępnego na https://androidkennel.org/android-camera-access-tutorial/
public class TakePhoto extends AppCompatActivity { public class TakePhoto extends AppCompatActivity {
private Uri photoFileUri;
public File photoFile; public File photoFile;
String path; String path;
@ -28,15 +27,15 @@ public class TakePhoto extends AppCompatActivity {
public void openCamera() { public void openCamera() {
Intent intent_Camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Intent intent_Camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoFile = getOutputMediaFile(); photoFile = getOutputMediaFile();
photoFileUri = Uri.fromFile(photoFile); Uri photoFileUri = Uri.fromFile(photoFile);
intent_Camera.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri); intent_Camera.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri);
startActivityForResult(intent_Camera, 100); startActivityForResult(intent_Camera, 100); //w przeciwieństwie do startActivity zwraca wynik w postaci Intentu odbieranego poniżej
} }
//Jeśli moduł kamery zostanie zamknięty zanim zrobione zostanie zdjęcie to activity skanowania się kończy, w innym razie przechodzi dalej //Jeśli moduł kamery zostanie zamknięty zanim zrobione zostanie zdjęcie to activity skanowania się kończy, w innym razie przechodzi dalej
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); //?????????????? super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100) { if (requestCode == 100) {
if (resultCode == RESULT_CANCELED) { if (resultCode == RESULT_CANCELED) {
finish(); finish();

View File

@ -3,7 +3,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="#67BAFF" android:background="#67BAFF"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools" xmlns:card_view="http://schemas.android.com/tools"
> >

View File

@ -20,7 +20,6 @@
<ImageView <ImageView
android:id="@+id/logoname" android:id="@+id/logoname"
android:layout_width="268dp" android:layout_width="268dp"
android:layout_height="84dp" android:layout_height="84dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"

View File

@ -6,37 +6,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView
android:id="@+id/popupnointernetmessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="132dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:gravity="center"
android:text="Nie udało się załadować obrazka, błąd przy łączeniu z internetem!"
android:textColor="#000000"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/productimagedet" />
<Button
android:id="@+id/popuprefresh_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Odśwież"
android:textColor="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/popupnointernetmessage"
android:visibility="gone"/>
<ImageView <ImageView
android:id="@+id/productimagedet" android:id="@+id/productimagedet"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Product">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductsAdapter">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,20 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".TakePhoto"> tools:context=".TakePhoto">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dalej"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,3 +1,3 @@
<resources> <resources>
<string name="app_name">Lookifyv2</string> <string name="app_name">Lookify</string>
</resources> </resources>

View File

@ -9,7 +9,6 @@
</style> </style>
<style name="NoBar" parent="Theme.AppCompat.Light.NoActionBar"> <style name="NoBar" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>