From bfcc9178ee51b3dd58eb556a5d2a53ca792d5ef5 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Tue, 2 Jan 2024 22:56:30 +0100 Subject: [PATCH 01/12] Update activity_about.xml --- app/src/main/res/layout/activity_about.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 28d0504..58e274b 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -72,7 +72,7 @@ android:layout_marginTop="20dp" android:layout_marginBottom="5dp" - android:text="Libraries" + android:text="Open source libraries" android:textSize="25sp" /> Date: Sat, 27 Jan 2024 20:44:07 +0100 Subject: [PATCH 02/12] Added Drag and Drop feature Drag JSON file and drop it into the app to open it --- app/src/main/AndroidManifest.xml | 3 +- .../java/com/sjapps/jsonlist/FileSystem.java | 12 +- .../com/sjapps/jsonlist/MainActivity.java | 104 +++++++++++++++--- app/src/main/res/layout/activity_main.xml | 34 ++++++ app/src/main/res/values/strings.xml | 2 + 5 files changed, 134 insertions(+), 21 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0cdb808..f0595c7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,12 +18,13 @@ + diff --git a/app/src/main/java/com/sjapps/jsonlist/FileSystem.java b/app/src/main/java/com/sjapps/jsonlist/FileSystem.java index 2f8719c..c0a0639 100644 --- a/app/src/main/java/com/sjapps/jsonlist/FileSystem.java +++ b/app/src/main/java/com/sjapps/jsonlist/FileSystem.java @@ -1,14 +1,16 @@ package com.sjapps.jsonlist; +import android.content.Context; import android.content.res.AssetFileDescriptor; import android.net.Uri; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.io.BufferedReader; -import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Path; public class FileSystem { @@ -21,7 +23,7 @@ public static JsonArray loadDataToJsonArray(JsonElement data) { return data.getAsJsonArray(); } - public static String LoadDataFromFile(MainActivity mainActivity, Uri uri) { + public static String LoadDataFromFile(Context context, Uri uri, InputStream inputStream, AssetFileDescriptor fileDescriptor) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { String path = uri.getPath(); @@ -34,18 +36,14 @@ public static String LoadDataFromFile(MainActivity mainActivity, Uri uri) { StringBuilder sb = new StringBuilder(); try { - FileInputStream inputStream = (FileInputStream) mainActivity.getContentResolver().openInputStream(uri); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - - AssetFileDescriptor fileDescriptor = mainActivity.getContentResolver().openAssetFileDescriptor(uri , "r"); - long currentBytes = 0; long fileSize = fileDescriptor.getLength(); String line; while ((line = reader.readLine()) != null) { sb.append(line); currentBytes += line.length(); - mainActivity.updateProgress((int)((currentBytes/(float)fileSize)*100)); + ((MainActivity) context).updateProgress((int)((currentBytes/(float)fileSize)*100)); } fileDescriptor.close(); diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index a75fc33..05ffda1 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -11,13 +11,18 @@ import android.app.Activity; import android.content.Context; +import android.content.ClipData; import android.content.Intent; +import android.content.res.AssetFileDescriptor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.transition.AutoTransition; import android.transition.TransitionManager; import android.util.Log; +import android.util.TypedValue; +import android.view.DragAndDropPermissions; +import android.view.DragEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; @@ -31,6 +36,7 @@ import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -40,13 +46,15 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; + import com.sjapps.about.AboutActivity; import com.sjapps.adapters.ListAdapter; import com.sjapps.jsonlist.java.JsonData; import com.sjapps.jsonlist.java.ListItem; import com.sjapps.library.customdialog.BasicDialog; - +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; @@ -68,6 +76,7 @@ public class MainActivity extends AppCompatActivity { AutoTransition autoTransition = new AutoTransition(); Handler handler = new Handler(); Thread readFileThread; + RelativeLayout dropTarget; @Override protected void onResume() { @@ -101,7 +110,7 @@ protected void onCreate(Bundle savedInstanceState) { dim_bg.setOnClickListener(view -> open_closeMenu()); - Intent intent = getIntent(); + Intent intent = getIntent(); Log.d(TAG, "onCreate: " + intent); if (Intent.ACTION_VIEW.equals(intent.getAction())) { ReadFile(intent.getData()); @@ -109,6 +118,62 @@ protected void onCreate(Bundle savedInstanceState) { if (intent.getAction().equals("android.intent.action.OPEN_FILE")){ ImportFromFile(); } + + dropTarget.setOnDragListener((v, event) -> { + + TextView dropTargetTxt = v.findViewById(R.id.dropTargetText); + View dropTargetBackground = v.findViewById(R.id.dropTargetBackground); + + switch (event.getAction()) { + case DragEvent.ACTION_DRAG_STARTED: + dropTarget.setAlpha(1); + return true; + + case DragEvent.ACTION_DRAG_ENTERED: + if (event.getClipDescription().hasMimeType("application/json")) { + dropTargetBackground.setBackgroundColor(setColor(R.attr.colorPrimary)); + dropTargetBackground.setAlpha(.8f); + }else { + dropTargetTxt.setText(R.string.this_is_not_json_file); + dropTargetBackground.setBackgroundColor(setColor(R.attr.colorError)); + } + return true; + + case DragEvent.ACTION_DRAG_EXITED: + dropTargetTxt.setText(R.string.drop_json_file_here); + dropTargetBackground.setBackgroundColor(setColor(R.attr.colorOnBackground)); + dropTargetBackground.setAlpha(.5f); + return true; + + case DragEvent.ACTION_DRAG_ENDED: + dropTargetTxt.setText(R.string.drop_json_file_here); + dropTargetBackground.setBackgroundColor(setColor(R.attr.colorOnBackground)); + dropTarget.setAlpha(0); + return true; + + case DragEvent.ACTION_DROP: + if (!event.getClipDescription().hasMimeType("application/json")) + return false; + if (readFileThread != null && readFileThread.isAlive()) { + Snackbar.make(getWindow().getDecorView(),"Loading file in progress, try again later", BaseTransientBottomBar.LENGTH_SHORT).show(); + return false; + } + + ClipData.Item item = event.getClipData().getItemAt(0); + + DragAndDropPermissions dropPermissions = null; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) + dropPermissions = requestDragAndDropPermissions(event); + + ReadFile(item.getUri()); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N && dropPermissions != null) + dropPermissions.release(); + + return true; + } + return false; + }); } private void OpenAbout() { @@ -168,6 +233,7 @@ private void initialize() { dim_bg.bringToFront(); menu.bringToFront(); menuBtn.bringToFront(); + dropTarget = findViewById(R.id.dropTarget); } private void open_closeMenu() { @@ -314,21 +380,27 @@ void ReadFile(Uri uri){ } loadingStarted("Reading file"); + try { + InputStream inputStream = getContentResolver().openInputStream(uri); + AssetFileDescriptor fileDescriptor = getContentResolver().openAssetFileDescriptor(uri , "r"); - readFileThread = new Thread(() -> { - String Data = FileSystem.LoadDataFromFile(MainActivity.this, uri); + readFileThread = new Thread(() -> { - if (Data == null) { - Log.d(TAG, "ReadFile: null data"); - return; - } - handler.post(() -> { - LoadData(Data); - }); + String Data = FileSystem.LoadDataFromFile(MainActivity.this, uri, inputStream, fileDescriptor); - }); - readFileThread.start(); + if (Data == null) { + Log.d(TAG, "ReadFile: null data"); + return; + } + handler.post(() -> { + LoadData(Data); + }); + }); + readFileThread.start(); + } catch (IOException e) { + throw new RuntimeException(e); + } } void loadingStarted(){ @@ -379,6 +451,12 @@ void loadingFinished(boolean isFinished){ } + int setColor(int resid){ + TypedValue typedValue = new TypedValue(); + getTheme().resolveAttribute(resid, typedValue, true); + return typedValue.data; + } + public static void setAnimation(Context context, @NonNull View view, @AnimRes int animationRes) { setAnimation(context,view,animationRes,null); } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 18320d3..67736c5 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -164,6 +164,40 @@ + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5d8256b..7ea89ad 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,4 +2,6 @@ Json List Open file Back + Drop JSON file here + This is not JSON file \ No newline at end of file From 466019010395ff115b97663b8799c529a1b7707b Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Sat, 27 Jan 2024 21:07:44 +0100 Subject: [PATCH 03/12] Update build.gradle --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 2aae321..ef94b8d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { applicationId "com.sjapps.jsonlist" minSdk 23 targetSdk 34 - versionCode 5 + versionCode 6 versionName "1.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From b22e3d9c3f316d17e58c9c282a8dc5739473a322 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Sun, 28 Jan 2024 00:59:30 +0100 Subject: [PATCH 04/12] Change from ListView to RecyclerView --- .../java/com/sjapps/adapters/ListAdapter.java | 195 ++++++++++++++---- .../com/sjapps/jsonlist/MainActivity.java | 8 +- app/src/main/res/layout/activity_main.xml | 2 +- 3 files changed, 162 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/sjapps/adapters/ListAdapter.java b/app/src/main/java/com/sjapps/adapters/ListAdapter.java index da9ea4b..d961b12 100644 --- a/app/src/main/java/com/sjapps/adapters/ListAdapter.java +++ b/app/src/main/java/com/sjapps/adapters/ListAdapter.java @@ -3,13 +3,25 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.graphics.Color; +import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseAdapter; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; +import android.view.animation.OvershootInterpolator; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.AnimRes; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import com.sjapps.jsonlist.java.JsonData; import com.sjapps.jsonlist.java.ListItem; import com.sjapps.jsonlist.MainActivity; @@ -17,13 +29,74 @@ import java.util.ArrayList; -public class ListAdapter extends BaseAdapter { +public class ListAdapter extends RecyclerView.Adapter { + + Handler handler = new Handler(); ArrayList list; Context context; MainActivity activity; String path; public int selectedItem = -1; + public int highlightedItem = -1; + + + + static class ViewHolderShort extends RecyclerView.ViewHolder{ + + TextView title; + + public ViewHolderShort(View itemView) { + super(itemView); + title = itemView.findViewById(R.id.itemName); + } + public TextView getTitleTxt(){ + return title; + } + + public View getView(){ + return itemView; + } + + } + + static class ViewHolderLong extends RecyclerView.ViewHolder{ + + TextView title, value; + + public ViewHolderLong(View itemView) { + super(itemView); + title = itemView.findViewById(R.id.itemName); + value = itemView.findViewById(R.id.itemValue); + } + public TextView getTitleTxt(){ + return title; + } + + public TextView getValueTxt(){ + return value; + } + + public View getView(){ + return itemView; + } + + } + + static class ViewHolderSpace extends RecyclerView.ViewHolder{ + + + public ViewHolderSpace(View itemView) { + super(itemView); + + } + + public View getView(){ + return itemView; + } + + } + public ListAdapter(ArrayList list, Context context,String path){ this.list = list; @@ -33,70 +106,82 @@ public ListAdapter(ArrayList list, Context context,String path){ } @Override - public int getCount() { - if (list == null) - return 0; - - if (list.size() == 0) - return 0; + public int getItemViewType(int position) { - if (!list.get(getLast()).isSpace()) - return list.size(); - return getLast(); - } + ListItem item = list.get(position); - @Override - public Object getItem(int i) { - return list.get(i); + return (item.isArray() || item.isObject())?0:item.isSpace()?2:1; } + @NonNull @Override - public long getItemId(int i) { - return i; - } - - private int getLast(){ - return (list.size()>0?list.size()-1:0); + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case 0: + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout,parent,false); + return new ViewHolderShort(view); + case 1: + view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout2,parent,false); + return new ViewHolderLong(view); + case 2: + view = LayoutInflater.from(parent.getContext()).inflate(R.layout.space_layout,parent,false); + return new ViewHolderSpace(view); + } + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout,parent,false); + return new ViewHolderShort(view); } - @Override - public View getView(int position, View convertView, ViewGroup parent) { + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int pos) { - ListItem item = list.get(position); + ListItem item = list.get(pos); if(item.isSpace()) { - return LayoutInflater.from(context).inflate(R.layout.space_layout, parent, false); + return; } + + int position = pos; + if (item.isArray() || item.isObject()) { - View view = LayoutInflater.from(context).inflate(R.layout.list_layout,parent,false); - TextView titleTxt = view.findViewById(R.id.itemName); + ViewHolderShort currentHolder = (ViewHolderShort) holder; + + TextView titleTxt = currentHolder.getTitleTxt(); titleTxt.setText(item.getName()); + View view = currentHolder.getView(); + if (selectedItem == position){ view.findViewById(R.id.copyBtn).setVisibility(View.VISIBLE); + }else view.findViewById(R.id.copyBtn).setVisibility(View.GONE); + + if (highlightedItem == position){ + setAnimation(context,view,R.anim.button_prev,new OvershootInterpolator()); + highlightedItem = -1; } + String newPath = path + (path.equals("") ? "": "///" + (item.getId()!=-1?"{" + item.getId() + "}":"")) + item.getName(); view.findViewById(R.id.btn).setOnClickListener(view1 -> activity.open(JsonData.getPathFormat(newPath),newPath)); view.findViewById(R.id.copyBtn).setOnClickListener(v -> { ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clipData = ClipData.newPlainText("Text",item.getName()); - clipboard.setPrimaryClip(clipData); - Toast.makeText(v.getContext(),"Copied to clipboard",Toast.LENGTH_SHORT).show(); - selectedItem = -1; - notifyDataSetChanged(); + ClipData clipData = ClipData.newPlainText("Text",item.getName()); + clipboard.setPrimaryClip(clipData); + Toast.makeText(v.getContext(),"Copied to clipboard",Toast.LENGTH_SHORT).show(); + selectedItem = -1; + notifyItemChanged(position); }); view.findViewById(R.id.btn).setOnLongClickListener(v -> { + notifyItemChanged(selectedItem); selectedItem = position; - notifyDataSetChanged(); + notifyItemChanged(position); return true; }); - return view; - + return; } - View view = LayoutInflater.from(context).inflate(R.layout.list_layout2,parent,false); - TextView titleTxt = view.findViewById(R.id.itemName); - TextView valueTxt = view.findViewById(R.id.itemValue); + + ViewHolderLong currentHolder = (ViewHolderLong) holder; + View view = currentHolder.getView(); + TextView titleTxt = currentHolder.getTitleTxt(); + TextView valueTxt = currentHolder.getValueTxt(); if (item.getName() == null) titleTxt.setVisibility(View.GONE); else { @@ -107,6 +192,38 @@ public View getView(int position, View convertView, ViewGroup parent) { valueTxt.setText(item.getValue().isEmpty() ? "\"\"" : item.getValue()); - return view; + } + + @Override + public int getItemCount() { + if (list == null) + return 0; + + if (list.size() == 0) + return 0; + + if (!list.get(getLast()).isSpace()) + return list.size(); + return getLast(); + } + + private int getLast(){ + return (list.size()>0?list.size()-1:0); + } + + @Override + public long getItemId(int position) { + return position; + } + + public void setHighlightItem(int position){ + highlightedItem = position; + } + + public static void setAnimation(Context context, @NonNull View view, @AnimRes int animationRes, Interpolator interpolator) { + Animation animation = AnimationUtils.loadAnimation(context, animationRes); + if (interpolator != null) + animation.setInterpolator(interpolator); + view.startAnimation(animation); } } diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index 05ffda1..3aacc33 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -8,6 +8,8 @@ import androidx.annotation.AnimRes; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import android.app.Activity; import android.content.Context; @@ -34,7 +36,6 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ListView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; @@ -65,7 +66,7 @@ public class MainActivity extends AppCompatActivity { ImageView fileImg; Button openFileBtn; TextView titleTxt, emptyListTxt; - ListView list; + RecyclerView list; JsonData data = new JsonData(); LinearLayout progressView; ProgressBar progressBar; @@ -190,7 +191,7 @@ public void handleOnBackPressed() { if (adapter!= null && adapter.selectedItem != -1){ adapter.selectedItem = -1; - adapter.notifyDataSetChanged(); + adapter.notifyItemRangeChanged(0,adapter.getItemCount()); return; } @@ -234,6 +235,7 @@ private void initialize() { menu.bringToFront(); menuBtn.bringToFront(); dropTarget = findViewById(R.id.dropTarget); + list.setLayoutManager(new LinearLayoutManager(this)); } private void open_closeMenu() { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 67736c5..15c5013 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -76,7 +76,7 @@ android:layout_height="match_parent" android:background="#70000000" android:visibility="invisible" /> - Date: Sun, 28 Jan 2024 01:01:13 +0100 Subject: [PATCH 05/12] save previous position --- .../java/com/sjapps/adapters/ListAdapter.java | 2 +- .../com/sjapps/jsonlist/MainActivity.java | 16 ++++++++++-- .../com/sjapps/jsonlist/java/JsonData.java | 15 +++++++++++ app/src/main/res/anim/button_prev.xml | 26 +++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/anim/button_prev.xml diff --git a/app/src/main/java/com/sjapps/adapters/ListAdapter.java b/app/src/main/java/com/sjapps/adapters/ListAdapter.java index d961b12..f5110ed 100644 --- a/app/src/main/java/com/sjapps/adapters/ListAdapter.java +++ b/app/src/main/java/com/sjapps/adapters/ListAdapter.java @@ -160,7 +160,7 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int pos) { } String newPath = path + (path.equals("") ? "": "///" + (item.getId()!=-1?"{" + item.getId() + "}":"")) + item.getName(); - view.findViewById(R.id.btn).setOnClickListener(view1 -> activity.open(JsonData.getPathFormat(newPath),newPath)); + view.findViewById(R.id.btn).setOnClickListener(view1 -> activity.open(JsonData.getPathFormat(newPath),newPath,position)); view.findViewById(R.id.copyBtn).setOnClickListener(v -> { ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clipData = ClipData.newPlainText("Text",item.getName()); diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index 3aacc33..2b6907f 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -210,7 +210,7 @@ public void handleOnBackPressed() { TransitionManager.beginDelayedTransition(viewGroup, autoTransition); data.goBack(); - open(JsonData.getPathFormat(data.getPath()), data.getPath()); + open(JsonData.getPathFormat(data.getPath()), data.getPath(),-1); if (data.isEmptyPath()) { backBtn.setVisibility(View.GONE); } @@ -322,7 +322,7 @@ private void LoadData(String Data) { readFileThread.start(); } - public void open(String Title, String path) { + public void open(String Title, String path, int previousPosition) { TransitionManager.beginDelayedTransition(viewGroup, autoTransition); if (isMenuOpen) @@ -336,6 +336,18 @@ public void open(String Title, String path) { ArrayList arrayList = getListFromPath(path,data.getRootList()); adapter = new ListAdapter(arrayList, this, path); list.setAdapter(adapter); + + if (previousPosition == -1) { + handler.postDelayed(() -> { + list.smoothScrollToPosition(data.getPreviousPos()+4); + adapter.setHighlightItem(data.getPreviousPos()); + }, 500); + handler.postDelayed(() -> { + adapter.notifyItemChanged(data.getPreviousPos()); + }, 600); + } + else data.addPreviousPos(previousPosition); + if (arrayList.size() == 0) { emptyListTxt.setVisibility(View.VISIBLE); } diff --git a/app/src/main/java/com/sjapps/jsonlist/java/JsonData.java b/app/src/main/java/com/sjapps/jsonlist/java/JsonData.java index ceb9ec9..3093d3f 100644 --- a/app/src/main/java/com/sjapps/jsonlist/java/JsonData.java +++ b/app/src/main/java/com/sjapps/jsonlist/java/JsonData.java @@ -1,10 +1,14 @@ package com.sjapps.jsonlist.java; import java.util.ArrayList; +import java.util.Stack; public class JsonData { String path = ""; ArrayList rootList = new ArrayList<>(); + Stack previousPosStack = new Stack<>(); + + int previousPos = -1; public String getPath() { return path; @@ -41,6 +45,9 @@ public boolean isRootListNull(){ public void goBack(){ + if (!previousPosStack.isEmpty()) + previousPos = previousPosStack.pop(); + String[] pathStrings = splitPath(); clearPath(); for (int i = 0; i < pathStrings.length-1; i++) { @@ -49,6 +56,14 @@ public void goBack(){ } + public void addPreviousPos(int pos){ + previousPosStack.push(pos); + } + + public int getPreviousPos(){ + return previousPos; + } + public static String getPathFormat(String path){ String[] pathStrings = splitPath(path); StringBuilder builder = new StringBuilder(); diff --git a/app/src/main/res/anim/button_prev.xml b/app/src/main/res/anim/button_prev.xml new file mode 100644 index 0000000..5196dcb --- /dev/null +++ b/app/src/main/res/anim/button_prev.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + From 725be11eff354a807d78c3b44f69d411533f2912 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Sun, 28 Jan 2024 01:02:11 +0100 Subject: [PATCH 06/12] Update build.gradle --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index ef94b8d..fd3cac0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { applicationId "com.sjapps.jsonlist" minSdk 23 targetSdk 34 - versionCode 6 + versionCode 7 versionName "1.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From f071afe649da32c022d3b3e2e0e4d0e761ee3f8b Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Sun, 28 Jan 2024 23:52:03 +0100 Subject: [PATCH 07/12] change smoothScrollToPosition --- app/src/main/java/com/sjapps/jsonlist/MainActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index 2b6907f..79a6b5b 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -339,7 +339,7 @@ public void open(String Title, String path, int previousPosition) { if (previousPosition == -1) { handler.postDelayed(() -> { - list.smoothScrollToPosition(data.getPreviousPos()+4); + list.smoothScrollToPosition(data.getPreviousPos()+2); adapter.setHighlightItem(data.getPreviousPos()); }, 500); handler.postDelayed(() -> { From f0871d03a0582e53d3aecf82148cd8cff796bb28 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Mon, 29 Jan 2024 00:03:15 +0100 Subject: [PATCH 08/12] Limit dropped files to one --- .../java/com/sjapps/jsonlist/MainActivity.java | 17 ++++++++++++++--- app/src/main/res/values/strings.xml | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index 79a6b5b..4ea36f1 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -131,13 +131,21 @@ protected void onCreate(Bundle savedInstanceState) { return true; case DragEvent.ACTION_DRAG_ENTERED: - if (event.getClipDescription().hasMimeType("application/json")) { - dropTargetBackground.setBackgroundColor(setColor(R.attr.colorPrimary)); + if(event.getClipDescription().getMimeTypeCount() > 1){ + dropTargetTxt.setText(R.string.only_one_file_is_allowed); + dropTargetBackground.setBackgroundColor(setColor(R.attr.colorError)); dropTargetBackground.setAlpha(.8f); - }else { + return false; + } + if (!event.getClipDescription().hasMimeType("application/json")) { dropTargetTxt.setText(R.string.this_is_not_json_file); dropTargetBackground.setBackgroundColor(setColor(R.attr.colorError)); + dropTargetBackground.setAlpha(.8f); + return false; } + + dropTargetBackground.setBackgroundColor(setColor(R.attr.colorPrimary)); + dropTargetBackground.setAlpha(.8f); return true; case DragEvent.ACTION_DRAG_EXITED: @@ -153,6 +161,9 @@ protected void onCreate(Bundle savedInstanceState) { return true; case DragEvent.ACTION_DROP: + if (event.getClipData().getItemCount() > 1){ + return false; + } if (!event.getClipDescription().hasMimeType("application/json")) return false; if (readFileThread != null && readFileThread.isAlive()) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7ea89ad..3cd16e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,4 +4,5 @@ Back Drop JSON file here This is not JSON file + Only one file is allowed! \ No newline at end of file From fd433ca17166e893b188241792c92ac474fe2759 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Tue, 30 Jan 2024 23:16:41 +0100 Subject: [PATCH 09/12] Update build.gradle --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index fd3cac0..467fc4a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { applicationId "com.sjapps.jsonlist" minSdk 23 targetSdk 34 - versionCode 7 + versionCode 8 versionName "1.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From 0ce91e8e2ef9a8bfe15713b527121f0748e13b70 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Wed, 31 Jan 2024 03:19:33 +0100 Subject: [PATCH 10/12] Add Crash log --- app/src/main/AndroidManifest.xml | 13 ++ .../java/com/sjapps/jsonlist/AppState.java | 30 ++++ .../java/com/sjapps/jsonlist/FileSystem.java | 90 +++++++++++ .../com/sjapps/jsonlist/MainActivity.java | 41 +++++ .../java/com/sjapps/jsonlist/functions.java | 21 +++ .../main/java/com/sjapps/logs/CrashLogs.java | 27 ++++ .../sjapps/logs/CustomExceptionHandler.java | 58 +++++++ .../java/com/sjapps/logs/LogActivity.java | 147 ++++++++++++++++++ app/src/main/res/drawable/ic_delete.xml | 10 ++ app/src/main/res/drawable/ic_menu.xml | 2 +- app/src/main/res/drawable/ic_share.xml | 7 + app/src/main/res/drawable/menu_with_dot.xml | 21 +++ app/src/main/res/drawable/ripple_red.xml | 14 ++ app/src/main/res/layout/activity_log.xml | 98 ++++++++++++ app/src/main/res/layout/activity_menu.xml | 12 +- app/src/main/res/xml/file_path.xml | 6 + 16 files changed, 595 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/sjapps/jsonlist/AppState.java create mode 100644 app/src/main/java/com/sjapps/jsonlist/functions.java create mode 100644 app/src/main/java/com/sjapps/logs/CrashLogs.java create mode 100644 app/src/main/java/com/sjapps/logs/CustomExceptionHandler.java create mode 100644 app/src/main/java/com/sjapps/logs/LogActivity.java create mode 100644 app/src/main/res/drawable/ic_delete.xml create mode 100644 app/src/main/res/drawable/ic_share.xml create mode 100644 app/src/main/res/drawable/menu_with_dot.xml create mode 100644 app/src/main/res/drawable/ripple_red.xml create mode 100644 app/src/main/res/layout/activity_log.xml create mode 100644 app/src/main/res/xml/file_path.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f0595c7..1f93d44 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,9 @@ android:largeHeap="true" android:theme="@style/Theme.JsonList"> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/sjapps/jsonlist/AppState.java b/app/src/main/java/com/sjapps/jsonlist/AppState.java new file mode 100644 index 0000000..d1ffdf7 --- /dev/null +++ b/app/src/main/java/com/sjapps/jsonlist/AppState.java @@ -0,0 +1,30 @@ +package com.sjapps.jsonlist; + +public class AppState { + boolean hasNewCrash; + boolean hasCrashLogs; + + public boolean hasNewCrash() { + return hasNewCrash; + } + + public void setHasNewCrash(boolean hasNewCrash) { + this.hasNewCrash = hasNewCrash; + } + + public boolean hasCrashLogs() { + return hasCrashLogs; + } + + public void setHasCrashLogs(boolean hasCrashLogs) { + this.hasCrashLogs = hasCrashLogs; + } + + @Override + public String toString() { + return "AppState{" + + "hasNewCrash=" + hasNewCrash + + ", hasCrashLogs=" + hasCrashLogs + + '}'; + } +} diff --git a/app/src/main/java/com/sjapps/jsonlist/FileSystem.java b/app/src/main/java/com/sjapps/jsonlist/FileSystem.java index c0a0639..31bb6b4 100644 --- a/app/src/main/java/com/sjapps/jsonlist/FileSystem.java +++ b/app/src/main/java/com/sjapps/jsonlist/FileSystem.java @@ -4,17 +4,25 @@ import android.content.res.AssetFileDescriptor; import android.net.Uri; +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.sjapps.logs.CrashLogs; import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Path; + public class FileSystem { + final static String LogFile = "Log.json"; + final static String StateFile = "CheckState.json"; public static JsonObject loadDataToJsonObj(JsonElement data){ return data.getAsJsonObject(); @@ -56,4 +64,86 @@ public static String LoadDataFromFile(Context context, Uri uri, InputStream in return null; } } + + static String LoadData(Context context,String FileName){ + File file = new File(context.getFilesDir(), FileName); + try { + if (!file.exists()) { + file.createNewFile(); + } + FileReader fileReader = new FileReader(file.getAbsolutePath()); + + + StringBuilder builder = new StringBuilder(); + String jsonString = null; + BufferedReader bufferedReader = new BufferedReader(fileReader); + while ((jsonString = bufferedReader.readLine()) != null) { + builder.append(jsonString); + } + bufferedReader.close(); + if (builder.toString().equals("") || builder.toString().equals("{}")) + return null; + + return new String(builder); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + static void SaveData(Context context, String FileName, String data){ + File file = new File(context.getFilesDir(), FileName); + try { + if (!file.exists()) { + file.createNewFile(); + } + FileWriter fileWriter = new FileWriter(file); + fileWriter.write(data); + fileWriter.close(); + }catch (IOException e){ + e.printStackTrace(); + } + } + + public static AppState loadStateData(Context context) { + String data = LoadData(context, StateFile); + if (data == null) + return new AppState(); + return new Gson().fromJson(data, AppState.class); + } + + public static CrashLogs loadLogData(Context context){ + String data = LoadData(context,LogFile); + if (data == null) + return new CrashLogs(); + return new Gson().fromJson(data,CrashLogs.class); + } + + public static void SaveState(Context context, String data) { + SaveData(context,StateFile,data); + } + + public static void SaveLog(Context context, String data) { + SaveData(context,LogFile,data); + } + + public static File createTempFile(Context context, String data, String fileName) { + File file = new File(context.getCacheDir(),fileName); + try { + if (!file.exists()) { + file.createNewFile(); + } + FileWriter fileWriter = new FileWriter(file); + fileWriter.write(data); + fileWriter.close(); + }catch (IOException e){ + e.printStackTrace(); + } + return file; + } + + public static boolean deleteTempFile(Context context, String fileName){ + File file = new File(context.getCacheDir(),fileName); + return file.delete(); + } } diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index 4ea36f1..289d1d0 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -53,6 +53,8 @@ import com.sjapps.jsonlist.java.JsonData; import com.sjapps.jsonlist.java.ListItem; import com.sjapps.library.customdialog.BasicDialog; +import com.sjapps.logs.CustomExceptionHandler; +import com.sjapps.logs.LogActivity; import java.io.IOException; import java.io.InputStream; @@ -82,12 +84,18 @@ public class MainActivity extends AppCompatActivity { @Override protected void onResume() { super.onResume(); + checkCrashLogs(); Log.d(TAG, "onResume: resume"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) { + Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this)); + } + setContentView(R.layout.activity_main); initialize(); @@ -108,6 +116,10 @@ protected void onCreate(Bundle savedInstanceState) { OpenAbout(); open_closeMenu(); }); + menu.findViewById(R.id.logBtn).setOnClickListener(view -> { + OpenLogPage(); + open_closeMenu(); + }); dim_bg.setOnClickListener(view -> open_closeMenu()); @@ -188,10 +200,39 @@ protected void onCreate(Bundle savedInstanceState) { }); } + void checkCrashLogs() { + + AppState state = FileSystem.loadStateData(this); + TextView logBtn = menu.findViewById(R.id.logBtn); + if (!state.hasCrashLogs()) { + logBtn.setVisibility(View.GONE); + return; + } + logBtn.setVisibility(View.VISIBLE); + + TypedValue typedValue = new TypedValue(); + + if (state.hasNewCrash()) { + getTheme().resolveAttribute(R.attr.colorOnError, typedValue, true); + logBtn.setTextColor(typedValue.data); + logBtn.setBackgroundResource(R.drawable.ripple_red); + menuBtn.setImageResource(R.drawable.menu_with_dot); + return; + } + getTheme().resolveAttribute(R.attr.colorOnSurfaceVariant, typedValue, true); + logBtn.setTextColor(typedValue.data); + logBtn.setBackgroundResource(R.drawable.ripple_list2); + menuBtn.setImageResource(R.drawable.ic_menu); + } + private void OpenAbout() { startActivity(new Intent(MainActivity.this, AboutActivity.class)); } + private void OpenLogPage() { + startActivity(new Intent(MainActivity.this, LogActivity.class)); + } + OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { diff --git a/app/src/main/java/com/sjapps/jsonlist/functions.java b/app/src/main/java/com/sjapps/jsonlist/functions.java new file mode 100644 index 0000000..a02edaf --- /dev/null +++ b/app/src/main/java/com/sjapps/jsonlist/functions.java @@ -0,0 +1,21 @@ +package com.sjapps.jsonlist; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +public class functions { + public static String timeFormat(Calendar c){ + if (c == null) + return "N/A"; + SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, MMM d h:mm:ss a, yyyy"); + return dateFormat.format(c.getTime()); + } + + public static String timeFormatShort(Calendar c){ + if (c == null) + return "N/A"; + SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); + return dateFormat.format(c.getTime()); + } + +} diff --git a/app/src/main/java/com/sjapps/logs/CrashLogs.java b/app/src/main/java/com/sjapps/logs/CrashLogs.java new file mode 100644 index 0000000..3d83f56 --- /dev/null +++ b/app/src/main/java/com/sjapps/logs/CrashLogs.java @@ -0,0 +1,27 @@ +package com.sjapps.logs; + +import java.util.ArrayList; + +public class CrashLogs { + + ArrayList logs = new ArrayList<>(); + + public void addLog(String s){ + logs.add(s); + } + + public ArrayList getLogs() { + return logs; + } + + public void setLogs(ArrayList logs) { + this.logs = logs; + } + + @Override + public String toString() { + return "RuntimeExceptions{" + + "logs=" + logs + + '}'; + } +} diff --git a/app/src/main/java/com/sjapps/logs/CustomExceptionHandler.java b/app/src/main/java/com/sjapps/logs/CustomExceptionHandler.java new file mode 100644 index 0000000..88da5e5 --- /dev/null +++ b/app/src/main/java/com/sjapps/logs/CustomExceptionHandler.java @@ -0,0 +1,58 @@ +package com.sjapps.logs; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.sjapps.jsonlist.AppState; +import com.sjapps.jsonlist.FileSystem; +import com.sjapps.jsonlist.functions; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Calendar; + + +public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler { + + private Thread.UncaughtExceptionHandler defaultUEH; + Context context; + Calendar calendar; + + + public CustomExceptionHandler(Context context) { + defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); + this.context = context; + + } + + @Override + public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) { + + AppState state = FileSystem.loadStateData(context); + + if (!state.hasCrashLogs()) + state.setHasCrashLogs(true); + + state.setHasNewCrash(true); + FileSystem.SaveState(context,new Gson().toJson(state)); + + final Writer result = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(result); + e.printStackTrace(printWriter); + String stacktrace = result.toString(); + printWriter.close(); + calendar = Calendar.getInstance(); + String log = ""; + log += "\n\n-- " + functions.timeFormat(calendar) + " -- \n"; + log += stacktrace; + + CrashLogs exceptions = FileSystem.loadLogData(context); + + exceptions.addLog(log); + FileSystem.SaveLog(context,new Gson().toJson(exceptions)); + defaultUEH.uncaughtException(t, e); + } +} diff --git a/app/src/main/java/com/sjapps/logs/LogActivity.java b/app/src/main/java/com/sjapps/logs/LogActivity.java new file mode 100644 index 0000000..76bda0d --- /dev/null +++ b/app/src/main/java/com/sjapps/logs/LogActivity.java @@ -0,0 +1,147 @@ +package com.sjapps.logs; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.FileProvider; + +import com.google.gson.Gson; +import com.sjapps.jsonlist.AppState; +import com.sjapps.jsonlist.FileSystem; +import com.sjapps.jsonlist.R; +import com.sjapps.jsonlist.functions; +import com.sjapps.library.customdialog.BasicDialog; +import com.sjapps.library.customdialog.ListDialog; + + +import java.util.Calendar; + +public class LogActivity extends AppCompatActivity { + + TextView logTxt; + String exportFileName = "logFile.txt"; + int numberOfLogs = 0; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_log); + + logTxt = findViewById(R.id.logTxt); + update(); + + AppState state = FileSystem.loadStateData(this); + + if (state.hasNewCrash()){ + state.setHasNewCrash(false); + FileSystem.SaveState(this,new Gson().toJson(state)); + } + + } + + @Override + protected void onResume() { + super.onResume(); + FileSystem.deleteTempFile(this,exportFileName); + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + + + public void Back(View view) { + finish(); + } + + public void deleteLog(View view) { + BasicDialog dialog = new BasicDialog(); + dialog.Delete(this,true) + .setTitle("Delete logs?") + .onButtonClick(() ->{ + dialog.dismiss(); + FileSystem.SaveLog(this,new Gson().toJson(new CrashLogs())); + update(); + }) + .show(); + } + + private void update() { + + CrashLogs logs = FileSystem.loadLogData(this); + + AppState state = FileSystem.loadStateData(this); + + if (state.hasCrashLogs() && logs.getLogs().isEmpty()){ + state.setHasCrashLogs(false); + FileSystem.SaveState(this,new Gson().toJson(state)); + } + StringBuilder log = new StringBuilder(); + + numberOfLogs = logs.getLogs().size(); + + for (String s : logs.getLogs()){ + log.append(s); + } + logTxt.setText(log.toString()); + } + + public void shareLog(View view) { + + if (logTxt.getText().toString().equals("")) { + Toast.makeText(this, "File is empty", Toast.LENGTH_SHORT).show(); + return; + } + + String[] options = {"Copy logs to clipboard","Share logs"}; + + ListDialog dialog = new ListDialog(); + dialog.Builder(this,true) + .setTitle("Chose action") + .setItems(options,(position, value) -> { + dialog.dismiss(); + switch (position){ + case 0: copyToClipboard(); + break; + case 1: share(); + break; + } + }) + .show(); + + } + + private void share() { + + exportFileName = "logFile " + functions.timeFormatShort(Calendar.getInstance()) + ".txt"; + + String appName = getResources().getString(R.string.app_name); + + Intent intentShare = new Intent(Intent.ACTION_SEND); + intentShare.setType("text/plain"); + intentShare.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".logs.provider", + FileSystem.createTempFile(this,logTxt.getText().toString(),exportFileName))); + intentShare.putExtra(Intent.EXTRA_SUBJECT, appName + " Crash logs"); + intentShare.putExtra(Intent.EXTRA_TEXT, numberOfLogs + " Crash log" + (numberOfLogs>1?"s":"") + " for " + appName); + + startActivity(Intent.createChooser(intentShare,"Share file")); + } + + private void copyToClipboard() { + + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = ClipData.newPlainText("log",logTxt.getText().toString()); + clipboard.setPrimaryClip(clipData); + Toast.makeText(this, "logs is copied to clipboard", Toast.LENGTH_SHORT).show(); + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml new file mode 100644 index 0000000..41fa9d6 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu.xml b/app/src/main/res/drawable/ic_menu.xml index e0409ca..a917303 100644 --- a/app/src/main/res/drawable/ic_menu.xml +++ b/app/src/main/res/drawable/ic_menu.xml @@ -6,5 +6,5 @@ android:tint="?attr/colorControlNormal"> + android:pathData="M4,18h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,16c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM4,13h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,11c-0.55,0 -1,0.45 -1,1s0.45,1 1,1zM3,7c0,0.55 0.45,1 1,1h16c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1L4,6c-0.55,0 -1,0.45 -1,1z"/> diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml new file mode 100644 index 0000000..d013943 --- /dev/null +++ b/app/src/main/res/drawable/ic_share.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/drawable/menu_with_dot.xml b/app/src/main/res/drawable/menu_with_dot.xml new file mode 100644 index 0000000..bef5432 --- /dev/null +++ b/app/src/main/res/drawable/menu_with_dot.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ripple_red.xml b/app/src/main/res/drawable/ripple_red.xml new file mode 100644 index 0000000..5f5a63b --- /dev/null +++ b/app/src/main/res/drawable/ripple_red.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_log.xml b/app/src/main/res/layout/activity_log.xml new file mode 100644 index 0000000..c590dfd --- /dev/null +++ b/app/src/main/res/layout/activity_log.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_menu.xml b/app/src/main/res/layout/activity_menu.xml index 2f7b157..3deff0a 100644 --- a/app/src/main/res/layout/activity_menu.xml +++ b/app/src/main/res/layout/activity_menu.xml @@ -39,7 +39,17 @@ android:paddingHorizontal="20dp" android:background="@drawable/ripple_list2" android:text="About"/> - + \ No newline at end of file diff --git a/app/src/main/res/xml/file_path.xml b/app/src/main/res/xml/file_path.xml new file mode 100644 index 0000000..24b6e4e --- /dev/null +++ b/app/src/main/res/xml/file_path.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file From 17b205853f633e5fcde219a2bd37f2df363c1197 Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Thu, 1 Feb 2024 21:08:58 +0100 Subject: [PATCH 11/12] add warning dialog before sharing logs --- .../java/com/sjapps/logs/LogActivity.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/sjapps/logs/LogActivity.java b/app/src/main/java/com/sjapps/logs/LogActivity.java index 76bda0d..665b568 100644 --- a/app/src/main/java/com/sjapps/logs/LogActivity.java +++ b/app/src/main/java/com/sjapps/logs/LogActivity.java @@ -19,6 +19,7 @@ import com.sjapps.jsonlist.functions; import com.sjapps.library.customdialog.BasicDialog; import com.sjapps.library.customdialog.ListDialog; +import com.sjapps.library.customdialog.MessageDialog; import java.util.Calendar; @@ -104,7 +105,7 @@ public void shareLog(View view) { } String[] options = {"Copy logs to clipboard","Share logs"}; - + ListDialog dialog = new ListDialog(); dialog.Builder(this,true) .setTitle("Chose action") @@ -112,13 +113,21 @@ public void shareLog(View view) { dialog.dismiss(); switch (position){ case 0: copyToClipboard(); - break; + break; case 1: share(); - break; + break; } - }) + }); + + MessageDialog warningDialog = new MessageDialog(); + warningDialog.ErrorDialogBuilder(this,true) + .setTitle("Warning!") + .setMessage("This reports may include personal information. Check before sharing to anyone") .show(); - + warningDialog.dialog.setOnDismissListener(dialogInterface -> { + warningDialog.dismiss(); + dialog.show(); + }); } private void share() { From 039575b98f683ea3936b4fd18000749120da97ae Mon Sep 17 00:00:00 2001 From: SlaVcE <102253539+SlaVcE14@users.noreply.github.com> Date: Fri, 2 Feb 2024 01:06:42 +0100 Subject: [PATCH 12/12] fix MIME types --- app/src/main/java/com/sjapps/jsonlist/MainActivity.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java index 289d1d0..ea1519f 100644 --- a/app/src/main/java/com/sjapps/jsonlist/MainActivity.java +++ b/app/src/main/java/com/sjapps/jsonlist/MainActivity.java @@ -17,6 +17,7 @@ import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.transition.AutoTransition; @@ -137,6 +138,8 @@ protected void onCreate(Bundle savedInstanceState) { TextView dropTargetTxt = v.findViewById(R.id.dropTargetText); View dropTargetBackground = v.findViewById(R.id.dropTargetBackground); + String MIMEType = Build.VERSION.SDK_INT > Build.VERSION_CODES.P?"application/json":"application/*"; + switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: dropTarget.setAlpha(1); @@ -149,7 +152,7 @@ protected void onCreate(Bundle savedInstanceState) { dropTargetBackground.setAlpha(.8f); return false; } - if (!event.getClipDescription().hasMimeType("application/json")) { + if (!event.getClipDescription().hasMimeType(MIMEType)) { dropTargetTxt.setText(R.string.this_is_not_json_file); dropTargetBackground.setBackgroundColor(setColor(R.attr.colorError)); dropTargetBackground.setAlpha(.8f); @@ -176,7 +179,7 @@ protected void onCreate(Bundle savedInstanceState) { if (event.getClipData().getItemCount() > 1){ return false; } - if (!event.getClipDescription().hasMimeType("application/json")) + if (!event.getClipDescription().hasMimeType(MIMEType)) return false; if (readFileThread != null && readFileThread.isAlive()) { Snackbar.make(getWindow().getDecorView(),"Loading file in progress, try again later", BaseTransientBottomBar.LENGTH_SHORT).show(); @@ -418,7 +421,7 @@ private void ImportFromFile() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType("application/json"); + intent.setType(Build.VERSION.SDK_INT > Build.VERSION_CODES.P?"application/json":"application/*"); ActivityResultData.launch(intent); }