I have an Android app with intent filter for "http". After install the user get "open with" dialog when he press a url in the browser.
My question is: If the user chose by mistake "open with x always" and he wants to change his selection to open the url with another app, how can he get the "choose app" dialog again ?
You have to clear the cache of the application.
For clearing cache you have take permission -
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
Call deleteCahce() to clear cahe
public static void deleteCache(Context context) {
try {
File dir = context.getCacheDir();
deleteDir(dir);
} catch (Exception e) {}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
return dir.delete();
} else if(dir!= null && dir.isFile()) {
return dir.delete();
} else {
return false;
}
}
Clear the cache before showing "Open With".
I am working on an app that allows user to select a file from external storage and send it using Android Beam.
Here is the FileBrowser Activity to select a file from a directory and return the file name and directory path back to main activity:
public class FileBrowser extends Activity {
private String root;
private String currentPath;
private ArrayList<String> targets;
private ArrayList<String> paths;
private File targetFile;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_browser);
getActionBar().setDisplayHomeAsUpEnabled(true);
root = "/";
currentPath = root;
targets = null;
paths = null;
targetFile = null;
showDir(currentPath);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_file_browser, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public void selectDirectory(View view) {
File f = new File(currentPath);
targetFile = f;
//Return target File to activity
returnTarget();
}
public void setCurrentPathText(String message)
{
TextView fileTransferStatusText = (TextView) findViewById(R.id.current_path);
fileTransferStatusText.setText(message);
}
private void showDir(String targetDirectory){
setCurrentPathText("Current Directory: " + currentPath);
targets = new ArrayList<String>();
paths = new ArrayList<String>();
File f = new File(targetDirectory);
File[] directoryContents = f.listFiles();
if (!targetDirectory.equals(root))
{
targets.add(root);
paths.add(root);
targets.add("../");
paths.add(f.getParent());
}
for(File target: directoryContents)
{
paths.add(target.getPath());
if(target.isDirectory())
{
targets.add(target.getName() + "/");
}
else
{
targets.add(target.getName());
}
}
ListView fileBrowserListView = (ListView) findViewById(R.id.file_browser_listview);
ArrayAdapter<String> directoryData = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, targets);
fileBrowserListView.setAdapter(directoryData);
fileBrowserListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int pos,long id) {
File f = new File(paths.get(pos));
if(f.isFile())
{
targetFile = f;
returnTarget();
//Return target File to activity
}
else
{
//f must be a dir
if(f.canRead())
{
currentPath = paths.get(pos);
showDir(paths.get(pos));
}
}
}
});
}
public void returnTarget()
{
Intent returnIntent = new Intent();
returnIntent.putExtra("file", targetFile);
returnIntent.putExtra("path", currentPath);
setResult(RESULT_OK, returnIntent);
finish();
}
}
Here is the code for MainActivity where the file returned by FileBrowser Activity is send using android beam:
public class MainActivity extends Activity {
private NfcAdapter nfcAdapter;
public final int fileRequestID = 98;
String name;
String[] extension={".png",".docx",".jpeg",".pdf",".doc"};
ArrayList <String>supportedExtension=new ArrayList<String>(Arrays.asList(extension));
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageManager pm = this.getPackageManager();
// Check whether NFC is available on device
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
Toast.makeText(this, "The device does not has NFC hardware.",
Toast.LENGTH_SHORT).show();
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
Toast.makeText(this, "Android Beam is not supported.",
Toast.LENGTH_SHORT).show();
}
else {
// NFC and Android Beam file transfer is supported.
Toast.makeText(this, "Android Beam is supported on your device.",
Toast.LENGTH_SHORT).show();
}
}
public void browseForFile(View view) {
Intent clientStartIntent = new Intent(this, FileBrowser.class);
startActivityForResult(clientStartIntent, fileRequestID);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//fileToSend
boolean filePathProvided;
File fileToSend;
if (resultCode == Activity.RESULT_OK && requestCode == fileRequestID) {
//Fetch result
File targetDir = (File) data.getExtras().get("file");
String path = (String)data.getExtras().get("path");
Log.i("Path=",path);
if(targetDir.isFile())
{
if(targetDir.canRead()) {
try{
String ext=targetDir.getName().substring(targetDir.getName().lastIndexOf("."));
if (supportedExtension.contains(ext)) {
fileToSend = targetDir;
filePathProvided = true;
setTargetFileStatus(targetDir.getName() + " selected for file transfer");
Button btn = (Button) findViewById(R.id.send);
btn.setVisibility(View.VISIBLE);
name = targetDir.getName();
}
else{
Toast.makeText(getApplicationContext(), "File with this extension cannot be printed",
Toast.LENGTH_LONG).show();
}
}catch (Exception e){e.printStackTrace();}
}
else
{
filePathProvided = false;
setTargetFileStatus("You do not have permission to read the file " + targetDir.getName());
}
}
else
{
filePathProvided = false;
setTargetFileStatus("You may not transfer a directory, please select a single file");
}
}
}
public void setTargetFileStatus(String message)
{
TextView targetFileStatus = (TextView) findViewById(R.id.selected_filename);
targetFileStatus.setText(message);
}
public void sendFile(View view) {
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
// Check whether NFC is enabled on device
if(!nfcAdapter.isEnabled()){
Toast.makeText(this, "Please enable NFC.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
}
else if(!nfcAdapter.isNdefPushEnabled()) {
Toast.makeText(this, "Please enable Android Beam.",
Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
}
else {
Uri[] mFileUris = new Uri[1];
String fileName=name;
// Retrieve the path to the user's public pictures directory
File fileDirectory = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File fileToTransfer;
fileToTransfer = new File(fileDirectory, fileName);
fileToTransfer.setReadable(true, false);
mFileUris[0] = Uri.fromFile(fileToTransfer);
nfcAdapter.setBeamPushUris(mFileUris, this);
}
}
}
Now, as you can see in my MainActivity, I am setting my directory as Pictures.
File fileDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
My question is How can I dynamically change my directory every time based on the actual directory value obtained from FileBrowser Activity?
I have already went through the android documentation of How to send files using Android Beam, but didn't find it much useful for my problem. I also went through the android documentation of Environment, but couldn't understand much.
Any help regarding this will really be appreciated. Thanks in advance!
You already have the file selected in OnActivityResult method. Just change
mFileUris[0] = Uri.fromFile(fileToTransfer);
to
mFileUris[0] = Uri.fromFile(targetDir);
i am trying to implement below code every thing works fine how ever
here is the situation i am facing
mainactivity just has a button to open splashactivity
splash activity does the parsing part then opens the listactvity
my workflow is if user has clicked on the button in main activity
it opens the splash activity and redirects to listactivty the
problem occurs when on the splash activity if a user clicks the
andorid back button it does go back to the mainactivity however the
parsing in splashactivity continues and user is redirected to
listactivty this thing should not happen, when user on splash
activity has clicked backbutton it should go back to mainactivity
and stay there itself
how can this be done
package com.site.name;
public class SplashActivity extends Activity {
RSSFeed feed;
String fileName;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
fileName = "TDRSSFeed.td";
Intent i = getIntent();
int position = i.getExtras().getInt("position");
String[] country = i.getStringArrayExtra("country");
// //public String RSSFEEDURL = "http://blogname.blogspot.com//feeds/posts/default/-/Awards?alt=rss";
Toast.makeText(getApplicationContext(), country[position], Toast.LENGTH_SHORT).show();
//Toast.makeText(getApplicationContext(), country[position], Toast.LENGTH_SHORT).show();
File feedFile = getBaseContext().getFileStreamPath(fileName);
ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() == null) {
// No connectivity. Check if feed File exists
if (!feedFile.exists()) {
// No connectivity & Feed file doesn't exist: Show alert to exit
// & check for connectivity
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"Unable to reach server, \nPlease check your connectivity.")
.setTitle("TD RSS Reader")
.setCancelable(false)
.setPositiveButton("Exit",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
} else {
// No connectivty and file exists: Read feed from the File
Toast toast = Toast.makeText(this,
"No connectivity!",
Toast.LENGTH_LONG);
toast.show();
//feed = ReadFeed(fileName);
startLisActivity(feed);
}
} else {
// Connected - Start parsing
new AsyncLoadXMLFeed().execute();
}
}
private void startLisActivity(RSSFeed feed) {
Bundle bundle = new Bundle();
bundle.putSerializable("feed", feed);
// launch List activity
Intent intent = new Intent(SplashActivity.this, ListActivity.class);
intent.putExtras(bundle);
startActivity(intent);
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
// kill this activity
finish();
}
private class AsyncLoadXMLFeed extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// Obtain feed
DOMParser myParser = new DOMParser();
Intent i = getIntent();
int position = i.getExtras().getInt("position");
String[] country = i.getStringArrayExtra("country");
//feed = myParser.parseXml(RSSFEEDURL);
//feed = myParser.parseXml("http://blogname.blogspot.com//feeds/posts/default/-/Awards?alt=rss");
feed = myParser.parseXml("http://blogname.blogspot.com//feeds/posts/default/-/" + country[position] + "?alt=rss");
if (feed != null && feed.getItemCount() > 0)
WriteFeed(feed);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
startLisActivity(feed);
}
}
// Method to write the feed to the File
private void WriteFeed(RSSFeed data) {
FileOutputStream fOut = null;
ObjectOutputStream osw = null;
try {
fOut = openFileOutput(fileName, MODE_PRIVATE);
osw = new ObjectOutputStream(fOut);
osw.writeObject(data);
osw.flush();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onBackPressed() {
//Include the code here
return;
}
}
You can cancel parsing the feed in MainActivity's onRestart() as this is one method of MainActivity that will be called when you press back from your Parsing Activity.
You can read more about Activity Life Cycle here.
For detecting the Back button press event use the following method
#Override
public void onBackPressed() {
// do something on back.
// Change your activity by calling intent
return;
}
If you want to do anything with your back button then you have to override it manually.
#Override
Public void onBackPressed() {
//do whatever you want to do as your question is quite confusing.
return;
}
I am new to android and am writing an app to copy all document files into my PC programmatically. I have the list of files in folders with me (Currently in a listview). All I need to know is how to copy each file into my PC. Once copied, how to retrieve them back? I am sure that I need to code a server side program in my PC as well, But a little concerned on where to start and how. Below is the android code snippet.
public class DocsList extends Activity implements OnClickListener {
CheckBox ChkSelectAll;
ListView DocsList;
Button Backup, Reset, GoBack;
TextView textview;
String[] FileNames;
int k = 0;
public List<String> myList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myList = new ArrayList<String>();
setContentView(R.layout.docslist);
ChkSelectAll = (CheckBox)findViewById(R.id.SelectAllDocscheckBox);
DocsList = (ListView)findViewById(R.id.DocsList);
Backup = (Button)findViewById(R.id.BackupDocs);
Reset = (Button)findViewById(R.id.ResetDocs);
GoBack = (Button)findViewById(R.id.GoBackDocs);
String dir = Environment.getExternalStorageDirectory().toString();
File f = new File(dir);
ArrayList<String> files = getListofDocs(f);
ArrayAdapter<String> PhoneAdptr = new ArrayAdapter<String>(this, android.R.layout.simple_selectable_list_item,files);
DocsList.setAdapter(PhoneAdptr);
boolean NetState = isNetworkConnected(this);
if (NetState == true) {
// Code yet to be written
}
else {
// Code yet to be written
}
}
private boolean isNetworkConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}
public ArrayList<String> getListofDocs(File parentdir) {
ArrayList<String> infiles = new ArrayList<String>();
File[] files = parentdir.listFiles();
if (files != null) {
for(File file : files)
if (file.isDirectory()) {
infiles.addAll(getListofDocs(file));
}
else {
if (file.getName().endsWith("doc") || file.getName().endsWith("DOC") ||
file.getName().endsWith("docx") || file.getName().endsWith("DOCX") ||
file.getName().endsWith("htm") || file.getName().endsWith("HTM") ||
file.getName().endsWith("html") || file.getName().endsWith("HTML") ||
file.getName().endsWith("txt") || file.getName().endsWith("TXT") ||
file.getName().endsWith("pdf") || file.getName().endsWith("PDF")) {
infiles.add(file.toString());
}
}
}
return infiles;
}
#Override
public void onClick(View v) {
if (v == GoBack) {
Intent Back = new Intent(DocsList.this, CloudStorage.class);
startActivity(Back);
finish();
}
}
}
I have made use of Dropbox to store my files. Thanks all for your help. I am still working on the retrieval though.
In Android, How would one save a text file from the internet to the sdcard, load the file from the sdcard and separate the entries of the file by commas into a ListView?
It's important that more than one of the entries in the ListView can be selected at once.
The use of fragments would be nice too, as it would make it easier to use with different screen sizes such as phones vs. tablets.
I see your question as 2 different problems, each with their own solutions and obstacles, that come together in the end. My examples are all compiled against API16 (4.1 Jelly Bean) with a minimum of API11 (3.0 Honeycomb). - WARNING - large amounts of text incoming.
Load from Internet
Loading from the internet seems overwhelming at first, although it is simple in the end. First you want to ensure that the device has a connection. To do this, you create a method called getConnectivityStatus as seen below:
public boolean getConnectivityStatus() {
ConnectivityManager cm = (ConnectivityManager) this
.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null)
return info.isConnected();
else
return false;
}
If a connection exists, you'll want to create a directory to save the file and download the file using the DownloadManager class. To do this, simply say:
File directory = new File(Environment.getExternalStorageDirectory(), "ExampleDirectory");
if (!directory.exists())
directory.mkdir();
Next, you'll want to download the file with the method downloadFile(String), passing in the file name you'll want. If you want only a single copy of the file at any given time, you'll have to delete the old file if it exists before downloading, or you will have multiple files such as examplefile.txt; examplefile-1.txt; examplefile-2.txt; Place this first portion of code in the method you want to start the download from, such as onClick:
String FILE_NAME = "examplefile.txt",
File examplefile = new File(Environment.getExternalStorageDirectory()
+ "/ExampleDirectory", FILE_NAME);
if (examplefile.exists()) {
boolean deleted = examplefile.delete();
if (deleted) {
if (getConnectivityStatus())
downloadFile(FILE_NAME);
}
}
The downloadFile(String) method:
public void downloadFile(String FILE_NAME) {
String url = "http://www.example.com/filetobedownloaded.txt";
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDescription("Example file to be displayed.");
request.setTitle(FILE_NAME);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
}
request.setDestinationInExternalPublicDir("ExampleDirectory", FILE_NAME);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
You can also register a receiver to return a callback when the download is complete. To do so, simple register the receiver in the onCreate method like so: registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); and place the below method in your class:
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
if (!started) {
started = true;
// perform action upon completion
}
}
};
Here is the final DownloadFile.java class:
public class DownloadFile extends Activity {
boolean started = false;
String url = "http://www.example.com/filetobedownloaded.txt";
String FILE_NAME = "examplefile.txt",
File directory = new File(Environment.getExternalStorageDirectory(), "ExampleDirectory");
File examplefile = new File(Environment.getExternalStorageDirectory()
+ "/ExampleDirectory", FILE_NAME);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_downloadfile);
registerReceiver(onComplete, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
check();
}
public void check {
if (!directory.exists())
directory.mkdir();
if (!getConnectivityStatus()) {
if (!started) {
started = true;
// perform action if no connection
}
}
if (examplefile.exists()) {
boolean deleted = examplefile.delete();
if (deleted && !started) {
if (getConnectivityStatus())
downloadFile(FILE_NAME);
}
}
}
public boolean getConnectivityStatus() {
ConnectivityManager cm = (ConnectivityManager) this
.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null)
return info.isConnected();
else
return false;
}
public void downloadFile(String FILE_NAME) {
String url = "http://www.example.com/filetobedownloaded.txt";
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(url));
request.setDescription("Example file to be displayed.");
request.setTitle(FILE_NAME);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
}
request.setDestinationInExternalPublicDir("ExampleDirectory", FILE_NAME);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
if (!started) {
started = true;
// perform action upon completion
}
}
};
Load into ListFragment
In order to load the file into a ListFragment, and later display the selected item, you'll have to create 3 classes and 2 xml files in the layout directory. In my example, I will use MainActivity.java , PreviewFragment.java , SelectionFragment.java , activity_main.xml , and fragment_preview.xml . We'll start with the xml. The first xml file is the one you are viewing, which contains the two fragments we are working with: the ListFragment and the PreviewFragment. The setup is fairly simple; you specify the two fragment, their ids and constraints, and their respective classes. Here is activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/fragmentSelection"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
class="com.smarticle.catering.update.SelectionFragment" />
<fragment
android:id="#+id/fragmentPreview"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
class="com.smarticle.catering.update.PreviewFragment" />
</LinearLayout>
The above layout is optimized for a tablet in landscape mode. You can tweak the arrangement if you feel so inclined.
Next, you'll have to specify the PreviewFragment in xml, also fairly simple since it is only a TextView centered horizontally and vertically which will eventually display the selected items. Here is fragment_preview.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvPreview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="#string/app_name"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
The ListFragment will be created at runtime, so it will not need its own xml file.
In order to display the fragments on the screen, you'll have to load the activity_main.xml layout in your activity. This is a very simple task as it looks like every other activity, ever. This is MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
That's it, seriously. But now onward. In order to change the text in the PreviewFragment, you'll have to extend the Fragment class in PreviewFragment.java, inflate the view and setup a setText method. The PreviewFragment.java class is shown below:
public class PreviewFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_preview, container,
false);
return view;
}
public void setText(String item) {
TextView tvPreview = (TextView) getView().findViewById(R.id.tvPreview);
tvPreview.setText(item);
}
}
The lifecycle for a fragment can be found here.
Now you'll have to setup the ListFragment. This will be done in the ListFragment.java class. In the onActivityCreated() method, you'll want to load the file, ensuring that it actually downloaded and is in the correct directory with the load(String) method. At this time, you'll also separate the file by its delimiter into an array. This is the load(String) method:
public void load(String FILE_NAME) {
String[] list;
String FILE_NAME = "examplefile.txt",
File directory = new File(Environment.getExternalStorageDirectory(), "ExampleDirectory");
File examplefile = new File(Environment.getExternalStorageDirectory()
+ "/ExampleDirectory", FILE_NAME);
if (examplefile.exists()) {
try {
File myFile = new File(directory + "/" + FILE_NAME);
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(
fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow;
aBuffer = aBuffer.trim();
list = aBuffer.split(",");
}
myReader.close();
if (!loaded)
Toast.makeText(getActivity(),
"Done reading '" + FILE_NAME + "'.", Toast.LENGTH_SHORT)
.show();
loaded = true;
if (!selections.equals("")) {
for (int i = 0; i < selections.size(); i++) {
getListView().setItemChecked(selections.get(i), true);
}
}
} catch (Exception e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
}
This will return the String array list with the contents of examplefile.txt separated by commas. You can replace the commas with whatever delimiter you want, as long as the expression of aBuffer.split(String delimiter) is consistent with the delimiter in the text file. The boolean value loaded is only to make sure a new Toast doesn't appear everytime the activity is recreated, such as on an orientation change.
In the load(String) method, it's also a good time to set up your ListFragment's adapter and mode. You'll want to select a textViewResourceId that allows multiple choice, unless you want single choice. This can be done smoothly after the while statement by simple inserting these lines:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_activated_1, list);
setListAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
If single choice is desired, change ListView.CHOICE_MODE_MULTIPLE to ListView.CHOICE_MODE_SINGLE and change android.R.layout.simple_list_item_activated_1 to android.R.layout.simple_list_item_1. Alternatively, if you want checks instead of highlighted, change to android.R.layout.simple_list_item_checked.
In this class, you must also initialize your PreviewFragment, done so in the onActivityCreated method like so: fragment = (PreviewFragment) getFragmentManager().findFragmentById(
R.id.fragmentPreview);
Lastly, you'll have to be able to read which items are selected in the ListFragment and display them on the PreviewFragment. This I do with a method named getSelectedItems() shown below:
public void getSelectedItems() {
cntChoice = getListView().getCount();
items = "";
selections.clear();
SparseBooleanArray sparseBooleanArray = getListView()
.getCheckedItemPositions();
for (int i = 0; i < cntChoice; i++) {
if (sparseBooleanArray.get(i) == true) {
items += getListView().getItemAtPosition(i).toString()
+ ";\n";
selections.add(i);
}
}
if (fragment != null && fragment.isInLayout())
fragment.setText(items);
}
The String items is what is displayed in the TextView, and selections is an ArrayList<Integer> used to restore the state upon an orientation change. Normally, you would specify an android:configChanges="orientation" in the AndroidManifest.xml file under the <activity > tag, but the problem occurs when using separate layouts for portrait or landscape. If you allow the Manifest to handle orientation changes, the layout is not changed when the orientation is changed because a new activity is not created like it would be under normal circumstances. Therefor, you create static ArrayList<Integer> containing the positions which contain a selected item.
The last thing to do is read when a ListItem has been clicked and to call the getSelectedItems method, a fairly simple task. Insert this below anywhere into your class:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
getItems();
}
You're finished! Now to put it all together. Here is the ListFragment.java class:
public class ListFragment extends ListFragment {
String FILE_NAME = "examplefile.txt", items = "";
String[] list;
static ArrayList<Integer> selections = new ArrayList<Integer>();
int cntChoice, position;
static boolean loaded = false;
File directory = new File(Environment.getExternalStorageDirectory(), "ExampleDirectory");
File examplefile = new File(Environment.getExternalStorageDirectory()
+ "/ExampleDirectory", FILE_NAME);
PreviewFragment fragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fragment = (PreviewFragment) getFragmentManager().findFragmentById(
R.id.fragmentPreview);
check();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
getSelectedItems();
}
public void getSelectedItems() {
cntChoice = getListView().getCount();
items = "";
selections.clear();
SparseBooleanArray sparseBooleanArray = getListView()
.getCheckedItemPositions();
for (int i = 0; i < cntChoice; i++) {
if (sparseBooleanArray.get(i) == true) {
items += getListView().getItemAtPosition(i).toString()
+ ";\n";
selections.add(i);
}
}
if (fragment != null && fragment.isInLayout())
fragment.setText(items);
}
public void check() {
if (examplefile.exists())
load(FILE_NAME);
}
public void load(String FILE_NAME) {
try {
File myFile = new File(directory + "/" + FILE_NAME);
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(
fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow;
aBuffer = aBuffer.trim();
list = aBuffer.split(",");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_activated_1, list);
setListAdapter(adapter);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
myReader.close();
if (!loaded)
Toast.makeText(getActivity(),
"Done reading '" + FILE_NAME + "'.", Toast.LENGTH_SHORT)
.show();
loaded = true;
if (!selections.equals("")) {
for (int i = 0; i < selections.size(); i++) {
getListView().setItemChecked(selections.get(i), true);
}
getSelectedItems();
}
} catch (Exception e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
}
Conclusion
I hope this solved your problem. I know it's lengthy, but it's thorough, tested and works well. To start this, you can do an Intent intent = new Intent(getBaseContext(), MainActivity.class); startActivity(intent); finish(); in the onReceive method of the receiver in the DownloadFile.java class. I would also suggest placing those same lines of code in the check() method, specifically the portion that is called if there is no connection, in which case, it will load the file that was previously downloaded to the directory. Good luck, happy coding and always remember... 01101000011101000111010001110000011100110011101000101111001011110111011101110111011101110010111001111001011011110111010101110100011101010110001001100101001011100110001101101111011011010010111101110111011000010111010001100011011010000011111101110110001111010110100101110101011000100100101000101101010110000101001101001100001110010110011101101111