From ad66c56d3901ed8b91d1f7960cd60cd0306e2505 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 16 Mar 2016 06:18:02 +0300 Subject: [PATCH 1/2] context menu item on listview --- .../activities/MainActivity.java | 119 +++++++++++------- .../audiorecorder/app/MainApplication.java | 10 ++ .../axet/audiorecorder/app/Storage.java | 28 ++++- .../audiorecorder/widgets/OpenFileDialog.java | 17 ++- app/src/main/res/menu/menu_context.xml | 15 +++ 5 files changed, 136 insertions(+), 53 deletions(-) create mode 100644 app/src/main/res/menu/menu_context.xml diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java index 65fbf7e..5a025ad 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/MainActivity.java @@ -17,10 +17,12 @@ import android.support.design.widget.FloatingActionButton; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.PopupMenu; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -37,6 +39,7 @@ import com.github.axet.audiorecorder.animations.RecordingAnimation; import com.github.axet.audiorecorder.animations.RemoveItemAnimation; import com.github.axet.audiorecorder.app.MainApplication; import com.github.axet.audiorecorder.app.Storage; +import com.github.axet.audiorecorder.widgets.OpenFileDialog; import com.github.axet.audiorecorder.widgets.PopupShareActionProvider; import java.io.File; @@ -78,10 +81,9 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr public class Recordings extends ArrayAdapter { MediaPlayer player; Runnable updatePlayer; - PopupShareActionProvider shareProvider; int selected = -1; - Map duration = new TreeMap<>(); + Map durations = new TreeMap<>(); public Recordings(Context context) { super(context, 0); @@ -89,7 +91,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr public void scan(File dir) { clear(); - duration.clear(); + durations.clear(); List ff = storage.scan(dir); @@ -99,7 +101,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr if (mp != null) { int d = mp.getDuration(); mp.release(); - duration.put(f, d); + durations.put(f, d); add(f); } else { Log.e(TAG, f.toString()); @@ -110,21 +112,15 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr sort(new SortFiles()); } - String formatSize(long s) { - if (s > 0.1 * 1024 * 1024) { - float f = s / 1024f / 1024f; - return String.format("%.1f MB", f); - } else { - float f = s / 1024f; - return String.format("%.1f kb", f); - } - } - public void close() { if (player != null) { player.release(); player = null; } + if (updatePlayer != null) { + handler.removeCallbacks(updatePlayer); + updatePlayer = null; + } } @Override @@ -154,15 +150,21 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr time.setText(s.format(new Date(f.lastModified()))); TextView dur = (TextView) convertView.findViewById(R.id.recording_duration); - dur.setText(MainApplication.formatDuration(duration.get(f))); + dur.setText(MainApplication.formatDuration(durations.get(f))); TextView size = (TextView) convertView.findViewById(R.id.recording_size); - size.setText(formatSize(f.length())); + size.setText(MainApplication.formatSize(f.length())); - View trash = convertView.findViewById(R.id.recording_player_trash); - trash.setOnClickListener(new View.OnClickListener() { + final View playerBase = convertView.findViewById(R.id.recording_player); + playerBase.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + } + }); + + final Runnable delete = new Runnable() { + @Override + public void run() { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle("Delete Recording"); builder.setMessage("...\\" + f.getName() + "\n\n" + "Are you sure ? "); @@ -190,14 +192,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr }); builder.show(); } - }); - - final View playerBase = convertView.findViewById(R.id.recording_player); - playerBase.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - } - }); + }; if (selected == position) { RecordingAnimation.apply(list, convertView, true, scrollState == SCROLL_STATE_IDLE && (int) convertView.getTag() == TYPE_COLLAPSED); @@ -212,7 +207,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr if (player == null) { playerPlay(playerBase, f); } else if (player.isPlaying()) { - playerPause(); + playerPause(playerBase, f); } else { playerPlay(playerBase, f); } @@ -223,29 +218,33 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr share.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - shareProvider = new PopupShareActionProvider(getContext(), share); + PopupShareActionProvider shareProvider = new PopupShareActionProvider(getContext(), share); Intent emailIntent = new Intent(Intent.ACTION_SEND); emailIntent.setType("audio/mp4a-latm"); emailIntent.putExtra(Intent.EXTRA_EMAIL, ""); emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f)); emailIntent.putExtra(Intent.EXTRA_SUBJECT, f.getName()); - emailIntent.putExtra(Intent.EXTRA_TEXT, "Shared via App Recorder"); + emailIntent.putExtra(Intent.EXTRA_TEXT, "Shared via Audio Recorder"); shareProvider.setShareIntent(emailIntent); shareProvider.show(); + } + }); - Log.d("123", "show"); + View trash = convertView.findViewById(R.id.recording_player_trash); + trash.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + delete.run(); } }); convertView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - playerStop(); select(-1); - notifyDataSetChanged(); } }); } else { @@ -256,13 +255,48 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr @Override public void onClick(View v) { select(position); - notifyDataSetChanged(); - - playerStop(); } }); } + convertView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + PopupMenu popup = new PopupMenu(getContext(), v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.menu_context, popup.getMenu()); + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + if (item.getItemId() == R.id.action_delete) { + delete.run(); + return true; + } + if (item.getItemId() == R.id.action_rename) { + final OpenFileDialog.EditTextDialog e = new OpenFileDialog.EditTextDialog(getContext()); + e.setTitle("Rename Recording"); + e.setText(Storage.getNameNoExt(f)); + e.setPositiveButton(new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String ext = Storage.getExt(f); + String s = String.format("%s.%s", e.getText(), ext); + File ff = new File(f.getParent(), s); + f.renameTo(ff); + load(); + } + }); + e.show(); + return true; + } + return false; + } + }); + popup.show(); + return true; + } + }); + return convertView; } @@ -278,7 +312,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr updatePlayerRun(v, f); } - void playerPause() { + void playerPause(View v, File f) { if (player != null) { player.pause(); } @@ -286,6 +320,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr handler.removeCallbacks(updatePlayer); updatePlayer = null; } + updatePlayerText(v, f); } void playerStop() { @@ -333,7 +368,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr TextView end = (TextView) v.findViewById(R.id.recording_player_end); int c = 0; - int d = duration.get(f); + int d = durations.get(f); if (player != null) { c = player.getCurrentPosition(); @@ -358,12 +393,10 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr @Override public void onStartTrackingTouch(SeekBar seekBar) { - } @Override public void onStopTrackingTouch(SeekBar seekBar) { - } }); @@ -405,9 +438,10 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr } }); + recordings = new Recordings(this); + list = (ListView) findViewById(R.id.list); list.setOnScrollListener(this); - recordings = new Recordings(this); list.setAdapter(recordings); list.setEmptyView(findViewById(R.id.empty_list)); @@ -467,7 +501,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr else load(); - final int selected = getLastPosition(); + final int selected = getLastRecording(); list.setSelection(selected); if (selected != -1) { handler.post(new Runnable() { @@ -483,7 +517,7 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr edit.commit(); } - int getLastPosition() { + int getLastRecording() { final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this); String last = shared.getString(MainApplication.PREFERENCE_LAST, ""); last = last.toLowerCase(); @@ -559,4 +593,5 @@ public class MainActivity extends AppCompatActivity implements AbsListView.OnScr recordings.close(); } + } diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java b/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java index 4cf836c..9226484 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/MainApplication.java @@ -25,6 +25,16 @@ public class MainApplication extends Application { return String.format("%02d", tt); } + public static String formatSize(long s) { + if (s > 0.1 * 1024 * 1024) { + float f = s / 1024f / 1024f; + return String.format("%.1f MB", f); + } else { + float f = s / 1024f; + return String.format("%.1f kb", f); + } + } + static public String formatDuration(long diff) { int diffMilliseconds = (int) (diff % 1000); int diffSeconds = (int) (diff / 1000 % 60); diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java b/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java index 3654b19..3384323 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java +++ b/app/src/main/java/com/github/axet/audiorecorder/app/Storage.java @@ -101,6 +101,26 @@ public class Storage { return getNextFile(parent, s.format(new Date()), ext); } + public static String getNameNoExt(File f) { + String fileName = f.getName(); + + int i = fileName.lastIndexOf('.'); + if (i > 0) { + fileName = fileName.substring(0, i); + } + return fileName; + } + + public static String getExt(File f) { + String fileName = f.getName(); + + int i = fileName.lastIndexOf('.'); + if (i > 0) { + return fileName.substring(i + 1); + } + return ""; + } + File getNextFile(File parent, File f) { String fileName = f.getName(); @@ -109,14 +129,18 @@ public class Storage { int i = fileName.lastIndexOf('.'); if (i > 0) { extension = fileName.substring(i + 1); + fileName = fileName.substring(0, i); } - fileName = fileName.substring(0, i); return getNextFile(parent, fileName, extension); } File getNextFile(File parent, String name, String ext) { - String fileName = String.format("%s.%s", name, ext); + String fileName; + if (ext.isEmpty()) + fileName = name; + else + fileName = String.format("%s.%s", name, ext); File file = new File(parent, fileName); diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/OpenFileDialog.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/OpenFileDialog.java index af05cf2..2bd7243 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/widgets/OpenFileDialog.java +++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/OpenFileDialog.java @@ -9,27 +9,22 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Environment; import android.support.v7.app.AlertDialog; +import android.support.v7.widget.PopupMenu; import android.text.TextUtils; -import android.util.DisplayMetrics; -import android.util.Log; import android.util.TypedValue; import android.view.Display; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; -import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ListView; -import android.widget.PopupMenu; import android.widget.TextView; import android.widget.Toast; @@ -232,7 +227,7 @@ public class OpenFileDialog extends AlertDialog.Builder { input.setSingleLine(true); - setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + setPositiveButton(new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); @@ -245,6 +240,10 @@ public class OpenFileDialog extends AlertDialog.Builder { setView(input); } + public AlertDialog.Builder setPositiveButton(final DialogInterface.OnClickListener listener) { + return super.setPositiveButton(android.R.string.ok, listener); + } + @Override public AlertDialog.Builder setPositiveButton(int textId, final DialogInterface.OnClickListener listener) { return super.setPositiveButton(textId, new DialogInterface.OnClickListener() { @@ -363,7 +362,7 @@ public class OpenFileDialog extends AlertDialog.Builder { final EditTextDialog builder = new EditTextDialog(getContext()); builder.setTitle(FOLDER_NAME); builder.setText(""); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + builder.setPositiveButton(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { File f = new File(currentPath, builder.getText()); @@ -401,7 +400,7 @@ public class OpenFileDialog extends AlertDialog.Builder { final EditTextDialog b = new EditTextDialog(getContext()); b.setTitle(FOLDER_NAME); b.setText(ff.getName()); - b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + b.setPositiveButton(new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { File f = new File(ff.getParent(), b.getText()); diff --git a/app/src/main/res/menu/menu_context.xml b/app/src/main/res/menu/menu_context.xml new file mode 100644 index 0000000..75a132e --- /dev/null +++ b/app/src/main/res/menu/menu_context.xml @@ -0,0 +1,15 @@ + + + + From fbbb092356aab91d509c250ee3597556a547d838 Mon Sep 17 00:00:00 2001 From: Alexey Kuznetsov Date: Wed, 16 Mar 2016 06:18:05 +0300 Subject: [PATCH 2/2] Bump version 1.0.17 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 083e54c..893c7e0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.github.axet.audiorecorder" minSdkVersion 16 targetSdkVersion 23 - versionCode 17 - versionName "1.0.16" + versionCode 18 + versionName "1.0.17" } signingConfigs { release {