I have an issue with renaming a file it seems every time I try to they end up being multiplied and are created 2 times the amount I.e. if I have one song that I want to rename in the list view and hold the on long click event it doubles the amount say 2 to 4 songs and 4 to 12 and so on in my list view . I'm using an OnItemLongClickListener to handle the files being created for each item click on the list view to be renamed . I have no idea why it isn't working ... I have even tried setting the position to
String pos = lv.getItemAtPosition(position);
And many other ways ...
But no use it ends up being a random number that is being multiplied ... My question is why ; how can fix .
downloadsList.setOnItemLongClickListener(
new OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> parent , View view , int position , long itemId ){
EditText bar = (EditText)findViewById(R.id.search);
String to = bar.getText().toString();
(ListView) findViewById(R.id.downloads);
File[] pos = files.listFiles();
File filein = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() , files.getName());
File fileTo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + to);
if(!filein.exists()){
filein.renameTo(fileTo);
} else {
try {
throw new IOException("File exists");
}catch (IOException e){
e.printStackTrace();
}
}
finish();
overridePendingTransition(0, 0);
startActivity(getIntent());
overridePendingTransition(0, 0);
return true;
}
});
Here is the list view method to populate it
private void ShowLists(){
files = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS).toString());
downloads = files.listFiles(new FileFilter(){
#Override
public boolean accept(File file){
String ext = file.getName();
if(ext.endsWith(".mp3")){
return true;
}
return false;
}
});
mp3s = new String[downloads.length];
for(int i = 0 ; i < mp3s.length; i++){
mp3s[i] = downloads[i].getName();
}
adapter = new ArrayAdapter<String>(this,R.layout.downloads, R.id.textviewone , mp3s);
ListView downloadsList = (ListView) findViewById(R.id.downloads);
downloadsList.setAdapter(adapter);
}
This is before http://imgur.com/rBmSAXK
This is after I click the long click to rename a file and the on going complication http://imgur.com/I9szC6m
UPDATED CODE
public boolean onItemLongClick(AdapterView<?> parent , View view , int position , long itemId ){
EditText bar = (EditText)findViewById(R.id.search);
String to = bar.getText().toString();
ListView lv = (ListView) findViewById(R.id.downloads);
String pos = lv.getItemAtPosition(position).toString();
File filein = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() , pos);
File fileTo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() , to);
filein.renameTo(fileTo);
finish();
overridePendingTransition(0, 0);
startActivity(getIntent());
overridePendingTransition(0, 0);
return true;
}
});
Related
I'm working on an android app, an mp3 player to be precise, and I would like to add all the .mp3 files it can find on the phone to the library. The problem is that it seems like the android app gets installed in a strange folder (I am unable to find the folder on my phone) and only searches files in that folder. In my AndroidManifest file, I added this line of code to ask for permissions and it works fine:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I also tried to emulate the app on Android studio and I noticed that the app got located in a folder like /storage/emulated/0 and it only searched for files in that directory.
This is my method to search for files:
public ArrayList<File> findSong (File file) {
ArrayList<File> arrayList = new ArrayList<>();
File[] files = file.listFiles();
if (files != null) {
for (File singlefile : files) {
if (singlefile.isDirectory() && !singlefile.isHidden()) {
arrayList.addAll(findSong(singlefile));
} else {
if (singlefile.getName().endsWith(".mp3") || singlefile.getName().endsWith(".wav")) {
arrayList.add(singlefile);
}
}
}
}
return arrayList;
}
And this is the function to display the songs in a list:
void displaySongs() {
final ArrayList<File> mySongs = findSong(Environment.getExternalStorageDirectory());
items = new String[mySongs.size()];
for (int i = 0; i<mySongs.size(); i++) {
items[i] = mySongs.get(i).getName().toString().replace(".mp3", "")
.replace(".wav", "");
}
/*
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
listView.setAdapter(myAdapter);
*/
customAdapter customAdapter = new customAdapter();
listView.setAdapter(customAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String songName = (String) listView.getItemAtPosition(position);
startActivity(new Intent(getApplicationContext(), PlayerActivity.class)
.putExtra("songs", mySongs)
.putExtra("songname", songName)
.putExtra("pos", position));
}
});
}
The songs get listed like this and when you click on them the player opens and starts playing the song:
I'm new at all this, but what the method should do is search through all files in the phone's storage and add to the list those who end with either .mp3 or .wav.
Any help, explanation, and/or feedback is highly appreciated. If you need some more information I will be happy to share it with you.
public List<AudioModel> getAllAudioFromDevice(final Context context) {
final List<AudioModel> tempAudioList = new ArrayList<>();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.AudioColumns.TITLE, MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.ArtistColumns.ARTIST,};
// if want from specific folder
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA + " like ? ", new String[]{"%utm%"}, null);
// if want fetch all files
Cursor c = context.getContentResolver().query(uri,
projection,
null,
null,
null);
if (c != null) {
while (c.moveToNext()) {
AudioModel audioModel = new AudioModel();
String path = c.getString(0);
String name = c.getString(1);
String album = c.getString(2);
String artist = c.getString(3);
audioModel.setaName(name);
audioModel.setaAlbum(album);
audioModel.setaArtist(artist);
audioModel.setaPath(path);
Log.e("Name :" + name, " Album :" + album);
Log.e("Path :" + path, " Artist :" + artist);
tempAudioList.add(audioModel);
}
c.close();
}
return tempAudioList;
}
If you look at the second code snippet I have in the answer, you can see that I tell the app to search in a Directory by using a deprecated Function:
final ArrayList<File> mySongs = findSong(Environment.getExternalStorageDirectory());
Environment.getExternalStorageDirectory() is deprecated in API level 29.
Now I didn't notice it because the API I am using is 23 and there was no error while trying the app in the emulator. But when I tried it on my Samsung s9 there was obviously a problem because the API there is definitely higher.
Luckily I found a very easy fix. It's probably neither the best nor the most efficient, all I'm saying is that it worked for me:
Just add the following line in your Manifest file in the application-tag:
android:requestLegacyExternalStorage="true"
What it does is somehow give external storage permissions on newer devices too.
I don't know exactly how it works. I'm gonna leave this here because maybe in the future it might help someone else too.
using MediaStore.Audio
private void lodfrmdvic() {
linearlayout.removeAllViews();//clear albums or favs or ondevic
//LinearLayout linearlayout = (LinearLayout) findViewById(R.id.linearlayout);
dataaray = new ArrayList<>();
titlaray = new ArrayList<>();
albmaray = new ArrayList<>();
artstaray = new ArrayList<>();
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
final Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if (cursor != null && cursor.getCount() > 0) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.weight = 1.0f;//params.gravity = Gravity.END;
while (cursor.moveToNext()) {
final int curndx =cursor.getPosition();
/** when using cursor.getPosition() make failre becase it set in title.setOnClickListener the last valu(cursor Counts)
using int or string then insert it in title.setOnClickListener solve problem */
final String dsnam = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));//title+extion
final String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
//final String titl = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
final String titl = dsnam.replace( dsnam.substring(dsnam.lastIndexOf(".")) ,"");//to show titl=filename wthot exton
// Save to arrays
dataaray.add(data);
titlaray.add(titl);
albmaray.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));
artstaray.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
LinearLayout mrow = new LinearLayout(this);
mrow.setPadding(0,20,0,20);
TextView title =new TextView(this);
//title.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f));
title.setLayoutParams(params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//17
title.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);//for start arabic if app lang is english and vice versa
}
ImageButton mor = new ImageButton(this);
//to short long title
String shrttitl = titl;
if(titl.length()>30){shrttitl=titl.substring(0,30)+"...";}//show till and ltr 30
title.setText(shrttitl);
mrow.addView(title);
//if(Build.VERSION.SDK_INT < 21){mor.setBackground(getResources().getDrawable(R.drawable.ic_baseline_cloud_upload_24));}
//else{mor.setBackground(getDrawable(R.drawable.ic_baseline_cloud_upload_24));}
mor.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.ic_baseline_cloud_upload_24, getTheme()));
mrow.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) {playaudio(curndx);} });
mor.setOnClickListener(new View.OnClickListener() { #Override public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(Showsonds.this);
// builder.setTitle("del?");
// builder.setCancelable(false);
builder.setMessage(getString(R.string.ad)+" "+titl+" "+getString(R.string.tomyclod))
.setPositiveButton( getString(R.string.yes) , new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { adtomine(data,dsnam,titl); }
})
.setNegativeButton( getString(R.string.cncl) , new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { dialog.cancel(); }
});
AlertDialog dialog = builder.create();
dialog.show();
} });
mrow.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//toast("looooooooong clk");
//todo show >>
toast(titl);
return true;
} });
mrow.addView(mor);
linearlayout.addView(mrow);
}cursor.close();
}
}
I am capturing images, then storing into SD Card and showing in a List, but here i need a small change, still i am getting old on top and latest at bottom, so now i want to show latest picture on the top on the basis of datetimestamp using as a part of file name.
UploadActivity.java code:-
String fileName;
static List <String> ImageList;
/*** Get Images from SDCard ***/
ImageList = getSD();
// ListView and imageAdapter
lstView = (ListView) findViewById(R.id.listView1);
lstView.setAdapter(new ImageAdapter(this));
}
public static List <String> getSD()
{
List <String> it = new ArrayList <String>();
String string = "/mnt/sdcard/Pictures/SamCam/";
f = new File (string+ CameraLauncherActivity.folder+ "/");
files = f.listFiles ();
for (int i = 0; i < files.length; i++)
{
file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
return it;
}
public class ImageAdapter extends BaseAdapter
{
private Context context;
public ImageAdapter(Context c)
{
// TODO Auto-generated method stub
context = c;
}
Note: I am using date/timestamp while storing my images into SD Card.
so finally it looks like this:
AU_20140328163947_1_4_X-1-4-006.jpg
and still files listing in below format, like below:
AU_20140328163947_1_4_X-1-4-006.jpg
AU_20140328163948_1_4_X-1-4-007.jpg
AU_20140328163949_1_4_X-1-4-008.jpg
but i want to list files in below format:-
AU_20140328163949_1_4_X-1-4-008.jpg
AU_20140328163948_1_4_X-1-4-007.jpg
AU_20140328163947_1_4_X-1-4-006.jpg
Code to Delete Image in a List:--
// btnDelete
final ImageButton btnDelete = (ImageButton) convertView.findViewById(R.id.btnDelete);
btnDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
// set title
alertDialogBuilder.setTitle("Delete Image");
// Setting Icon to Dialog
alertDialogBuilder.setIcon(R.drawable.ic_launcher);
// set dialog message
alertDialogBuilder
.setMessage("Are you sure you want to delete this image?")
.setCancelable(false)
.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, close
// current activity
// to get fileName
fileName = ImageList.get(position).toString().substring(strPath.lastIndexOf('/')+1, strPath.length());
// to get SD card path (Folders+fileName)
String fileToDelete = Environment.getExternalStorageDirectory().getPath() +"/Pictures/SamCam/" + CameraLauncherActivity.folder+ "/" + fileName;
Log.d("FileToDelete", fileToDelete);
File myFile = new File(fileToDelete);
// if image exists
if(myFile.exists())
// delete image
myFile.delete();
// get position and delete
ImageList.remove(position);
// to refresh the view
((BaseAdapter) lstView.getAdapter()).notifyDataSetChanged();
dialog.cancel();
}
})
.setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
// TODO Auto-generated method stub
}
});
return convertView;
}
}
If you getting data in reverse order than you can use reverse loop.
Try below loop
for (int i = files.length-1; i >= 0; i--)
{
file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
instead of
for (int i = 0; i < files.length; i++)
{
file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
or sort data with particular field
Sort array data before using in for loop and use same loop..
Arrays.sort(files, new Comparator<Object>()
{
public int compare(Object o1, Object o2) {
if (((File)o1).lastModified() > ((File)o2).lastModified()) {
return -1;
} else if (((File)o1).lastModified() < ((File)o2).lastModified()) {
return +1;
} else {
return 0;
}
}
});
for (int i = 0; i < files.length; i++)
{
file = files[i];
Log.d("Count",file.getPath());
it.add (file.getPath());
}
Use MediaStore ContentProvider for this job
Save the image using MediaStore using this method
And you can query the image using this method
Set the order by as MediaStore.Images.Media.DATE_TAKEN
You can use the Collections.sort method in your list adapter to sort the values according to the image file name like:
Collections.sort(ImageList, new Comparator<String>() {
int compare(String obj1, String obj2) {
return obj1.compareTo(obj2);
}
});
compareTo method and also compareToIgnoreCase method, use wichever you think is appropriate, and also, you can experiment with obj1 and obj2, that is, you could swap the condition to:
return obj2.compareTo(obj1);
That way your list will be sorted. Hope that helps!
EDIT:
Since you know that the format is _ and then -.jpg, what you can do is in the comparator split the value from - like:
Collections.sort(ImageList, new Comparator<String>() {
int compare(String obj1, String obj2) {
String[] obj1Arr = obj1.split(-);
String[] obj2Arr = obj2.split(-);
obj1Arr = obj1Arr[1].split("."); // to just get the counter value
obj2Arr = obj2Arr[1].split(".");
return obj1Arr[0].compareTo(obj2Arr[0]);
}
});
I have been trying to find answers, but it has been hard to find a solution that works.
I tried setting the adapter to null, clearing the actual list but neither seems to work.
I am using a ListView with a ListAdapter and am trying to make it clear on a change of search Text when text is changed.
list.clear(); works but it does not occur on text change.
Here is my code:
private EditText search_input;
private Button search_button;
// progress bar for search results
private ProgressDialog search_loading;
private ListView wordSearchList;
private ListAdapter adapter;
// no result layout
private LinearLayout no_res;
// create list for adapter
ArrayList<HashMap<String, String>> list;
// database helper
private DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dictionary_search);
search_input = (EditText) findViewById(R.id.search_dictionary);
search_button = (Button) findViewById(R.id.search_button);
search_button.setOnClickListener(this);
// linear layout for no results
no_res = (LinearLayout) findViewById(R.id.search_result_ll);
// create hashmap list
list = new ArrayList<HashMap<String, String>>();
// remove views if they exist
search_input.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// REMOVE LIST VIEW AND ADAPTER
// list.clear();
if (no_res.getChildCount() > 0) {
no_res.removeAllViews();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public void onClick(View v) {
if (v == search_button) {
// clear list for fresh start
list.clear();
no_res.removeAllViews();
// validate input and that something was entered
if (search_input.getText().toString().length() < 1) {
// missing required info (null was this but lets see)
Toast.makeText(getApplicationContext(),
"Please search for something!", Toast.LENGTH_LONG)
.show();
} else {
String search_data;
search_data = search_input.getText().toString();
// remove any current views on search again
// REMOVE THE LIST VIEW
// execute the query search
List<DatabaseWordsFTS> search_results = db
.getSingleWordSearch(search_data);
// if no search results returned
if (search_results.size() <= 0) {
TextView no_results_tv = new TextView(this);
no_results_tv.setText("No results found.");
no_res.addView(no_results_tv);
}
// setup listview
wordSearchList = (ListView) findViewById(R.id.wordSearchList);
for (DatabaseWordsFTS word_found : search_results) {
// have to create hashmap in loop
HashMap<String, String> map = new HashMap<String, String>();
// convert d id to long
Integer dictionary_id_convert = (int) (long) word_found._dictionaryId;
// extract dictionary from d-id - since it is not a list and
// just a variable
DatabaseDictionary dictionary_found = db
.getDictionary(dictionary_id_convert);
// extract languages to send below
Integer dln_1 = (int) dictionary_found._language1Id;
Integer dln_2 = (int) dictionary_found._language2Id;
Integer dln_3 = (int) dictionary_found._language3Id;
Integer dln_4 = (int) dictionary_found._language4Id;
// get languages for the words based on ids passed in
List<DatabaseLanguages> LanguagesForD = db
.getAllLanguagesWithId(dln_1, dln_2, dln_3, dln_4);
// add name to hashmap and rest of the data as strings
map.put("w_1", word_found.get_word1_fts());
map.put("l_1", LanguagesForD.get(0)._language_name);
map.put("d_id", String.valueOf(dictionary_id_convert));
map.put("w_id", String.valueOf(word_found.get_id()));
if (word_found.get_word2_fts() != null) {
map.put("w_2", word_found.get_word2_fts());
map.put("l_2", LanguagesForD.get(1)._language_name);
}
if (word_found.get_word3_fts() != null) {
map.put("w_3", word_found.get_word3_fts());
map.put("l_3", LanguagesForD.get(2)._language_name);
}
if (word_found.get_word4_fts() != null) {
map.put("w_4", word_found.get_word4_fts());
map.put("l_4", LanguagesForD.get(3)._language_name);
}
list.add(map);
// used to dismiss progress bar for searching
search_loading.dismiss();
}
String[] from = { "w_1", "w_2", "w_3", "w_4" }; // , "word3",
// "word4"
int[] to = { R.id.textName, R.id.textLanguage };
adapter = new SimpleAdapter(this, list,
R.layout.dictionary_row, from, to);
wordSearchList.setAdapter(adapter);
wordSearchList
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
// ListView Clicked item index
int itemPosition = position;
// ListView Clicked item value
HashMap itemValue = (HashMap) wordSearchList
.getItemAtPosition(position);
String w_id = (String) itemValue.get("w_id");
String d_id = (String) itemValue.get("d_id");
String l_1 = (String) itemValue.get("l_1");
String l_2 = (String) itemValue.get("l_2");
String l_3 = (String) itemValue.get("l_3");
String l_4 = (String) itemValue.get("l_4");
String w_1 = (String) itemValue.get("w_1");
String w_2 = (String) itemValue.get("w_2");
String w_3 = (String) itemValue.get("w_3");
String w_4 = (String) itemValue.get("w_4");
// Show Alert
Toast.makeText(
getApplicationContext(),
"Position :" + itemPosition
+ " ListItem : " + w_id,
Toast.LENGTH_LONG).show();
// creating bundle
Bundle d_data = new Bundle();
// add to bundle
d_data.putString("w_id", w_id);
d_data.putString("wd_id", d_id);
d_data.putString("w_1", w_1);
d_data.putString("l_1", l_1);
// get tags only if it exists
if (w_2 != null) {
d_data.putString("w_2", w_2);
d_data.putString("l_2", l_2);
}
if (w_3 != null) {
d_data.putString("w_3", w_3);
d_data.putString("l_3", l_3);
}
if (w_4 != null) {
d_data.putString("w_4", w_4);
d_data.putString("l_4", l_4);
}
// start new intent based on the tag -
Intent single_word_view = new Intent(
DictionaryWordSearch.this,
DictionarySingleWordView.class);
// call extras
single_word_view.putExtras(d_data);
// new_dictionary_view.putExtra("d_id",
// WhatAmISupposeToPassInHere);
startActivity(single_word_view);
}
});
}
EDIT: (Below worked for me)
Changed ListAdapter to SimpleAdapter
if(adapter != null){list.clear(); adapter.notifyDataSetChanged();}
Added the above code in onTextChange
Look if you want the TextView with no result you can implement this code
listView.setEmptyView(emptyView)
and pass your TextView to this method ,
for clearing the ListView you can clear your collection and call notifyChangeDataSet or set adapter with null try both and feed me back
I have a listview which display a list of files (without filename extension) stored in the internal memory of the phone.
Then I have implement the OnItemLongClickListener that allow the user to delete a file.
OnItemLongClickListener works with the "switch" statement.
because position of the items in the list view will change every time a file will be deleted, I would like to implement a rule that check if the name of the file match the related file, no matter if name of the file is moved in case 0, case 1 and so on.
To be clear:
Initial Listview:
switch Listview items related file to delete
case 0; A A.map
case 1; B B.map
case 2; C C.map
case 3; D D.map
Listview after B has been deleted:
switch Listview items related file to delete
case 0; A A.map
case 1; C C.map
case 2; D
Now, if before I wrote a rule at case 1 which was to delete B.map, it works fine.
But now item C have the same rule of case 1 , and rule does not match.
Because I am new to android, I don't know how to dove this problem.
Can somebody help me?
This is the Activity
public class MainActivity extends Activity {
ListView lv;
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.listView1);
File dir = new File(Environment.getExternalStorageDirectory().getPath() + "/osmdroid/tiles/");
File[] filelist = dir.listFiles();
String[] theNamesOfFiles = new String[filelist.length];
for (int i = 0; i < theNamesOfFiles.length; i++) {
String temp = filelist[i].getName();
theNamesOfFiles[i] = temp.substring(0, temp.lastIndexOf('.'));
}
Arrays.sort(theNamesOfFiles);
adapter = new ArrayAdapter<String>(this, R.layout.list_row, theNamesOfFiles);
lv.setAdapter(adapter);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
// setting onItemLongClickListener and passing the position to the function
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
switch(position){
case 0:{
}
break;
case 1:{
}
break;
case 2:{
}
break;
case 3:{
}
break;
case 4:{
}
break;
}
return true;
}
});
}
public void doDeleteFile(int position){
File fileToDelete = new File(Environment.getExternalStorageDirectory().getPath() + "/osmdroid/tiles/", "A.map");
if(!fileToDelete.isDirectory()){
try{
if(fileToDelete.delete()){
System.out.println("File delete operation success");
}
else{
System.out.println("File delete operation failed");
}
}catch(Exception ex){
System.out.println("Exception :"+ex.getMessage());
}
}else{
System.out.println("It is not a file");
}
}
}
when you deleted your item remove it from array also and then call notifyDataSetChange() on adapter after updating the array item
No need to check for name.You can do it by position
I would do it like this:
First I will have a data structure about the items.
public class MyFile {
File file;
String fileName;
public MyFile(File file)
{
this.file = file;
this.fileName = file.getName();
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
}
#Override
public String toString() {
return this.fileName;
}
}
toString() method is important. That method gives the text in the ListView in the ArrayAdapter.
Then I would initialize the adapter like this.
adapter = new ArrayAdapter<MyFile>(this, R.layout.list_row, arrayOfMyFileObjects);
And lastly in onItemLongClick() function you can get the respective MyFile object like this
MyFile item = adapter.getItem(position);
And then you can delete using deleteFile(item.file);
I think the below code should do it.
public class MainActivity extends Activity {
ListView lv;
ArrayAdapter<MyFile> adapter;
public void list() {
lv = (ListView) findViewById(R.id.listView1);
File dir = new File(Environment.getExternalStorageDirectory().getPath()
+ "/osmdroid/tiles/");
File[] filelist = dir.listFiles();
ArrayList<MyFile> theNamesOfFiles = new ArrayList<MyFile>();
for (File temp : filelist) {
theNamesOfFiles.add(new MyFile(temp));
}
Collections.sort(theNamesOfFiles, new Comparator<MyFile>() {
#Override
public int compare(MyFile lhs, MyFile rhs) {
return lhs.toString().compareToIgnoreCase(rhs.toString());
}
});
adapter = new ArrayAdapter<MyFile>(this, R.layout.list_row,
theNamesOfFiles);
lv.setAdapter(adapter);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
list();
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
// setting onItemLongClickListener and passing the position to the
// function
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
doDeleteFile(adapter.getItem(position).file);
return true;
}
});
}
public void doDeleteFile(File fileToDelete) {
if (!fileToDelete.isDirectory()) {
try {
if (fileToDelete.delete()) {
System.out.println("File delete operation success");
}
else {
System.out.println("File delete operation failed");
}
} catch (Exception ex) {
System.out.println("Exception :" + ex.getMessage());
}
} else {
System.out.println("It is not a file");
}
}
public class MyFile {
File file;
String fileName;
public MyFile(File file)
{
this.file = file;
this.fileName = file.getName();
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
}
#Override
public String toString() {
return this.fileName;
}
}
}
in my android application I have a Button which adds a new dynamic Spinner to the Layout. All of the created Spinners are using the same Array.
What is working until now, I can save the number of created Spinners and recreate them after restarting the Application.
But I really would like to save the selectedPosition of each Spinner in the sharedPreferences and this is where I'm stucking in a ForceClose Desaster...
In my understanding, every Spinner gets an ID when created so you can save the Position bounded on this ID in the preferences.
So this is what I did:
public void addSpinner(){
LinearLayout AddLayout = (LinearLayout)findViewById(R.id.linearAddScroll);
spinner = new Spinner(this);
ArrayAdapter<?> adapt = ArrayAdapter.createFromResource(this,
R.array.Filter, android.R.layout.simple_spinner_item);
adapt.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapt);
AddLayout.addView(spinner);
}
this creates the Spinner.
public void onClick(View v) {
addSpinner();
int ID = 1000+x;
spinner.setId(ID);
Toast.makeText(MatReporterActivity.this,"ID" + ID, 5)
.show();
x++;
}
set the ID.
This is what I do in the on Create method:
x = settings.getInt("xsave", 1);
for(y = 1; y < x; y++){
addSpinner();
int ID = 1000+y;
Spinner s = (Spinner) findViewById(ID);
String ys= Integer.toString(ID);
Toast.makeText(MatReporterActivity.this,"ID" +ys, 5)
.show();
int yf = settings.getInt(ys, 1);
s.setSelection(yf);
}
And this onStop():
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("xsave", x);
for(y = 1; y < x; y++){
int ID = 1000+y;
Spinner s2= (Spinner) findViewById(ID);
int possS = s2.getSelectedItemPosition();
Toast.makeText(MatReporterActivity.this, "IDStop" + ID, 5)
.show();
String ys= Integer.toString(ID);
editor.putInt(ys, possS);
}
editor.commit();
}
I think there is a logical Problem in the onCreate Method, but I'm not able to find it, also I didn't find any help in the web how to populate and save dynamically created spinners.
So maybe someone has an idea.
thanks.
SharedPreferences are not a good way to store this kind of data. You should try to follow those 2 steps :
Create a class which implements Serializable to represent the data you want to store (you might use a list of Serializable objects)
public class SpinnerSave implements Serializable {
public String ID;
public int selection;
public SpinnerSave(String ID, int selection){
this.ID = ID;
this.selection = selection;
}
}
Then you should write your data into a file like so
private void saveState() {
final File cache_dir = this.getCacheDir();
final File suspend_f = new File(cache_dir.getAbsoluteFile() + File.separator + SUSPEND_FILE);
FileOutputStream fos = null;
ObjectOutputStream oos = null;
boolean keep = true;
try {
fos = new FileOutputStream(suspend_f);
oos = new ObjectOutputStream(fos);
oos.writeObject(this.gameState);
}
catch (Exception e) {
keep = false;
Log.e("MyAppName", "failed to suspend", e);
}
finally {
try {
if (oos != null) oos.close();
if (fos != null) fos.close();
if (keep == false) suspend_f.delete();
}
catch (Exception e) { /* do nothing */ }
}
}